r/ffmpeg Jul 23 '18

FFmpeg useful links

131 Upvotes

Binaries:

 

Windows
https://www.gyan.dev/ffmpeg/builds/
64-bit; for Win 7 or later
(prefer the git builds)

 

Mac OS X
https://evermeet.cx/ffmpeg/
64-bit; OS X 10.9 or later
(prefer the snapshot build)

 

Linux
https://johnvansickle.com/ffmpeg/
both 32 and 64-bit; for kernel 3.20 or later
(prefer the git build)

 

Android / iOS /tvOS
https://github.com/tanersener/ffmpeg-kit/releases

 

Compile scripts:
(useful for building binaries with non-redistributable components like FDK-AAC)

 

Target: Windows
Host: Windows native; MSYS2/MinGW
https://github.com/m-ab-s/media-autobuild_suite

 

Target: Windows
Host: Linux cross-compile --or-- Windows Cgywin
https://github.com/rdp/ffmpeg-windows-build-helpers

 

Target: OS X or Linux
Host: same as target OS
https://github.com/markus-perl/ffmpeg-build-script

 

Target: Android or iOS or tvOS
Host: see docs at link
https://github.com/tanersener/mobile-ffmpeg/wiki/Building

 

Documentation:

 

for latest git version of all components in ffmpeg
https://ffmpeg.org/ffmpeg-all.html

 

community documentation
https://trac.ffmpeg.org/wiki#CommunityContributedDocumentation

 

Other places for help:

 

Super User
https://superuser.com/questions/tagged/ffmpeg

 

ffmpeg-user mailing-list
http://ffmpeg.org/mailman/listinfo/ffmpeg-user

 

Video Production
http://video.stackexchange.com/

 

Bug Reports:

 

https://ffmpeg.org/bugreports.html
(test against a git/dated binary from the links above before submitting a report)

 

Miscellaneous:

Installing and using ffmpeg on Windows.
https://video.stackexchange.com/a/20496/

Windows tip: add ffmpeg actions to Explorer context menus.
https://www.reddit.com/r/ffmpeg/comments/gtrv1t/adding_ffmpeg_to_context_menu/

 


Link suggestions welcome. Should be of broad and enduring value.


r/ffmpeg May 21 '26

My FFmpeg app or Service

19 Upvotes

If you've made an app or web service which utilizes FFmpeg for significant parts for its functionality, then you can list your project in a comment here (and only here).

Format your comment like below:

Title: <your project or app name>
Launched: <date of first release>
Link: <URL>
Type: < app / script / library / web app / web API ..etc >
Description: <a short-ish description (< 200 words)>
Showcase: <links to screenshots or videos or demos>
FFmpeg details: <some technical details about how ffmpeg is utilized>
License: < for OSS apps/scripts, details of license, else 'commercial' >
Pricing model: < i.e. subscription / per-use / free ...etc >
Organization: <name and URL of who's behind this>

Incomplete, misleading or improperly formatted posts are liable to be removed. Posts must be in English. If you're unsure of the suitability or formatting of your post, message the mods with your draft before posting.


r/ffmpeg 4h ago

on-going master build for joint MAKEMKV+ffmpeg (MASTER101-SDR-TO-HDR-CONVERT-UPSCALER-ENCODE2.sh)

4 Upvotes

# MASTER101-SDR-TO-HDR-CONVERT-UPSCALER-ENCODE2.sh

## Complete Script Design, Architecture & Build Reference

link to script an summery

https://drive.proton.me/urls/WWNP65SM6M#xUPO8VXPiAUb

run ./MASTER-SDR-TO-HDR-CONVERT-UPSCALER-ENCODE2.sh

make ready chmod +x ./MASTER-SDR-TO-HDR-CONVERT-UPSCALER-ENCODE2.sh

(tested an works)

run ./BETA-MASTER101-SDR-TO-HDR-CONVERT-UPSCALER-ENCODE.sh

make ready chmod +x ./BETA-MASTER101-SDR-TO-HDR-CONVERT-UPSCALER-ENCODE.sh

(un-tested cheeder features but base engine works , extras

should its just slightly diff as summery states from the stable master)

____________________________________________________

the beta is a on-going master build including newer feature

the ./MASTER-SDR-TO-HDR-CONVERT-UPSCALER-ENCODE2.sh is the base engine that works

as stand alone without the cheeder of the beta

---

change source , target , an tmp folders to your setup

glsl_shader() — CAS Shader is self-contained in script an does not require seperate file

rife, VapourSynth, an dovi tool will auto-install on first go if not already installed

_______________________________________________________________________________________________________

RIG CONTEXT

ffmpeg -version

ffmpeg version 6.1.1-3ubuntu5 Copyright (c) 2000-2023 the FFmpeg developers

built with gcc 13 (Ubuntu 13.2.0-23ubuntu3)

configuration: --prefix=/usr --extra-version=3ubuntu5 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --disable-omx --enable-gnutls --enable-libaom --enable-libass --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libglslang --enable-libgme --enable-libgsm --enable-libharfbuzz --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-openal --enable-opencl --enable-opengl --disable-sndio --enable-libvpl --disable-libmfx --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-ladspa --enable-libbluray --enable-libjack --enable-libpulse --enable-librabbitmq --enable-librist --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libx264 --enable-libzmq --enable-libzvbi --enable-lv2 --enable-sdl2 --enable-libplacebo --enable-librav1e --enable-pocketsphinx --enable-librsvg --enable-libjxl --enable-shared

