Last active
November 18, 2024 14:02
-
-
Save gphg/1dd083b89bddd17548eb721d6475433c to your computer and use it in GitHub Desktop.
My attempt on writing script for ffmpeg on WEBM.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Usage: | |
# v9-ffmpeg.sh 720 input.mp4 | |
# v9-ffmpeg.sh 720 input.mp4 output.webm | |
# | |
# Best usage for scaling down video OR just simply reencode video into WEBM. | |
# Change me. | |
OUTPUT_PREFIX="" | |
# Set to 0 as it is. | |
OUTPUT_BASECRF="0" | |
__get_info() { | |
local input="$1" | |
local entry="$2" | |
ffprobe -v error -select_streams v:0 -of default=nw=1:nk=1 \ | |
-show_entries stream="$entry" "$input" | |
} | |
__encode() { | |
local target="$1" | |
local input="$2" | |
local output="$3" | |
local w=$(__get_info "$input" "width") | |
local h=$(__get_info "$input" "height") | |
# https://developers.google.com/media/vp9/settings/vod/#recommended_settings | |
local filter | |
local scale | |
local bitrate | |
local minrate | |
local maxrate | |
local qcrf | |
local tcolumn1=1 | |
local tcolumn2=1 | |
local threads=4 | |
case $target in | |
1080) | |
# For modern mobile device storing | |
scale="1080" | |
qcrf="19" | |
tcolumn1=2 | |
tcolumn2=3 | |
threads=8 | |
;; | |
720) | |
# For reasonable online sharing | |
scale="720" | |
qcrf="20" | |
tcolumn1=2 | |
tcolumn2=2 | |
threads=8 | |
;; | |
480) | |
# 10+ mins long or VGA | |
scale="480" | |
qcrf="24" | |
;; | |
360) | |
# Half of 720p | |
scale="360" | |
qcrf="28" | |
;; | |
240) | |
# Very 2000-ish (OR MEME QUALITY; DO NOT REMOVE) | |
scale="240" | |
qcrf="30" | |
;; | |
*) | |
echo "Preset doesn't exist." | |
exit 1 | |
;; | |
esac | |
# Output follows input with different file extension, relative to CWD | |
if [ -z "$output" ]; then | |
output=$(basename "${input%.*}.webm") | |
fi | |
# Portrait orientation? | |
if [[ $h -gt $w ]]; then | |
filter="scale=${scale}:-2" | |
else | |
filter="scale=-2:${scale}" | |
fi | |
# Recalculate crf base: 18 to 23 = lossless | |
qcrf=$(( $OUTPUT_BASECRF + $qcrf )) | |
# 35 is the maximum recommended | |
qcrf=$(( $qcrf < 35 ? $qcrf : 35 )) | |
# lesser than 18 is placebo | |
qcrf=$(( $qcrf > 18 ? $qcrf : 18 )) | |
# https://developers.google.com/media/vp9/settings/vod/#ffmpeg_command_lines | |
ffmpeg -i "$input" -vf "$filter" \ | |
-tile-columns "$tcolumn1" -g 240 -threads "$threads" -quality good -crf "$qcrf" \ | |
-c:v libvpx-vp9 -c:a libopus -b:a 256k -pass 1 -speed 4 "${OUTPUT_PREFIX}${output}" && \ | |
ffmpeg -i "$input" -vf "$filter" \ | |
-tile-columns "$tcolumn2" -g 240 -threads "$threads" -quality good -crf "$qcrf" \ | |
-c:v libvpx-vp9 -c:a libopus -b:a 256k -pass 2 -speed 4 -y "${OUTPUT_PREFIX}${output}" | |
} | |
# Pass the args into function. This script only takes one file. | |
__encode "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Omitted
bitrate
,minbitrate
, andmaxbitrate
. Previous version can be viewed here: https://gist.github.com/gphg/1dd083b89bddd17548eb721d6475433c/474a465094e8102e6cea1e03d46ac9f3d12294b3It is now tied to CRF clamp between 18 and 35.