#! /bin/sh set -e usage () { cat <&2; } Usage: $0 [OPTIONS...] SRC [SRC...] Re-encodes to h.264, preserving audio and subtitles. Output will be written to \$SRC.h264.mp4 -height H Rescale to no taller than H -1080p Rescale to no bigger than 1080p -720p Rescale to no bigger than 720p -480p Rescale to no bigger than 480p -bitrate B Set average bitrate to B, overriding rescale setting or CRF -crf C Set CRF to C, overriding rescale setting or bitrate -swenc Software encode instead of hardware EOD height=ih codec=h264_v4l2m2m bitrate="-b:v 2048k" while true; do case "$1" in -height|--height) height=$2 shift 2 ;; -1080p|--1080p) height=1080 bitrate="-b:v 2048k" shift ;; -720p|--720p) height=720 bitrate="-b:v 1200k" shift ;; -480p|--480p) height=480 bitrate="-b:v 512k" shift ;; -bitrate|--bitrate) bitrateManual="-b:v $2" shift 2 ;; -crf|--crf) bitrateManual="-crf $2" shift 2 ;; -swenc|--swenc) codec=h264 shift ;; -*) usage exit ;; *) break ;; esac done if [ "$codec" = "h264" ]; then bitrate="-crf 28" fi bitrate=${bitrateManual:-$bitrate} log () { echo "=== $*" } cmd () { nice "$@" } # This got a height of 719 (n%2 must = 0) #-vf "scale='min($width,iw)':'min($height,ih)':force_original_aspect_ratio=decrease,format=yuv420p" \ for fn in "$@"; do base=${fn%.*} filename=$(basename "$fn") intermediate="$base.nut" out="$base.h264.mkv" [ -f "$out" ] && continue case "$fn" in *.h264.mp4) continue ;; esac # ffmpeg has some bizarro thing where the h264_v4l2m2m codec won't write to a mkv file, # In addition, some subtitles interfere with it too. # Solution: transcode video + audio into an intermediate file, # then add back any subtitles. log "$filename - Scale/Transcode" cmd ffmpeg \ -hide_banner \ -loglevel warning \ -stats \ -i "$fn" \ -map 0:v \ -vf "scale=-2:'min($height,ih)':force_original_aspect_ratio=decrease,format=yuv420p" \ -c:v $codec \ $bitrate \ -map 0:a \ -c:a copy \ -num_capture_buffers 16 \ -num_output_buffers 32 \ -y \ "$intermediate" log "$filename - Add subtitles" cmd ffmpeg \ -hide_banner \ -loglevel warning \ -stats \ -i "$intermediate" \ -i "$fn" \ -map 0:v \ -map 0:a \ -map 1:s? \ -c copy \ -y \ "$out" rm "$intermediate" done