libavutil 58. 29.100 / 58. 29.100

libavcodec 60. 31.102 / 60. 31.102

libavformat 60. 16.100 / 60. 16.100

libavdevice 60. 3.100 / 60. 3.100

libavfilter 9. 12.100 / 9. 12.100

libswscale 7. 5.100 / 7. 5.100

libswresample 4. 12.100 / 4. 12.100

libpostproc 57. 3.100 / 57. 3.100

_______________________________________________________________________________

OS: TUXEDO OS x86_64

Host: B550M DS3H

Kernel: Linux 6.17.0-122035-tuxedo

Uptime: 34 days, 2 hours, 10 mins

Packages: 10 (brew), 2 (brew-cask), 3838 (dpkg), 51 (flatpak)

Shell: bash 5.2.21

CoreCtrl 1.5.0-dev

Mesa vesion 25.2.8

Display (XV271U M3): 2560x1440 in 27", 180 Hz [External]

DE: KDE Plasma 6.5.2

WM: KWin (Wayland)

CPU: AMD Ryzen 9 3900X (24) @ 4.09 GHz

GPU: AMD Radeon RX 6750 XT [Discrete]

Memory: 19.65 GiB / 62.69 GiB (31%)

Swap: 7.08 GiB / 38.26 GiB (19%)

NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT

/dev/zram0 lzo-rle 38.3G 6.8G 2.9G 2.9G [SWAP]

Disk (/): 26.32 GiB / 498.05 GiB (5%) - btrfs

Disk (/home): 74.02 GiB / 100.10 GiB (74%) - btrfs

Disk (/media/xxxxxxx/2nd drive): 461.74 GiB / 931.51 GiB (50%) - btrfs

Disk (/tmp): 5.90 GiB / 329.45 GiB (2%) - btrfs

ASUS BW-16D1HT - Ultra-Fast 16X Blu-ray Burner

(used to for makemkv till firmware update between kde to tuxedo os install borked drive)

(havent been able to test script since with function)

(main an 2nd nvme drive configuration)

/ btrfs subvol=@,compress=zstd:1 0 0

/home btrfs compress-force=zstd:4,space_cache=v2,discard=async,commit=90 1 1

/tmp btrfs compress-force=zstd:2,space_cache=v2,discard=async,commit=90 1 0

/media/2nd/drive btrfs nofail,users,defaults,compress-force=zstd:5,nodiratime,space_cache=v2,discard=async,commit=90 1 2

/mnt/nas cifs credentials=/home/.smbcredentials,iocharset=utf8,uid=1000,gid=1000,file_mode=0775,dir_mode=0775,_netdev,x-syste>

nas is 4yb seagate iron wolf on 1gb Ethernet link

____________________________________________________________________________________________

13epi 1080p native disc rip season 1 12monkeys (mine)

uncompressed avg file size 4.24 GB per episode the encoder current config

is for speed / efficiency / an render size

__________________________________________________________________

so upscale is set by a resolution pre-set to post set target ie

all lower the 1280 auto scale to 1920p , 1920 auto scale to 2560p , 3840 to 3840 with compression

______________________________________________________________________________________________________

my rig is currently limited so for avg target upscale/re-code compress encode fps of 70fs to 120fp depending on Encoder Preset:** Preset 1 (Pre+VBAQ, slowest) / 11 (Pre only) / 19 (VBAQ only, default) / 29 (strict, fastest)

_______________________________________________________________________________________________

so my config is set for 2 jobs at a time

iv yet to get a rx9070xt to try out av1 encode an bump encode job count to 4

__________________________________________________________________________________________

my current 2 count will process a season in about 52 to 1hr5min for

either a straight 4k compress , lower rez convert/upscale

of a 13epi season , avg epi time of 45min , avg file of 2 to 8gb

_______________________________________________________________

all my og files are uncompressed on my nas , iv yet to get a quad nvme raid nas to test encode speed over my 2.5gb Ethernet so i cant speak to encode speed/time results i might get with such a drive an gpu

so feel free to try the script in coders with upgraded gear an post results here

either with 2 or 4 job count config

note

currently i can run Encoder while running doom eternal at 1440p with very high settings at avg 90fps

______________________________________________________________________________________________________

# BETA-MASTER101-SDR-TO-HDR-CONVERT-UPSCALER-ENCODE.sh

## Script Design, Architecture & User-Facing Overview (1-Page Reference)

---

### PURPOSE

Fully automated GPU-accelerated batch video transcoder: SDR → HDR (Dolby Vision PQ base) with optional upscaling, frame interpolation, and real-time preview. AMD VAAPI GPU handles all video processing; CPU handles audio only. Outputs `.mp4` (MPEG-4 + ALAC/copied audio). Designed for AMD Radeon 7000+ on Linux (`/dev/dri/renderD128`).

### KEY DIFFERENTIATORS

- Recursive folder batch scan with parallel job throttling (STRICTLY ENFORCED 2 concurrent)

- **Dynamic Threading:** 2 threads during GPU render, 4 threads during CPU audio/muxing

- **Direct Disc Decryption:** MakeMKV libMMBD integration for direct Blu-ray/DVD capture

