ffmpeg permet de modifier des flux audio / vidéo / sous-titre d'un fichier vidéo mp4 mkv avi.
J'ai 2 fichiers vidéo, fichier0.mp4 et fichier1.avi.
Le fichier0 est de bonne qualité vidéo, et la bande son en anglais.
Le fichier1 est de moyenne qualité vidéo, et la bande son est en français.
Je désire une vidéo de bonne qualité avec le son en français avec un second son en anglais. J'ai aussi les sous-titres en français et en anglais que je veux mettre dans le fichier vidéo.
Je dois tout d'abord regarder comment sont constitués les fichiers vidéo grâce à la commande ffprobe.
>ffprobe fichier0.mp4 ... Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/unknown), 1280x536 [SAR 1:1 DAR 160:67], 905 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc (default) Metadata: creation_time : 2014-09-17T11:05:33.000000Z handler_name : video.264#trackID=1:fps=23.976 - Imported with GPAC 0.5.0-rev4065 Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 93 kb/s (default) Metadata: creation_time : 2014-09-17T11:05:42.000000Z handler_name : GPAC ISO Audio Handler >ffprobe fichier1.avi ... Stream #0:0: Video: mpeg4 (Simple Profile) (XVID / 0x44495658), yuv420p, 720x300 [SAR 1:1 DAR 12:5], 720 kb/s, 23.98 fps, 23.98 tbr, 23.98 tbn, 23.98 tbc Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 128 kb/s
les flux sont souvent 0 pour la vidéo, 1 pour l'audio principale, 2 pour l'audio secondaire…, on trouve ensuite les sous-titres.
ffmpeg prend en entrée des fichiers, et ensuite on lui dit quoi faire des flux.
ffmpeg -i fichier0.mp4 -i fichier1.avi -i sous-titres.fr.srt -i sous-titres.en.srt \ -map 0:v \ -map 1:1 -metadata:s:a:0 language=fre -disposition:a:0 default \ -map 0:1 -metadata:s:a:1 language=eng -disposition:a:1 none \ -map 2 -metadata:s:s:0 language=fre \ -map 3 -metadata:s:s:1 language=eng \ -c copy video.mkv
Explication de la commande ci-dessus :
Sur la première ligne, on met tous les fichiers en entrée
ensuite :
- sur le flux 0 (le premier fichier), on prend la vidéo seulement
- sur le flux 1:1 (le second fichier), on ne prend que l'audio (piste son french), on lui dit que la médadonnée stream audio 0 sera de langage french et que l'audio 0 sera la piste audio par défaut
- sur le flux 0:1 (la piste son en anglais), on lui dit que c'est une piste en anglais, et qu'il n'y a aucune priorité. J'ai été obligé de lui dire car cette piste est par défaut dans le flux d'origine.
- sur le flux 2 (sous-titre français), on dit dans les métadonnée du flux sous-titre 0 que le langage est french
- sur le flux 3 (sous-titre anglais), on dit dans les métadonnée du flux sous-titre 1 que le langage est english
- on dit à ffmpeg qu'on ne fera que des copies, donc il n'y aura aucun encodage à faire et on lui donne le fichier de sortie.
De l'ordre des fichiers d'entrée va dépendre les commandes map et donc tout ça modifie l'ordre des flux dans le fichier de sortie. Ici, j'ai fait un exemple ordonné, mais vous pouvez ordonner les fichiers dans l'ordre qui vous plaît, du moment que vous modifiez les numéros de flux dans les commandes map. Par contre, l'ordre des map va donner l'ordre des flux dans le fichier de sortie.
Dans cet exemple, chaque flux traité est sur une ligne pour faciliter la lecture. La commande que je viens d'expliquer donne un fichier video.mkv avec le détail suivant :
>ffprobe video.mkv ... Input #0, matroska,webm, from 'video.mkv': Metadata: COMPATIBLE_BRANDS: isomavc1 MAJOR_BRAND : isom MINOR_VERSION : 1 ENCODER : Lavf57.83.100 Duration: 01:53:35.88, start: 0.000000, bitrate: 1133 kb/s Stream #0:0: Video: h264 (High), yuv420p(tv, bt709/bt709/unknown, progressive), 1280x536 [SAR 1:1 DAR 160:67], 23.98 fps, 23.98 tbr, 1k tbn, 47.95 tbc (default) Metadata: HANDLER_NAME : video.264#trackID=1:fps=23.976 - Imported with GPAC 0.5.0-rev4065 DURATION : 01:53:29.481000000 Stream #0:1(fre): Audio: mp3, 48000 Hz, stereo, s16p, 128 kb/s (default) Metadata: ENCODER : Lavf DURATION : 01:53:28.488000000 Stream #0:2(eng): Audio: aac (LC), 48000 Hz, stereo, fltp Metadata: HANDLER_NAME : GPAC ISO Audio Handler DURATION : 01:53:29.547000000 Stream #0:3(fre): Subtitle: subrip Metadata: DURATION : 01:53:27.229000000 Stream #0:4(eng): Subtitle: subrip Metadata: DURATION : 01:53:35.880000000
On voit très bien dans le résultat de la commande ffprobe, on a plusieurs flux :
- Stream #0:0: Video: h264
- Stream #0:1(fre): Audio: mp3
- Stream #0:2(eng): Audio: aac
- Stream #0:3(fre): Subtitle: subrip
- Stream #0:4(eng): Subtitle: subrip
Ces flux sont dans l'ordre des map de la commande qui a servi à créer ce fichier.
J'ai un file0.avi et un file1.srt le premier fichier se présente ainsi (ffprobe)
Input #0, avi, from 'file0.avi': Metadata: IAS1 : English Duration: 00:30:02.04, start: 0.000000, bitrate: 1824 kb/s Stream #0:0: Video: mpeg4 (Advanced Simple Profile) (XVID / 0x44495658), yuv420p, 576x432 [SAR 1:1 DAR 4:3], 1391 kb/s, 25 fps, 25 tbr, 25 tbn, 25 tbc Stream #0:1: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 137 kb/s Stream #0:2: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 134 kb/s Stream #0:3: Audio: mp3 (U[0][0][0] / 0x0055), 48000 Hz, stereo, s16p, 132 kb/s
Je désire récupérer le flux vidéo 0 et la première piste son 1 et inclure le sous-titre français file1.srt
ffmpeg -fflags +genpts -i file0.avi -i file1.srt \ -map 0:v \ -map 0:1 -metadata:s:a:0 language=eng -disposition:a:0 default \ -map 1 -metadata:s:s:0 language=fre \ -c copy video.mkv
En premier lieu, on désigne les fichiers d'entrée
On prend la piste vidéo
On prend la première piste audio (le flux 1 du fichier 0), piste audio par défaut en english
On prend le sous-titre, qui sera french
On ne fera que des copies sans conversion dans le fichier video.mkv Si l'erreur «Can't write packet with unknown timestamp» s'affiche à l'exécution, on peut rajouter l'option -fflags +genpts qui va recréer les timestamps. Cette erreur peut arriver quand on fait un changement de format vers une destination mkv.
>ffprobe video.mkv ... Input #0, matroska,webm, from 'video.mkv': ... Stream #0:0: Video: mpeg4 (Advanced Simple Profile), yuv420p, 576x432 [SAR 1:1 DAR 4:3], 25 fps, 25 tbr, 1k tbn, 25 tbc ... Stream #0:1(eng): Audio: mp3, 48000 Hz, stereo, s16p, 112 kb/s (default) ... Stream #0:2(fre): Subtitle: subrip
On voit bien ici les 3 flux dans le fichier video.mkv qu'on a généré précédemment.