mefody.dev

Easy video converting for the web

I want to keep my blog performant. So when there are some videos in an article, I need to convert videos to modern formats to make them smaller.

HTML

Andrey Sitnik wrote a great article about video codecs for the web. I customized the snippet from the article for my needs.

<video width="600" height="400" controls muted playsinline preload="metadata">
    <source src="video.av1.mp4" type="video/mp4; codecs=av01.0.05M.08">
    <source src="video.h264.mp4" type="video/mp4">
</video>

This snippet works great in modern Chrome and Firefox with AV1-codec supported, falling back to the bulletproof H264-codec for other browsers.

ffmpeg

To convert source videos for the web you can use ffmpeg. For macOS, it’s just brew install ffmpeg. This is a really great tool to work with videos. But its synopsis is not so easy to remember. And it’s not copypastable because of the strict order of arguments. For example, here is a snippet for converting to H264.

ffmpeg -i input.mov -map_metadata -1 -an -c:v libx264 \
-crf 24 -preset veryslow -profile:v main -pix_fmt yuv420p \
-movflags +faststart -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
output.h264.mp4

I don’t want to remember it!

Bash aliases

Let’s make aliases for Bash. Open your ~/.bashrc (or ~/.zshrc if you use ZSH instead of Bash). Add the next code to the end of the file.

function convert-to-h264 {
    if [[ $2 ]];
        then output=$2
        else output=${1%.*}.h264.mp4
    fi

    ffmpeg -i $1 -map_metadata -1 -an -c:v libx264 \
    -crf 24 -preset veryslow -profile:v main -pix_fmt yuv420p \
    -movflags +faststart -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
    $output
}

Save the file, then apply it with source ~/.bashrc (or source ~/.zshrc for ZSH). Voila, you can use new alias to easily convert your videos.

convert-to-h264 input.mov # converts to input.h264.mp4 by default
# or
convert-to-h264 input.mov output.mp4

I also have other aliases for my blog videos.

function convert-to-av1 {
    if [[ $2 ]];
        then output=$2
        else output=${1%.*}.av1.mp4
    fi

    ffmpeg -i $1 -map_metadata -1 -an -c:v libaom-av1 -crf 50 -b:v 0 \
    -pix_fmt yuv420p -movflags +faststart -vf "scale=trunc(iw/2)*2:trunc(ih/2)*2" \
    -strict experimental -cpu-used 1 \
    $output
}

function resize-to-width {
    if [[ $3 ]];
        then output=$3
        else output=${1%.*}@$2.${1##*.}
    fi

    ffmpeg -i $1 -vf "scale="$2":trunc(ow/a/2)*2" $output
}

So my workflow with videos usually consists of three commands.

resize-to-width source.mov 1200 video.mov
convert-to-h264 video.mov
convert-to-av1 video.mov

Sources

Webmentions [?]

  1. Для оптимизации видео я использую ffmpeg. Но запоминать все его параметры — боль. Каждый раз их гуглить — тоже. Поэтому я их не запоминаю, а собрал для себя несколько Bash-алиасов, которые в случае необходимости можно подстроить под новые нужды.