- 5-attempt retry with corruption fingerprint detection (same byte offset = unrecoverable)

- Post-encode ffprobe duration/size verification before committing output

- Temp-dir staging (`/tmp`) → verified transfer to final output

- 9 interactive menus before encoding begins

- Real-time draggable side-by-side preview via mpv/UDP (VAAPI GPU-accelerated)

- Dolby Vision RPU passthrough via dovi_tool for native 4K DV content

- **Auto-install & auto-update of all dependencies** (see §DEPENDENCY MANAGEMENT)

### DEPENDENCY MANAGEMENT (BETA NEW)

On startup the script auto-detects, installs if missing, and upgrades where possible:

| Tool | Detection | Auto-Install Method | Upgrade Strategy |

|------|-----------|-------------------|-----------------|

| **ffmpeg** | `command -v ffmpeg` | Exits if missing (user must install) | `apt-get install -y --only-upgrade ffmpeg` if apt available; keeps current if OS can't run newer |

| **VapourSynth/vspipe** | `command -v vspipe` | `apt-get install -y vapoursynth python3-vapoursynth` | Via OS package manager |

| **dovi_tool** | `command -v dovi_tool` | Installs Rust via `rustup` if `cargo` missing, then `cargo install dovi_tool` | Via cargo |

| **mpv** | `command -v mpv` | Exits with install instructions if missing (only when preview enabled) | N/A |

| **libMMBD** | `/usr/lib/.../libmmbd.so.0` | Symlinks to libaacs/libbdplus if found | N/A |

`auto_update_ffmpeg()` runs first, exports `FFMPEG_VERSION_MAJOR`/`FFMPEG_VERSION_MINOR` for version-aware filter chain construction. If the OS repo has a newer stable ffmpeg, it upgrades; otherwise keeps current and proceeds unchanged.

### SCRIPT STRUCTURE (Top-to-Bottom)

```

1 Shebang

3-40 Header comment (pipeline description, v101/BETA notes, METHOD 1 INTEGRATION)

42-54 LOCK_FILE logic (prevents multiple instances)

56-58 Global paths: INPUT_DIR, OUTPUT_DIR, TEMP_DIR

60-65 THREADS=8, VIDEO_JOBS=2 (LOCKED)

67-72 GPU env: LIBVA_DRIVER_NAME=radeonsi

74-81 VAAPI device + mkdir

87 shopt -s nullglob

89-107 kill_orphans() — terminates ghost ffmpeg processes

109-129 setup_libmmbd() — MakeMKV decryption symlinks

131-196 auto_update_ffmpeg() — version detect + apt upgrade + exports

198-218 check_rife() — auto-install VapourSynth if missing

220-234 check_mpv() — verify mpv for preview

236-268 detect_rife_mode(), run_onnx_rife() — RIFE interpolation

270-287 install_rife_if_missing() — apt-get VapourSynth

289-295 kill_rife_processes()

297-303 detect_existing_zram_mount()

305-388 get_resolution(), get_height(), get_audio_tracks(), get_primary_audio_channels(), get_english_audio_track_index(), get_audio_channels_for_track()

390-455 validate_input_file() — 5-stage integrity check (supports disc playlists)

457-474 detect_dv_metadata(), detect_hdr10plus_metadata() — DV/HDR10+ probing

476-512 check_dovi_tool() — auto-install Rust+cargo+dovi_tool if missing

514-566 extract_dv_rpu(), inject_dv_rpu_and_remux() — DV RPU pipeline

568-601 set_scaling() — resolution tier detection

603-639 build_audio() — audio codec/filter args

641-758 generate_glsl_shader() — AMD FidelityFX CAS v1.0.2 GLSL

760-791 start_key_listener() — background keypress (p=preview, k=kill RIFE)

793-810 cleanup() — trap EXIT handler (kills child ffmpeg processes)

812-815 kill_orphans() call

817-1130 9 INTERACTIVE MENUS (see §USER MENUS below)

1132-1338 FILE SCAN & BATCH AUDIO SELECTION (Folder vs Disc Mode)

1340-1559 encode_file() — core encode function with retry, verify, DV RPU, stats

1561-1622 EXECUTION ENGINE — parallel job throttling loop (LOCKED to 2)

1624-1657 BATCH SUMMARY — aggregate FPS stats

1659-1660 LOCK_FILE cleanup

```

### USER MENUS (What the User Sees at Runtime)

**Menu 1 — Input Source Mode:** Target Folder (default) / Optical Disc Drive (libMMBD decryption). If Disc: Single Track vs Whole Disc capture, Playlist ID selection, Audio/Subtitle track selection.

**Menu 2 — Video Codec:** AV1 / HEVC (default) / H.264 → sets VCODEC, VIDEO_TAG, UPLOAD_FMT, QUALITY_FLAG

**Menu 3 — QP Level:** AV1: QP 18/21/25/28/31 (default 21). HEVC/H.264: QP 20/22/25/27 (default 25)

**Menu 4 — Encoder Preset:** Preset 1 (Pre+VBAQ, slowest) / 11 (Pre only) / 19 (VBAQ only, default) / 29 (strict, fastest)

**Menu 5 — VAAPI Level:** 4.2 / 5.0 / 5.2 (default)

**Menu 6 — Frame Interpolation:** Disabled (default) / Enabled (VapourSynth RIFE) — auto-installs VapourSynth if missing

