2026-11-06 18:25:31 +00:00
2026-10-09 18:58:50 +00:00
2026-10-09 18:58:50 +00:00
2026-10-09 18:58:50 +00:00
2026-10-09 18:58:50 +00:00
2026-10-09 18:58:50 +00:00
2026-10-09 18:58:50 +00:00
2026-10-09 18:58:50 +00:00
2026-10-09 18:58:50 +00:00

FFmpeg Wrapper

A desktop GUI for common ffmpeg jobs: remuxing MKV files to Jellyfin-friendly MP4s, choosing which audio tracks to keep, stripping audio, re-encoding, and scaling. Works on single files or whole batches. It's a single executable for Windows and Linux, built with Python, Qt (PySide6) and PyInstaller.

icon

Features

  • Single file or batch. Use Add Files, Add Folder (recursive), or drag and drop. Files are probed in the background and shown with duration, video info, and audio and subtitle counts.
  • Target container. MP4, MKV, MOV, M4V, WebM, AVI or MPEG-TS. The encoder lists only show codecs the chosen container can hold.
  • Audio track picker. Every audio track in the selected file is listed with its language, codec, channels and title. Tick the tracks you want and drag them into order. The first ticked track becomes the default. Apply to All Files copies your choice to the rest of the queue, matching tracks by language, codec and layout, so a season of episodes takes one click.
  • Strip audio. Set Audio mode to Strip audio.
  • Keep streams unaltered. Copy mode remuxes video and/or audio without re-encoding. Auto copies whatever the container supports and re-encodes only what it can't hold (for example DTS/TrueHD to AAC for MP4).
  • Up/downscale video. Pick 360p up to 8K, or a custom WxH, with aspect ratio kept and Lanczos scaling. Portrait and rotated phone videos are handled. You can also change the frame rate. Encoders: H.264, HEVC, AV1, VP9, MPEG-4, plus NVENC, QuickSync and AMF if your ffmpeg has them. There are CRF quality and speed preset controls.
  • Up/downmix audio. Change channels (mono, stereo, 5.1, 7.1), sample rate, bitrate, and codec (AAC, AC-3, E-AC-3, Opus, MP3, Vorbis, FLAC, ALAC, PCM).
  • Output folder. Save next to the source or in a chosen folder. You can add a filename suffix and choose what happens when the output file already exists (keep both, overwrite, or skip). The source file is never overwritten.
  • Subtitles are kept where possible. MP4 and MOV turn text subs into mov_text, and image subs (PGS) are dropped with a note in the log. MKV keeps everything, including font attachments.
  • MP4/MOV outputs get +faststart, and HEVC is tagged hvc1 for Apple and TV compatibility.
  • The window shows per-file and overall progress, has a Stop button, and keeps a full log. Show Command prints the exact ffmpeg command so you can copy it.
  • ffmpeg writes to name.part.ext and the file is renamed only on success, so a failed or cancelled job never leaves a half-written file.

Getting ffmpeg

The app looks for ffmpeg and ffprobe in this order:

  1. The folder set in Settings > Set FFmpeg Location...
  2. Next to the executable (or in ffmpeg/, ffmpeg/bin/ or bin/ beside it)
  3. Your PATH

The release archives (FFmpegWrapper-<version>-windows-x64.zip / -linux-x64.tar.gz) already include ffmpeg and ffprobe next to the executable, with ffmpeg's license as ffmpeg-LICENSE.txt. If you use the bare executable, install ffmpeg (sudo apt install ffmpeg, winget install ffmpeg, ...) or point the app at it.

Running from source

python -m venv .venv
.venv/bin/pip install -r requirements-dev.txt        # Windows: .venv\Scripts\pip ...
python scripts/fetch_ffmpeg.py                        # optional: downloads ffmpeg into ./ffmpeg/bin
python run.py

Tests: python -m pytest. The integration tests run real conversions when ffmpeg is found, either on PATH or through FFWRAP_FFMPEG_DIR=ffmpeg/bin.

Building the executables

PyInstaller does not cross-compile. Build the Windows .exe on Windows and the Linux binary on Linux.

pip install -r requirements-dev.txt
python build.py                              # -> dist/FFmpegWrapper  or  dist/FFmpegWrapper.exe
python build.py --ffmpeg-dir ffmpeg/bin      # also bundles ffmpeg + ffprobe + their license into a .zip / .tar.gz
python scripts/smoke_test.py dist/FFmpegWrapper   # optional: headless start-up check

--onedir builds a folder instead of a single file. It starts faster because nothing has to be unpacked on launch.

CI: .github/workflows/build.yml builds, tests and smoke-tests both platforms on every v* tag (or a manual run) and attaches the archives to the release. Gitea and Forgejo Actions can run it too, but they need a Windows runner registered.

Notes

  • Linux: the binary needs glibc 2.35 or newer (Ubuntu 22.04+, Debian 12+, Fedora 36+, Mint 21+). It bundles the Qt XCB libraries, but uses the system's OpenGL/EGL driver libraries. To get a menu entry, copy assets/icon.png and write a .desktop file that points at the binary.
  • PySide6 is pinned below 6.12. PySide6 6.12.0 mis-counts references to Python's None (in QComboBox.clear()/currentData()), which crashes the app on Python 3.11. Python 3.12+ is not affected, but keep the pin until a fixed PySide6 ships.
  • ffmpeg licensing: the bundled ffmpeg builds come from BtbN/FFmpeg-Builds and are GPLv3, so their license has to ship with them. scripts/fetch_ffmpeg.py saves it as ffmpeg/LICENSE.txt, and build.py --ffmpeg-dir copies it into the archive as ffmpeg-LICENSE.txt. It looks in the ffmpeg folder and the folder above it, and stops with an error if the license isn't in either.
  • Settings (last options, window size, ffmpeg location) are saved per user through Qt's QSettings: the registry on Windows, ~/.config/ffwrap/FFmpegWrapper.conf on Linux.

Project layout

ffwrap/
  formats.py      container/encoder tables and compatibility rules (no Qt)
  probe.py        ffprobe -> MediaInfo/Stream dataclasses
  command.py      Options -> ffmpeg arguments, output naming, audio-track matching (no Qt)
  tools.py        locating ffmpeg/ffprobe, encoder detection
  gui/            main window, queue model, QProcess batch runner
build.py          PyInstaller build + packaging
scripts/          fetch_ffmpeg.py, smoke_test.py, make_icon.py
tests/            unit tests + real-ffmpeg integration tests

License

Kopimi

FFmpeg Wrapper is public domain, released under the Unlicense. Kopimi: copy it, change it, share it, sell it. No permission needed.

That covers this project's own code. The ffmpeg and ffprobe binaries in the release archives are GPLv3 (license in ffmpeg-LICENSE.txt, source at https://ffmpeg.org/download.html), and the Qt libraries built into the executable are LGPLv3.

Description
No description provided
Readme Unlicense 106 KiB
2026-11-06 18:18:55 +00:00
Languages
Python 100%