#!/bin/bash # TODO # make pix_fmt a variable when svt supports more than 10bit/4:2:0 # stop avif mode fucking up png colors, if possible # add selection menus for audio and subtitle streams # script cannot handle input files with ' in the name # Dependencies: ffmpeg 6.1+ built with libplacebo-7+ and libsvtav1-3.1+ # Usage: ./av1encode.sh [file] [start] [stop] Input="$1" StartTime="$2" StopTime="$3" Filters=() encode() { TimeArgs=() if [[ "$StartTime" != "" && "$StopTime" != "" ]]; then TimeArgs=(-ss "$StartTime" -to "$StopTime") fi AudioOutput=() mapfile -t AudioProbe < <(ffprobe -v error -select_streams a:0 -show_entries stream=codec_name,channels -of default=noprint_wrappers=1:nokey=1 "$Input") if [[ ${AudioProbe[1]} != 2 ]]; then AudioOutput=(-c:a libopus -b:a 192k -ac 2) elif [[ ${AudioProbe[0]} == "flac" && ${AudioProbe[1]} == 2 ]]; then AudioOutput=(-c:a libopus -b:a 192k) else AudioOutput=(-c:a copy) fi SubsProbe=$(ffprobe -v error -select_streams s -show_entries stream=index -of csv=p=0 "$Input") if [[ $SubsProbe != "" ]]; then EscapedInput=$(printf "%q" "$Input") if [[ ${#Filters[@]} -eq 0 ]]; then Filters=(-vf subtitles="$EscapedInput") else string="${Filters[1]},subtitles=$EscapedInput" Filters=(-vf "$string") fi fi ffmpeg -hide_banner -i "$Input" "${TimeArgs[@]}" "${AudioOutput[@]}" "${Filters[@]}"\ -c:v libsvtav1 -preset "$Preset" -crf "$CRF" -pix_fmt yuv420p10le -svtav1-params tune=1:enable-tf=0"$1""$2"\ "${Input%.*}"_"$ffmpegaction"_preset"$Preset"_crf"$CRF"."$Ext" exit } quality() { printf "Enter an svt-av1 preset [0-12] or a script option [a, b, c]\nLower numbers mean higher visual quality, lower filesize and longer encoding time.\n" printf "a) Normal AV1 video (Preset 4, CRF 28, Variance Boost Off)\nb) Fast AV1 video (Preset 4, CRF 44, Variance Boost On)\nc) AVIF image (Preset 0, CRF 12)\n" Ext="mp4" useAvif="" varBoost="" while true; do read -r -p "#? " Preset if [[ $Preset == a ]]; then Preset=4 CRF=28 elif [[ $Preset == b ]]; then Preset=4 CRF=44 # VMAF >95 at preset 4 varBoost=":enable-variance-boost=1" elif [[ $Preset == c ]]; then Preset=0 CRF=12 Ext="avif" useAvif=":avif=1" elif [[ "$Preset" =~ ^[0-9]{,2}$ ]]; then printf "Enter a Constant Rate Factor (CRF) [1-63]" read -r -p "#? " CRF fi encode $useAvif $varBoost done } ffprobe -hide_banner -i "$1" printf "Choose a scaling factor: \n" select ffmpegaction in "scale1x" "dscale2x" "dscale4x" "scale2x" "scale4x" "exit"; do ExtraArgs="extra_opts=preset=high_quality:deband=no" case $ffmpegaction in scale1x) quality break ;; dscale2x) Filters=(-vf libplacebo=w=iw/2:h=ih/2:"$ExtraArgs") quality break ;; dscale4x) Filters=(-vf libplacebo=w=iw/4:h=ih/4:"$ExtraArgs") quality break ;; scale2x) Filters=(-vf libplacebo=w=iw*2:h=ih*2:"$ExtraArgs") quality break ;; scale4x) Filters=(-vf libplacebo=w=iw*4:h=ih*4:"$ExtraArgs") quality break ;; exit) break ;; esac done