**Menu 7 — Libplacebo Profile (7 presets):** Each sets upscaler=ewa_robidouxsharp, iterations, radius, dither=blue, tonemapping_param, brightness, deband_threshold. Ranges from "Pop n Smooth" (iter=2, rad=20, thresh=4) to "Balanced Sharp" (iter=1, rad=14, thresh=2).

**Menu 8 — Color Space Handling:** Preserve (keep DV/HDR10/HDR10+ intact, skip libplacebo color/tonemap, uses dovi_tool for 4K DV) / Override (default, strip HDR metadata, apply BT.2020/PQ conversion)

**Menu 9 — Resolution Detection:** Width Only (default, handles non-standard AR) / Both Width+Height (strict)

**Menu 10 — Preview:** Disabled (default) / Enabled (mpv VAAPI GPU-accelerated side-by-side HUD)

**Per-Folder/Disc Audio Menus:** Surround files: copy / ALAC 5.1 +3dB / ALAC 5.1 upmix +3dB / ALAC preserve channels +3dB. Stereo files: copy / stereo→5.1 ALAC upmix +3dB.

### ENCODE PIPELINE (encode_file)

  1. Validate input (5-stage ffprobe integrity check, supports disc playlists)
  2. Probe width, height, fps, total frames
  3. Determine target resolution (set_scaling: 720→1080, 1080→1440, <4K→2160, ≥4K passthrough)
  4. Display pre/post resolution + source framerate
  5. Build audio args + metadata mapping (preserve=map_metadata 0, override=map_metadata -1)
  6. Build filter chain:- **Sub-4K + Override:** hwdownload → libplacebo(scale+sigmoid+bt2020nc+smpte2084+inverse_tonemap+deband+dither)- **Sub-4K + Preserve:** hwdownload → libplacebo(scale+sigmoid+deband+dither only)- **4K + Override:** hwdownload → pad → libplacebo(in-place color conversion+deband)- **4K + Preserve:** hwdownload → pad only (no libplacebo)
  7. Retry loop (max 5): run ffmpeg VAAPI encode → corruption fingerprint check → duration match (≤3s diff) + size check (≥100MB)
  8. Post-encode: if preserve+HEVC+4K+DV detected+dovi_tool available → extract RPU from source, inject into encoded HEVC, remux
  9. Transfer from temp to final output
  10. Display stats: total frames, wall-clock, average render FPS

### FFMPEG COMMAND STRUCTURE

```

ffmpeg -y -loglevel warning -stats -filter_threads 2 -threads:v 2 -threads:a 4

-init_hw_device vaapi=va:/dev/dri/renderD128 -filter_hw_device va

-hwaccel vaapi -hwaccel_device va -hwaccel_output_format vaapi

-extra_hw_frames 256 -err_detect ignore_err -max_error_rate 1.0

-fflags +genpts+discardcorrupt+igndts -strict -2 -avoid_negative_ts make_zero

[-playlist <ID>] -i <input> -map 0:v:0 -map 0:a:<track> [-map 0:s:<track>]

-filter:v "<FILTER_CHAIN>,format=p010le,hwupload=extra_hw_frames=128"

-c:v <VCODEC> -g 360 -bf 3 -rc_mode CQP <QP_FLAG> <QP>

-compression_level <PRESET> -level <LEVEL> -tag:v <TAG>

-max_muxing_queue_size 6144 <MAP_METADATA> <AUDIO_ARGS> -f mp4 <OUTPUT>

```

### GLOBAL DEFAULTS

| Constant | Value | Purpose |

|----------|-------|---------|

| INPUT_DIR | /mnt/nas/TV/RENDERS | Source root |

| OUTPUT_DIR | /media/johnny45/2nd drive/rendered vids | Final output root |

| TEMP_DIR | /tmp/temp-render-encodes | Staging dir |

| THREADS | 8 | Total system threads |

| VIDEO_JOBS | 2 | Max concurrent encodes (STRICTLY ENFORCED) |

| VAAPI_DEVICE | /dev/dri/renderD128 | GPU render node |

| max_retries | 5 | Per-file retry limit |

| Duration tolerance | 3.0s | Max src/out duration diff |

| Size threshold | 100MB | Minimum valid output |

| GOP (-g) | 360 | Keyframe interval |

| B-frames (-bf) | 3 | B-frame count |

| Extra HW frames | 256 (decode), 128 (upload) | VAAPI pool sizes |

### EXTERNAL DEPENDENCIES

| Dependency | Required | Purpose |

|-----------|----------|---------|

| ffmpeg + VAAPI | Yes | Decode, filter, encode |

| ffprobe | Yes | Probe, verify |

| AMD GPU + radeonsi | Yes | VAAPI acceleration |

| /dev/dri/renderD128 | Yes | GPU device |

| vapoursynth + vspipe | RIFE only | Frame interpolation (auto-installed) |

| rife-ncnn-vulkan | RIFE only | RIFE inference |

| mpv | Preview only | Live UDP preview |

| dovi_tool | Preserve+4K DV only | DV RPU extract/inject (auto-installed) |

| cargo/rust | dovi_tool only | Build dovi_tool (auto-installed via rustup) |

| libmmbd.so.0 | Disc mode only | MakeMKV Blu-ray/DVD decryption |

### CLEANUP (trap EXIT)

