Python scripts for batch video processing with ffmpeg. Each script walks a directory recursively, detects video files using ffprobe.
curl -sSL https://raw.githubusercontent.com/vherolf/ffmpeg-helper-tools/main/install.sh | bashRun the same command again at any time to update.
The script checks for system dependencies (python3, pip3, ffmpeg, ffprobe, git), clones or pulls the repo into ./ffmpeg-helper-tools (relative to where you run the command), creates a venv, and installs all packages.
Ubuntu / Debian: sudo apt install -y git python3 python3-pip python3-venv ffmpeg
macOS: brew install git python3 ffmpeg
After installing, run:
./build.shThis uses PyInstaller to compile each script into a self-contained binary in dist/. The binaries have no Python dependency — copy them anywhere and run directly:
./dist/compressor -s /videos -d /output
./dist/resizer -r 1080 -nffmpeg and ffprobe still need to be installed on the system.
git clone https://github.com/vherolf/ffmpeg-helper-tools.git
cd ffmpeg-helper-tools
python3 -m venv venv
venv/bin/pip install -r requirements.txtPrints the path, resolution, codec, and duration for every video found.
python analyzer.py
python analyzer.py -d /path/to/videosRe-encodes videos to H.265 (libx265) at CRF 28.
python compressor.py
python compressor.py -s /path/to/videos -d /path/to/output
python compressor.py -c 23 # lower CRF = higher quality (range 0–51)
python compressor.py -n # dry run — print actions without encodingDefaults: source = current directory, destination = ~/Desktop/compressed_videos, CRF = 28.
Resizes videos to 720p height while preserving aspect ratio.
python resizer.py
python resizer.py -s /path/to/videos -d /path/to/output
python resizer.py -r 1080 # resize to 1080p instead
python resizer.py -n # dry run — print actions without resizingDefaults: source = current directory, destination = ~/Desktop/resized_videos, resolution = 720.
Copies videos with spaces in filenames replaced by underscores.
python renamer.py
python renamer.py -s /path/to/videos -d /path/to/output
python renamer.py -n # dry run — print actions without copyingDefaults: source = current directory, destination = ~/Desktop/renamed_videos.
Merges pairs of videos found in the same folder side-by-side (default) or stacked vertically. Output goes to the current directory by default.
python mosaic.py # horizontal (side-by-side)
python mosaic.py -v # vertical (stacked)
python mosaic.py -d /path/to/videosEach subfolder must contain exactly 2 video files.
Like mosaic.py but uses _left / _right in filenames to determine order. The output filename is derived by stripping the _left / _right suffix.
python mosaic-left-right.py
python mosaic-left-right.py -d /path/to/videosSplits a wide video into 3 equal horizontal scenes using ffmpeg's crop filter. A video at 5760x1080 produces three 1920x1080 clips.
python videoslicer-horizontal.py
python videoslicer-horizontal.py -s /path/to/videos -d /path/to/outputFilenames must follow the format YYYY-MM-DD HH-MM-SS.ext (e.g. 2022-05-24 15-46-07.mkv).
Output is written to <destination>/<date>/<time>/. Defaults: source = current directory, destination = ~/Desktop/sliced_videos.
Splits a video into 2 equal vertical scenes using ffmpeg's crop filter. A video at 1920x1080 produces two 960x540 clips.
python videoslicer-vertical.pySame filename format requirement as videoslicer-horizontal.py.
Generates numbered test images (using Pillow) and converts them to videos — useful for testing the other scripts.
python generate-test-media.py # generate images + videos
python generate-test-media.py -l # list available fontsOutput is written to videos/, images/, and videos_merge/ in the current directory.
Shared helper used by all scripts. is_video(filename) runs ffprobe on the file and returns True if it contains a video stream — format-agnostic, works on any container.
ffmpeg -i input.MTS output.mp4
crf is 0-52 (23-28 is a good choice)
compress the videos with ffmpeg to h.265 (better)
ffmpeg -i videoin.mp4 -vcodec libx265 -crf 28 -c:a copy videoout.mp4 -y
compress the videos with ffmpeg to h.264 (for legacy systems)
ffmpeg -i input.MTS -crf 23 output.mp4
ffmpeg -i "concat:00008.MTS|00009.MTS|00021.MTS|00010.MTS" -crf 23 output.mp4
https://video.stackexchange.com/questions/4563/how-can-i-crop-a-video-with-ffmpeg
ffmpeg -i input.mp4 -filter:v crop=iw/2:ih/2:0:0 -c:a copy output.mp4
- The -ss parameter is the starting point.
- The -t provides the length of the clip
ffmpeg -i input.mp4 -ss 00:00:10 -t 00:20:00 -async 1 output.mp4
ffmpeg -i input.pm4 rainbowunicorn.gif
ffplay -rtsp_transport tcp -i rtsp://user:password@192.168.88.248:554/ipcam_mjpeg.sdp -fs
extract from old video camcorder over firewire
dvgrab -size=0 -rewind -t mpeg2 -showstatus -timesys -autosplit=10000
and to properly convert it to a mp4 use yadif filter
ffmpeg -i dv-grabbed-video.dv out.mp4