← Wiki personnel

Convertir des vidéos pour le web

29 janvier 2024

Convertir avec ffmpeg

A partir d’une vidéo de haute qualité, produire ces deux formats :

-vp9.webm

ffmpeg -i "$i" -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 1 -an -f null /dev/null && \
ffmpeg -i "$i" -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 2 -an "${i%.*}-vp9.webm"

Avec audio : sur la 2e passe remplacer -an par -c:a libopus -b:a 64k.

-compat.mp4

ffmpeg -i "$i" -c:v libx264 -profile:v main -level 3.1 -pix_fmt:v yuv420p -movflags faststart -an "${i%.*}-vp9.webm"

Avec audio : remplacer -an par -c:a aac.

La vidéo MP4 peut parfois être très lourde. Pour limiter sa résolution, ajouter -vf scale=-2:480 pour 480p par exemple.

Il serait possible d’être encore plus compatible avec le profil baseline et l’AVC level 3, mais les paramètres proposés sont suffisants pour iOS depuis un moment.

Convertir un dossier

Sur Mac, appeler le fichier script.command par exemple.

Le placer dans le dossier au-dessus des vidéos.

Le code n’est pas élégant, je suis ouvert aux suggestions.

#!/bin/bash

mydir="$(dirname "$BASH_SOURCE")"
cd "$mydir"
printf "Choisir un dossier contenant des vidéos :\n"
select d in */; do test -n "$d" && break; echo "Sélection invalide, entrer le numéro du dossier."; done
cd "$d"
pwd

echo "Activer la piste audio ? (y/n)"
read -r keep_audio

echo "Convertir en (1) vp9 (2) h264 (3) vp9 et h264 ? (1/2/3)"
read -r convert_to

if [[ $convert_to != "1" ]]; then
    echo "Scale h264 video to 480p? (y/n)"
    read -r scale_down
fi

for i in *.{mp4,webm}
do
    if [[ -f "$i" ]]; then
        if [[ $convert_to != "2" ]]; then
            echo "Conversion de $i en ${i%.*}-vp9.webm..."
            if [[ $keep_audio == "y" ]]; then
                ffmpeg -loglevel warning -i "$i" -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 1 -an -f null /dev/null
                ffmpeg -loglevel warning -i "$i" -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 2 -c:a libopus -b:a 64k "${i%.*}-vp9.webm"
            else
                ffmpeg -loglevel warning -i "$i" -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 1 -an -f null /dev/null && \
                ffmpeg -loglevel warning -i "$i" -c:v libvpx-vp9 -b:v 0 -crf 30 -pass 2 -an "${i%.*}-vp9.webm"
            fi
        fi
        if [[ $convert_to != "1" ]]; then
            echo "Conversion de $i en ${i%.*}-compat.mp4..."
            if [[ $keep_audio == "y" ]]; then
                if [[ $scale_down == "y" ]]; then
                    ffmpeg -loglevel warning -i "$i" -c:v libx264 -profile:v main -level 3.1 -pix_fmt:v yuv420p -movflags faststart -vf scale=-2:480 -c:a aac "${i%.*}-compat.mp4"
                else
                    ffmpeg -loglevel warning -i "$i" -c:v libx264 -profile:v main -level 3.1 -pix_fmt:v yuv420p -movflags faststart -c:a aac "${i%.*}-compat.mp4"
                fi
            else
                if [[ $scale_down == "y" ]]; then
                    ffmpeg -loglevel warning -i "$i" -c:v libx264 -profile:v main -level 3.1 -pix_fmt:v yuv420p -movflags faststart -vf scale=-2:480 -an "${i%.*}-compat.mp4"
                else
                    ffmpeg -loglevel warning -i "$i" -c:v libx264 -profile:v main -level 3.1 -pix_fmt:v yuv420p -movflags faststart -an "${i%.*}-compat.mp4"
                fi
            fi
        fi
    fi
done

HTML

<video>
  <source src="video-vp9.webm" type='video/webm; codecs="vp9, vorbis"'>
  <source src="video-compat.mp4" type="video/mp4">
</video>

Thumbnail

Non testé.

ffmpeg -i "$i" -ss 00:00:00 -vframes 1 "${i%.*}-thumb.webp"