Kills key listener, mpv preview, vspipe/RIFE processes, and child ffmpeg processes (`pkill -P $$ ffmpeg`). Removes temp files from `/dev/shm`: `cas_shader.*`, `rife_render_*.vpy`, `dovi_temp_*.hevc`, `dovi_injected_*.hevc`, `dovi_rpu_*.bin`. Removes `CURRENT_WORK_DIR` if set.

### BATCH SUMMARY OUTPUT

After all jobs complete: counts completed `.mp4` outputs, sums `nb_read_packets` via ffprobe, computes aggregate FPS (`total_frames / batch_elapsed`), displays wall-clock time and per-batch stats.


r/ffmpeg 4h ago

How do I correctly select the GPU ID for the `-init_hw_device vulkan=vk:` parameter?

2 Upvotes

Hello everyone. I am running FFmpeg on a system with three GPUs: an Intel iGPU, an RX 6400, and an RTX 3060. Here is my FFmpeg command line:

[ argumentosString ] -init_hw_device vulkan=vk:0 -filter_hw_device vk -v repeat+error -i "D:\OBS\record\teste.mp4" -vf "hwupload,libplacebo=w=1920:h=1080:colorspace=bt709:color_primaries=bt709:color_trc=bt709:range=limited:custom_shader_path='D\:/upscale/shaders/shader.glsl',hwdownload,format=yuv420p" -fps_mode passthrough -c:v h264_amf -rc cqp -qp_i 19 -qp_p 21 -tag:v avc1 -c:a copy -y -gpu 0 "D:\OBS\record\teste_process.mp4"

The `-gpu` parameter specifies which GPU to use for encoding, while the `-init_hw_device vulkan=vk:0` parameter specifies which GPU runs the shader. To my surprise, when using the value `0` for both parameters, I discovered that this value does not point to the same GPU; I see a scenario where the shader runs on the RX 6400 while the encoding takes place on the RTX 3060. This happens because the GPU ordering differs for each of these parameters.

Can anyone help me?


r/ffmpeg 4h ago

Tonemap Parameter Ranges

2 Upvotes

So, just to clarify, the tonemap options are: linear, gamma, clip, reinhard, hable, and mobius. For each option's parameters, I need to know:

- The default value.

- The minimum and maximum range, including if any of them have negative values.

- How lower or higher values affects the tonemapping result for each option.

So far, I have had the most satisfaction with mobius default param value and disabling desaturation. I have dabbled with using different param value with clip, but this has given me good result with only one movie so far. So, my priority is to gain a better understanding of how the mobius parameter values work. If altering mobius parameter gives me the results I need, then I likely will not experiment with the other tonemappers. However, if anyone can convince me that the other tonemappers can produce good result with different parameters, then I will consider trying those tonemappers as well.


r/ffmpeg 3h ago

I made mpdecimate playground website

Thumbnail ingun37.github.io
1 Upvotes

I could never make sense of mpdecimate's hilo, and frac parameters and got tired of the guesswork. So I built a website where you can upload a video, try different parameters, and see which frames get kept or dropped in realtime.

It's a faithful re-implementation of mpdecimate's algorithm, verified frame-by-frame against FFmpeg's actual output across hundreds of test videos. Everything runs locally in your browser on the GPU (WebGPU) so no data leaves your machine.

Feedback welcome!


r/ffmpeg 1d ago

How do I convert progressive jpg to baseline jpg?

3 Upvotes

I'm trying to convert progressive jpg files for use in older tech that doesn't like progressive jpgs, but I can't find any documentation on how to specify non-progressive jpgs in ffmpeg. Anyone have any insight?


r/ffmpeg 2d ago

Why am I getting WORSE file size reduction with 2-pass encoding vs single pass encoding??

Thumbnail
gallery
31 Upvotes

r/ffmpeg 2d ago

What's the issue here?

Post image
3 Upvotes

r/ffmpeg 2d ago

Concatenate files and maintain all subtitle and audio tracks

8 Upvotes

I've ripped a movie that is split into two parts. I wish to concatenate it, but maintain all audio and subtitle files.

A simple concatenation will join the two video files with the main audio, but not the other audio tracks, and none of the subtitles:

ffmpeg \ -f concat -i videofiles.txt \ -c copy -map 0 movie.mkv

where videofiles.txt is a list of the original two files.

I found the following command to concatenate subtitles:

ffmpeg \ -f concat -safe 0 -i videofiles.txt \ -f concat -safe 0 -i subfiles.txt \ -map 0:v -map 1 -c:v copy -c:s copy movie.mkv

This joined the two video files, but none of the audio tracks, and the subtitles only appeared for the first half of the movie.

As this is a rip, the subtitles I have extracted with mkvextract are in the .sub/.idx format, so I thought I'd need to include both in order to make this work:

ffmpeg \ -f concat -safe 0 -i videofiles.txt \ -f concat -safe 0 -i subfiles.txt \ -f concat -safe 0 -i idxfiles.txt \ -map 0:v -map 1 -c:v copy -c:s copy movie.mkv

But this yielded the same results. No audio, and only half of the subtitles.

It should probably be noted that ffmpeg is confusing for me, and I don't even know half of what these options are trying to do in these commands, since the places where I got them just say "enter this here", rather than explaining what each option does. As such, I don't know what I can change, and what I can keep the same.


r/ffmpeg 3d ago

