Re-encode video files to AV1 or HEVC to save disk space. Prefers hardware encoders when available and falls back to software.
ffmpeg(withffprobe)- Optionally
python3, used to read Google Takeout.supplemental-metadata.jsonsidecars and embed the capture time and GPS location.
Hardware encoding needs a VAAPI render node (/dev/dri/renderD128) or a Vulkan
device with the matching ffmpeg encoders built in.
The script picks the first encoder available, in this order:
av1_vaapi— VAAPI hardware AV1 (needs the VAAPI device)hevc_vaapi— VAAPI hardware HEVChevc_vulkan— Vulkan hardware HEVClibx265— software HEVC
Pass --hevc to skip AV1 and start from hevc_vaapi.
When a hardware encoder can't decode the source codec (some drivers reject older formats such as wmv3), the encode is retried with software decode while still encoding on the GPU.
./av1-reencode.sh [OPTIONS] [FILE_OR_DIR ...]
With no path arguments it processes the current directory. Directories are
scanned one level deep for .mp4, .wmv, .avi, .mkv, .mov, .mpeg, and
.mpg files, and you're asked to confirm before a batch runs.
Output is written next to each source as NAME<suffix>.mp4 (suffix .av1 or
.hevc depending on the encoder), or into --outdir if given.
| Option | Description |
|---|---|
-q, --quality N |
Quality. Default 120 for AV1 (global_quality, 0=lossless, 255=worst), 28 for HEVC (0=lossless, 51=worst). |
-p, --preset NAME |
libx265 preset for software encode (default: medium). |
-s, --suffix SUF |
Output suffix before .mp4 (default: auto, .av1 or .hevc). |
-o, --outdir DIR |
Write outputs to DIR instead of alongside the source. |
-a, --audio-br BR |
Re-encode audio to AAC at this bitrate, e.g. 128k (default: copy source audio when possible). |
-r, --replace |
Replace the source with the output if the output is smaller. |
--newer |
Re-encode when the source is newer than an existing output. |
--force |
Overwrite existing outputs regardless of age. |
-n, --dry-run |
Print what would be done without encoding. |
--hevc |
Force HEVC instead of AV1. |
-h, --help |
Show help. |
Source audio is copied when the codec fits in an MP4 container (aac, mp3, ac3,
eac3, alac, opus). Anything else (for example wmav2 or vorbis) is re-encoded to
AAC 192k, since copying it would make the muxer reject the stream. Use
--audio-br to force AAC at a chosen bitrate for every file.
By default a source is skipped when its output already exists. --newer
re-encodes sources that are newer than their output; --force always
overwrites. Files carrying the output suffix are ignored during directory scans
so encodes aren't fed back in.
Re-encode one file:
./av1-reencode.sh clip.mp4
Re-encode a directory into a separate output folder, HEVC, higher quality:
./av1-reencode.sh --hevc -q 24 -o encoded/ ~/Videos
Preview a run without encoding:
./av1-reencode.sh -n ~/Videos
Re-encode in place and replace originals when the result is smaller:
./av1-reencode.sh -r clip.mp4
- Outputs are muxed with
+faststartfor streaming. - If an output ends up no smaller than the source, both files are kept.
- A summary at the end reports how many files were encoded, skipped, and failed, along with the total space saved.