Mapping des flux avec ffmpeg
FFmpeg permet de manipuler l'ordre des flux audio ou vidéo contenus dans un format (ou un container) à l'aide du mapping. Cette fonctionnalité est très utile et simple à mettre en place lorsque l'on a compris le principe. On peut ajouter un sous-titre à une vidéo facilement, dupliquer une piste, faire une extraction juste de l'audio ou juste inverser l'ordre des flux.
Je m'attarde sur cette fonctionnalité parce qu'elle me semble essentielle à la bonne prise en main de ffmpeg.
Et surtout, une fois que l'on a compris cela, on peut quasiment tout faire.
Contenu de l'élément à traiter:
Un format (ou container) en .mkv par exemple peut contenir plusieurs flux vidéo, audio ou sous-titres ainsi que des meta-donnés. On parle de flux ou de stream.
Pour cet exemple j'ai téléchargé à l'aide de cclive la bande d'annonce du projet Gooseberry de la fondation Blender disponible en creative commons sur Youtube:
cclive -s fmt43_360p https://www.youtube.com/watch?v=XfezG5M2ICg
En interrogeant ffmpeg sur la vidéo, on peut se rendre compte de son contenu:
ffmpeg -i GooseberryTeaser.mp4
On peut voir qu'il y a deux flux, un de vidéo numéroté en zéro:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x536 [SAR 2144:2145 DAR 1024:429], 1246 kb/s, 24 fps, 24 tbr, 24 tbn, 48 tbc (default)
et un flux audio numéroté en un:
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
Je m'attarde sur cette fonctionnalité parce qu'elle me semble essentielle à la bonne prise en main de ffmpeg.
Et surtout, une fois que l'on a compris cela, on peut quasiment tout faire.
Contenu de l'élément à traiter:
Un format (ou container) en .mkv par exemple peut contenir plusieurs flux vidéo, audio ou sous-titres ainsi que des meta-donnés. On parle de flux ou de stream.
Pour cet exemple j'ai téléchargé à l'aide de cclive la bande d'annonce du projet Gooseberry de la fondation Blender disponible en creative commons sur Youtube:
cclive -s fmt43_360p https://www.youtube.com/watch?v=XfezG5M2ICg
En interrogeant ffmpeg sur la vidéo, on peut se rendre compte de son contenu:
ffmpeg -i GooseberryTeaser.mp4
On peut voir qu'il y a deux flux, un de vidéo numéroté en zéro:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x536 [SAR 2144:2145 DAR 1024:429], 1246 kb/s, 24 fps, 24 tbr, 24 tbn, 48 tbc (default)
et un flux audio numéroté en un:
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
Mapping:
Dans notre cas le mapping permet par exemple de dupliquer un flux audio:
ffmpeg -i GooseberryTeaser.mp4 -map 0:0 -map 0:1 -map 0:1 -c copy GooseberryTeaserOut.mp4 J'ai fait une copie à l'identique du flux audio:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x536 [SAR 2144:2145 DAR 1024:429], 1246 kb/s, 24 fps, 24 tbr, 24 tbn, 48 tbc (default)
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
Stream #0:2(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
Je peux éventuellement faire un traitement sur la piste audio que je viens de dupliquer:
ffmpeg -i GooseberryTeaser.mp4 -map 0:0 -map 0:1 -map 0:1 -c:v copy -c:a:0 copy -c:a:1 libvorbis -qscale:a 5 -ar 48000 GooseberryTeaserOut.mp4
J'ai fait une conversion en vorbis, avec modification de l'échantillonnage (48khz) ainsi que de la compression:
Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p, 1280x536 [SAR 2144:2145 DAR 1024:429], 1246 kb/s, 24 fps, 24 tbr, 12288 tbn, 48 tbc (default)
Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 191 kb/s (default)
Stream #0:2(und): Audio: vorbis (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 139 kb/s (default)
-c:v copy me permet de copier à l'identique tout les flux vidéo.
-c:a:0 copy me permet de copier à l'identique le premier flux audio:
-c:a:1 libvorbis -qscale:a 5 -ar 48000 me permet d'appliquer la conversion en vorbis qu'au flux audio n°2
(Mélanger du 44100Hz avec du 48000Hz est un mauvaise idée, à ne pas faire dans la vraie vie :) )
Ici, j'ai donc procédé au mapping,puis j'ai fais la conversion:
Extraction:
Donc si on peut dupliquer une piste, je peux en supprimer, il me suffit de ne pas déclarer tout les flux:
ffmpeg -i GooseberryTeaser.mp4 -map 0:1 -c:a copy GooseberryTeaser_Son.mp4
Insertion:
A l'inverse, avec deux fichiers en entrée (input) je peux faire de l'assemblage:
ffmpeg -i GooseberryTeaser.mp4 -i GooseberryTeaser_Son.mp4 -map 0:0 -map 0:1 -map 1:0 -c copy GooseberryTeaserOut.mp4
- -map 0:0 faisant référence au premier flux du premier “input” : soit la vidéo du fichier “ GooseberryTeaser.mp4”
- -map 1:0 faisant référence au premier flux du deuxième “input” : soit l'unique piste audio du fichier “GooseberryTeaser_Son.mp4”
Une fois ce principe compris, vous pourrez faire vos propres assemblages, ou extractions, la manipulation des flux devient plus facile.
Sachez tout de même que toutes les combinaisons ne sont pas possible, comme de la vidéo dans du mp3, tout dépends du container que vous aurez choisit.
Pour aller plus loin, j'ai rédigé un tuto assez complet sur ffmpeg ici:
Ce billet était juste là pour mettre en lumière, cette fonction que je trouve maintenant indispensable.