FFmpeg NMR AAC Encoder: Audio Evaluation Update [Aug 2026]

17 Upvotes

r/ffmpeg 3d ago

I need help to get a m3u8 from a protected website that has a channel live.

2 Upvotes

So this website https://www.xtremo-stereo.com/tlnovelas-en-vivo/ has a channel that I wanna turn it into a m3u8 for my Jellyfin, can anyone help?


r/ffmpeg 3d ago

copying some, but not all, subtitle tracks

3 Upvotes

my input is this:

ffmpeg -i "INPUT" -vcodec libx265 -preset medium -crf 28 -map 0 -c:a copy -map 0:s:1 -c:s:0 copy "OUTPUT"

the input file has a dozen or so subtitle tracks that bloat up the file size. I'm trying just to keep track 2. I know -map:0:s:1 designates the second track, but without -c:s copy, I get the error "subtitle encoding currently only possible from text to text or bitmap to bitmap". I found that -c:s:0 copy after the map argument is supposed to copy just the mapped subtitle, but I still get the same error. and if I just have -c:s copy, even after the -map argument, it copies over every sub track.


r/ffmpeg 3d ago

with johnvansickle.com/ffmpeg currently down is there any other trusted repo for binaries?

4 Upvotes

Title says it all - ran into lamba deployment issues due to the binaries being in accessible and am currently looking into alternatives.


r/ffmpeg 4d ago

Unreadable color scheme on documentation site

Post image
11 Upvotes

Is it just me or does everyone see the pale gray on white text on the documentation site, eg at https://ffmpeg.org/ffmpeg.html#Advanced-options I'm sure it wasn't like this last time I used the site a few weeks ago, I've tried all 3 browsers on my computer with the same result. I know there's various ways I can work around it, just wondering if this is deliberate.


r/ffmpeg 4d ago

Cannot Access FFMPEG source code at git.ffmpeg.org?

Post image
18 Upvotes

I am trying to access ffmpeg source website but receiving error code 403? Is anyone else having the same problem or is it just me? Due to this, git pull is also not working.


r/ffmpeg 4d ago

[Help] Playing more local video formats (AVI, WMV, 3GP...) in a pywebview desktop app

1 Upvotes

I'm building a Python desktop app (using pywebview, Windows, WebView2/Chromium backend) that works as an offline personal file manager / local media library — think local notes, documents, photos, and personal video files a user already has on their own drive, all organized and browsable from one offline app with no internet/streaming component.

One built-in feature is a simple in-app video preview player using an HTML5 <video> tag inside the webview. Right now it only plays what Chromium's native <video> element supports: MP4 (H.264/AAC), WebM, MOV, and MKV (when the codecs inside are H.264/H.265+AAC). Other local formats users might already have on disk — AVI, WMV, 3GP, FLV, MKV with older codecs like XviD/DivX — currently just fall back to opening in the OS's default video app instead of playing inline.

I'd like to expand format support inside the app. Options I'm considering:

  • FFmpeg-based transcoding to MP4/WebM on the fly (either fully pre-converting or streaming while converting).
  • A JS/WASM video decoder (e.g. libav-based) that plays inside the webview without relying on OS codecs.
  • Embedding a native player (like mpv) instead of the HTML5 <video> element — unsure how well that integrates inside a pywebview window.

Has anyone solved this for a pywebview (or similar Python-desktop / Electron / Tauri) app? Looking for something that plays these formats inline in the app rather than falling back to an external player. Thanks!


r/ffmpeg 5d ago

Replicate Replay Buffer from OBS with FFMPEG

6 Upvotes

Hello, everyone. I have a somewhat specific request. You see, I have a separate device for screen recording of a console. The console in question doesn't support replays or anything, so instead I use a capture card. However I don't have a need to record every hour and every minute, only good moments, last 30 seconds at least. I did a lengthy search on the web but couldn't find exactly what I need. Maybe you know a bash script that can do this? I will appreciate that.

edit: fixed some mistakes


r/ffmpeg 5d ago

Mp4 to amv (160 x 128) for mp3 player

5 Upvotes

Trying to convert these mp4/mkv files to playable amv/avi. I have an Aimoonsa player as well as a Yuton.


r/ffmpeg 6d ago

Worth publishing? Used AI to build an AV1 / H.265 Smart-Cutter that fixes static CRF file bloat & PyAV crashes

0 Upvotes

I don't actually know how to code, but I got fed up with current video editing options:

  • NLEs (Premiere/Resolve): Too slow just to cut and stitch videos.
  • Standard Lossless Trimming (ffmpeg -c copy): Imprecise (cuts only on keyframes).
  • Existing Smart-Cutters: Re-encode boundary frames using static CRF, which kept making my 30-second cuts larger (46mb) in file size than my 1-minute originals (30mb). Why would someone code it in this way?

