Created
November 27, 2023 11:48
-
-
Save alexozwald/2c72126b7a9946671fd3ebf6e1a557ce to your computer and use it in GitHub Desktop.
to-avif ZSH conversion script using SVT-AV1 and ffmpeg
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
#!/usr/bin/env zsh | |
local img img_out img_short size_in_B size_out_B size_in size_out img_in_short img_out_short pct_diff | |
# Output coloring: Leep this compatability workaround or manually load the plugin using your plugin manager | |
[[ ! -e "/tmp/colors.plugin.zsh" ]] && curl -s "https://raw.githubusercontent.com/zpm-zsh/colors/master/colors.plugin.zsh" -o /tmp/colors.plugin.zsh | |
source /tmp/colors.plugin.zsh | |
# source ~/.zi/plugins/zpm-zsh---colors/colors.plugin/zsh | |
for IMG in ${argv[@]}; do | |
IMG_out="${IMG%.*}.avif" | |
IMG_in_short="${IMG:t}" | |
IMG_out_short="${IMG_out:t}" | |
size_in_B="$(STAT -f%z "$IMG")" | |
size_in="$(numfmt --to=iec $size_in_B)" | |
[[ -e "$IMG_out" ]] && { echo "UNEXPECTED ERROR: FILE '$IMG_out' EXISTS."; return 0; }; | |
ffmpeg -hide_banner -y -loglevel error -i "$IMG" -c:v libsvtav1 -qp 0 -svtav1-params 'preset=0:fast-decode=1' "${IMG%.*}.avif" \ | |
|| ffmpeg -hide_banner -y -loglevel error -i "$IMG" -c:v libsvtav1 -qp 0 "${IMG%.*}.avif" \ | |
|| ffmpeg -hide_banner -y -loglevel error -i "$IMG" -vf "scale=ceil(iw/2)*2:ceil(ih/2)*2" -c:v libsvtav1 -qp 0 -svtav1-params 'preset=0:fast-decode=1' "${IMG%.*}.avif" \ | |
|| ffmpeg -hide_banner -y -loglevel error -i "$IMG" -vf "scale=ceil(iw/2)*2:ceil(ih/2)*2" -c:v libsvtav1 -qp 0 "${IMG%.*}.avif" \ | |
|| { echo "${c[bold]}${c[red]}ERROR: ${c[base]}faied to write '${IMG%.*}.avif' - proceeding...${c[reset]}" && return 1 } | |
exiftool -overwrite_original -tagsFromFile "$IMG" -FileModifyDate -FileCreateDate "${IMG%.*}.avif" | |
size_out_B="$(STAT -f%z $IMG_out)" | |
size_out="$(numfmt --to=iec $size_out_B)" | |
pct_diff="$(awk "BEGIN {print ((( $size_out_B - $size_in_B ) / $size_in_B ) * 100)}")%" | |
[[ $((size_out_B - size_in_B)) -le 0 ]] && pct_color='green' || pct_color='red' | |
echo "${c[bold]}Converted file:${c[base]} '${c[green]}$IMG_in_short${c[base]}' -> '${c[green]}$IMG_out_short${c[base]}' ($IMG_out_short)${c[reset]}" | |
echo "${c[bold]}AVIF Size Reduction:${c[base]} ${c[light_blue]}$size_in${c[base]} -> ${c[light_blue]}$size_out${c[base]} (${c[$pct_color]}$pct_diff${c[base]} change)${c[reset]}" | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
[orig posted on r/av1]
hi all. i've noticed that most of the ffmpeg/imagemagick/graphicsmagick conversions to AVIF can be pretty trash at times. I've explored using the following libraries: AOM Codec (
libaom
), rav1e (librav1e
), and SVT-AV1 (libsvtav1
). For a variety of pictures from different sources, color profiles, etc, I noticed severe inconsistencies in encoding time, size, efficiency, and other limitations (namely 8k+ support). My verdict is that SVT-AV1 reigns far supreme.So I wrote the following script using ffmpeg built with svt-av1 specifically (try
brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-rav1e --with-svt-av1
), and exiftool to transfer the metadata. There are issues in AVIF images when resolution is >8k or the # of pixels in any dimension is odd not even. This script will convert any type even with those limitations trying at first only the best custom params, and then widdle down limited params for 8k+ or to image-resizing workarounds for 'odd' resolutions.