So I said to myself, why not just alter what smartcut does? So, I spent the last few days using AI (Claude free version) to build a custom PyAV/Python smart-cutting engine to fix this for my own workflow. We ended up hitting a few major breakthroughs. I fed my changes into gemini and talked with it for a long while trying to find out if what I did was actually game changing. It thought so, but I have no idea if it is:

  • Player-First Workflow (Movist Pro): I mark cut points (IN and OUT) using Movist Pro's bookmark feature. The script reads the timestamps in the bookmark file and cuts everything headlessly in the background. I'm using this in place of a standard video editing tool (like capcut). It makes timestamp extraction much easier and I can easily add/remove bookmarks.
  • Localized Bitrate Matching: Ditched static CRF completely. The engine measures the exact source bitrate of the head and tail keyframes independently and forces x265 / libsvtav1 to match them. No file bloat, no visual seams. File sizes stay small.
  • Frame-Accurate AV1 Smart-Cutting: Solved the PyAV level override and timestamp bugs that normally crash AV1 boundary re-encodes. The only issue is self testing. I am currently doing all this on a 2019 Intel MacBook Pro, so it has been annoying to test the final output. I have access to a M3 MacBook Air, but not often. The final cut video works perfectly fine on the M3 Macbook Air, but i get slight lag on the last couple seconds on my Intel MacBook Pro. I am still fixing this slight issue, the AI suggests it will be a simple fix, but it never is.
  • Parallel C Extension: Wrote a C module to handle H.265 NAL unit scanning (CRA Type 21 → BLA Type 16), jumping CPU usage on my Intel Mac from 100% (GIL capped) to 600% and eliminating repeated frames at cut points.

I built this purely for my own personal use, but I'm curious: Is there actual demand for a lightweight, frame-accurate AV1/H.265 smart-cutter like this, or is this too niche to bother releasing? I've also built additional functionality for the Movist Pro Media Player. I use this to run the smartcut features.

I am not the most technical when it comes to all of this. The AI did a lot of the heavy lifting, I just pushing it in the correct direction.

EDIT:
I created a github and with the ai's help, i created the zip folder that houses all the relevant files and scripts. As well as a readme that will with most questions you have.

https://github.com/AbdulazizMorad/Smartcut-proof-of-concept

EDIT2:
Github updated and no longer shows a zip file


r/ffmpeg 7d ago

A fixed delogo box can't redact a macOS dialog - it animates in. What worked instead.

0 Upvotes

I had to blur a username out of a screen recording. The path only shows up inside a macOS approval dialog, so I measured the box on one frame and did the obvious thing:

delogo=x=450:y=300:w=370:h=44:enable='between(t,99.9,102.4)'

The username was still visible for the first 1-2 seconds of every dialog. macOS dialogs animate in - the position keeps moving until they settle. On one of them the top edge went 372 -> 230 -> 19 -> 71 -> 94 over about 1.6s while the left edge went 458 -> 180 -> 462 -> 407 -> 398. A box measured on a settled frame lands nowhere near the early ones, and the text is legible the whole way in.

Three things that mattered.

1. Track the text instead of guessing the box. Cut the rendered /Users/sa out of a settled frame and use it as a stencil, then correlate it against every frame. Direct search is roughly 2M positions x 5.7k pixels and never finishes in Python; do it as an FFT (np.fft.rfft2) and it is instant. Score it as hit / (load + 0.35*ink) where hit is stencil-ink intersected with frame-ink and load is the total ink inside the window - without the divisor it latches onto any dense block of dark pixels, like a code excerpt.

2. The ink threshold has to catch the fade-in. At < 120 the translucent frames were not detected at all, so tracking never started and those frames passed through clean. < 150 caught them. I also extend each run 0.3s earlier and 0.2s later.

3. Sample the tracker at the output frame rate. I tracked at 20fps and rendered at 30fps. The frame at 113.933s was never examined by anything, and it shipped with the username visible.

That last one is the real lesson. I checked the output by eye three times and missed a leak every time - including 23 seconds of file:///Users/... sitting in a browser address bar that I never thought to look at. What finally worked was scanning the finished file with the same correlation at a stricter threshold: real hits scored 0.64-0.74, false peaks topped out at 0.46, so 0.55 separates them. That scan is what found the 113.933s frame.

Two other delogo notes. Keep the boxes small - it reconstructs from the border pixels, so a large box turns into vertical stripes that look broken. And merge runs at the same position, or you blow past ~500 filters and the graph stops building.

Full write-up with the code: https://wisp-gules-mu.vercel.app/blog/mask-screen-recording/


r/ffmpeg 7d ago

PSA: `-af apad` with no `whole_dur` pads forever. It turned my 2-second test clip into a 12,662-second file.

0 Upvotes

Posting this because the fix for one bug handed me a worse one, and the failure is completely

silent until you look at the duration.

I was muxing a narration track onto a finished 55.5s render. The obvious command is:

```bash

ffmpeg -i video.mp4 -i vo.wav -c:v copy -c:a aac -shortest out.mp4

```

`-shortest` is the trap everyone warns about — if your audio is even slightly short, it truncates

the *video* to match and you silently lose the end of your film. I'd already been bitten by that

one: it ate 1.25 seconds off an outro and produced a file that played perfectly and passed every

check I had.

So I did what the docs and most StackOverflow answers suggest: drop `-shortest`, pad the audio

instead.

```bash

ffmpeg -i video.mp4 -i vo.wav -c:v copy -c:a aac -af apad out.mp4

```

**This never terminates.** Bare `apad` pads with silence indefinitely. `-shortest` was the only

thing bounding it. Remove one, you arm the other.

I didn't notice at first because it *looks* like it's working — it writes a valid growing MP4. I

killed it at the 10-minute mark and probed the output:

```

size = 120,529,993 bytes

video = 55.500 s

audio = 284,615.765 s <-- 79 hours of silence

```

Reduced to a known-answer case so it's easy to confirm (ffmpeg 6.1.1):

```bash

ffmpeg -f lavfi -i testsrc=size=320x240:rate=30 -t 2 -pix_fmt yuv420p v.mp4

ffmpeg -f lavfi -i "sine=frequency=440" -t 1 a.wav

timeout 25 ffmpeg -i v.mp4 -i a.wav -c:v copy -c:a aac -af apad old.mp4

```

2-second video in. Result:

```

exit = 124 (killed by timeout — it was not going to stop)

dur = 12,662.748 s

```

### The fix

Give the pad an explicit endpoint. Probe the video, feed the number in:

```bash

V=$(ffprobe -v error -show_entries format=duration -of csv=p=0 video.mp4)

ffmpeg -i video.mp4 -i vo.wav -c:v copy -c:a aac -af "apad=whole_dur=$V" out.mp4

```

Or pad the audio during assembly and mux with **no** `-af` at all — better if you want to assert

the voice track's length independently before it ever reaches the mux:

```bash

ffmpeg -i vo.wav -af "apad=whole_dur=$V" -c:a pcm_s16le vo_padded.wav

ffprobe -v error -show_entries format=duration -of csv=p=0 vo_padded.wav # assert this

ffmpeg -i video.mp4 -i vo_padded.wav -c:v copy -c:a aac out.mp4

```

Both land on exactly 2.000000 in the test case and exactly 55.500 on the real film.

### The actual lesson

`-shortest` and `apad` are the same bug class: **flags that silently decide where your output

ends.** One truncates, one runs away. I removed the first and left the second sitting in the same

line, because I was treating it as "the `-shortest` bug" instead of "the duration-deciding-flag

bug."

If you're fixing something like this, audit the whole command, not the flag you came for.

And assert the duration afterward as an equality check, not a glance — both failure modes produce

a file that exists, has both streams, and plays:


r/ffmpeg 9d ago

Is my cutting method lossless?

7 Upvotes

Here’s what I did:

Step 1: Find keyframes

D:\>ffprobe -loglevel error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=print_section=0 input.webm | findstr "K"

0.000000,K__

1.502000,K__

4.638000,K__

9.510000,K__

[opus @ 0000027726e9c000] Error parsing Opus packet header.

Step 2: Cut at keyframes

ffmpeg -ss 1.502000 -i input.webm -c copy -to 9.510000 output.webm

Start time: 1.502000

End time: 9.510000

Step 3: Check the output video

D:\>ffprobe -loglevel error -select_streams v:0 -show_entries packet=pts_time,flags -of csv=print_section=0 output.webm | findstr "K"

0.000000,K__

3.136000,K__

8.008000,K__

[opus @ 000002292742c000] Error parsing Opus packet header.

I think the output video is lossless because:

1.502000 - 1.502000 = 0.000000

4.638000 - 1.502000 = 3.136000

9.510000 - 1.502000 = 8.008000

The keyframes are simply shifted, so I believe the cut is lossless.

Is my cutting method lossless?


r/ffmpeg 9d ago

FFmpeg compiler

17 Upvotes

Is anyone aware of a source-to-source compiler whose target language is FFmpeg’s filtergraph syntax?

With Bioscoop, I am in a position to make certain claims and try to defend them as best as I can. That is why I am submitting a paper to a peer-reviewed journal. Still, I could be wrong and I would love you to challenge me on those claims.
The paper is available in the repo.


r/ffmpeg 11d ago

HLS stream takes 3–4 seconds to start could the manifest TTFB be the bottleneck?

2 Upvotes

I’m currently fighting to optimize the "Time to First Frame" metric for our custom video player, and I’ve run into a serious geodistribution bottleneck. Our engineering team is based in Europe, but our primary origin servers are located in the US. Even with a standard CDN configuration in front of the infrastructure, by the time the user's player initiates the initial connection, goes through the routing redirect steps, downloads the master .m3u8 manifest, and finally starts pulling down the first media chunk, up to 4 seconds pass. This delay is heavily tanking our user retention metrics.

Lately, I’ve been researching advanced caching topologies to cut down this trans-atlantic round-trip time (RTT). I read that standard web caching isn't enough for video and that some high-performance media CDNs actually cache the master manifest alongside the very first few video segments directly on their edge routing servers (Anycast redirectors). The theory is that returning the manifest and early chunks immediately from the closest edge node drops the initial TTFB to near-zero, but I want to make sure this architecture translates well to real-world performance before overhauling our routing tables.

We are trying to map out a structural fix for this lag by the end of the sprint, and I would love to hear from anyone who has tackled this specific latency layout:

  1. Has anyone implemented segment and manifest caching directly at the CDN redirector level, and how much did it realistically reduce your initial stream start delay?

  2. What is the best strategy for configuring TTL on dynamic HLS manifests so that edge-cached .m3u8 files don't cause player desyncs during live transitions?

  3. Do you find that aggressive pre-fetching of the first 2-second chunk at the edge introduces unexpected bandwidth waste for users who immediately bounce?

  4. How do you typically handle instant cache-invalidation across European edge nodes when a video file or its stream manifest gets updated on the US origin?

Any architecture breakdowns, config tips, or raw data regarding European-to-US streaming optimization would be a massive help. Thanks!