972 votes

Comment concaténer deux fichiers MP4 à l'aide de FFmpeg ?

J'essaie de concaténer deux fichiers mp4 en utilisant ffmpeg. J'ai besoin que ce soit un processus automatique, c'est pourquoi j'ai choisi ffmpeg. Je convertis les deux fichiers en .ts et les concaténer, puis essayer d'encoder ces fichiers concaténés. .ts fichier. Les fichiers sont h264 et aac encodé et j'espère garder la même qualité ou aussi proche de l'original que possible.

ffmpeg -i part1.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part1.ts
ffmpeg -i part2.mp4 -vcodec copy -vbsf h264_mp4toannexb -acodec copy part2.ts
cat part1.ts part2.ts > parts.ts
ffmpeg -y -i parts.ts -acodec copy -ar 44100 -ab 96k -coder ac -vbsf h264_mp4toannexb parts.mp4

Malheureusement, je reçois le message d'erreur suivant de ffmpeg pendant l'encodage :

[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[h264 @ 0x1012600]sps_id out of range
[h264 @ 0x1012600]non-existing SPS 0 referenced in buffering period
[NULL @ 0x101d600]error, non monotone timestamps 13779431 >= 13779431kbits/s    
av_interleaved_write_frame(): Error while opening file

Cela se produit à peu près à mi-chemin de l'encodage, ce qui me fait penser que vous ne pouvez pas concaténer deux fichiers .ts ensemble et que cela fonctionne.

1691voto

rogerdpack Points 12806

FFmpeg dispose de trois méthodes de concaténation :

1. filtre vidéo concat

Utilisez cette méthode si vos entrées n'ont pas les mêmes paramètres (largeur, hauteur, etc.), ou n'ont pas les mêmes formats/codecs, ou si vous voulez effectuer un filtrage.

Notez que cette méthode effectue un ré-encodage de toutes les entrées. Si vous voulez éviter le ré-encodage, vous pouvez ré-encoder seulement les entrées qui ne correspondent pas afin qu'elles partagent le même codec et d'autres paramètres, puis utiliser le démuxeur concat pour éviter de tout ré-encoder.

ffmpeg -i opening.mkv -i episode.mkv -i ending.mkv \
-filter_complex "[0:v] [0:a] [1:v] [1:a] [2:v] [2:a] \
concat=n=3:v=1:a=1 [v] [a]" \
-map "[v]" -map "[a]" output.mkv

2. démultiplicateur de concat

Utilisez cette méthode lorsque vous voulez éviter un réencodage et que votre format ne prend pas en charge la concaténation au niveau du fichier (la plupart des fichiers utilisés par les utilisateurs généraux ne prennent pas en charge la concaténation au niveau du fichier).

$ cat mylist.txt
file '/path/to/file1'
file '/path/to/file2'
file '/path/to/file3'

$ ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.mp4

Pour Windows :

(echo file 'first file.mp4' & echo file 'second file.mp4' )>list.txt
ffmpeg -safe 0 -f concat -i list.txt -c copy output.mp4

3. protocole de concat

Utilisez cette méthode avec les formats qui prennent en charge la concaténation au niveau du fichier (MPEG-1, MPEG-2 PS, DV). Faites pas utiliser avec MP4.

ffmpeg -i "concat:input1|input2" -codec copy output.mkv

Cette méthode ne fonctionne pas pour de nombreux formats, dont le MP4, en raison de la nature de ces formats et de la concaténation simpliste effectuée par cette méthode.


En cas de doute sur la méthode à utiliser, essayez le démultiplicateur concat.

Voir aussi

5 votes

Le caractère d'échappement de l'invite de commande Windows est ^ ; j'ai également rencontré des problèmes avec les guillemets, donc c'est devenu : ffmpeg -i concat:input1^|input2 -codec copy output

1 votes

Réponse utile. Et elle a pris encore plus de sens pour moi quand j'ai lu cette variation : superuser.com/a/607384/74576

0 votes

J'aurais vraiment aimé trouver cette réponse il y a des heures, mais je vous remercie de m'avoir épargné de nombreuses heures supplémentaires. L'utilisation du style de protocole concat à partir d'un processus enfant dans un nœud me donnait toujours des erreurs "no such file or directory", mais fonctionnait lorsque je l'exécutais en ligne de commande. En passant au style de démuxeur concat, tout a fonctionné à merveille.

101voto

EllieBaby Points 11

J'essayais de concaténer trois .mp3 fichiers audio en un seul .m4a et cette commande ffmpeg fonctionne.

Commande d'entrée :

ffmpeg -i input1.mp3 -i input2.mp3 -i input3.mp3 \
       -filter_complex "concat=n=3:v=0:a=1" -f MOV -vn -y input.m4a

Signification de : -filter_complex "concat=n=3:v=0:a=1" :

concat signifie utiliser la fonction de concaténation (jonction) des médias.
n signifie confirmer le nombre total de fichiers d'entrée.
v signifie a une vidéo ? utiliser 0 = pas de vidéo, 1 = contient de la vidéo.
a signifie a un son ? utiliser 0 = pas d'audio, 1 = contient de l'audio.
-f signifie forcer le format de fichier défini (pour voir tous les formats supportés, utilisez ffmpeg -formats )
-vn signifie désactiver la vidéo (et aussi -an désactiverait l'audio si on ne le souhaite pas)
-y signifie écraser les fichiers de sortie (si le fichier de sortie existe déjà).

Pour plus d'informations : utiliser ffmpeg -h full imprimer toutes les options (y compris toutes les options spécifiques au format et au codec, très long)

4 votes

Si je l'utilise -f concat -safe 0 -i "file.txt" -c copy -y "OutPut.mp4" il concatène mais quand certaines vidéos sont avec audio et d'autres sans audio, cela ne fonctionne pas, comment puis-je résoudre ce problème ? Merci.

1 votes

Cela fonctionne. Merci pour l'explication détaillée dans votre réponse. C'est très utile.

2 votes

Ça a marché comme sur des roulettes, il fallait juste changer "v=0" en "v=1" et le reste était résolu !

67voto

cnd Points 94

Voici un moyen rapide (moins d'une minute) et sans perte de données de faire cela sans avoir besoin de fichiers intermédiaires :

ls Movie_Part_1.mp4 Movie_Part_2.mp4 | \
perl -ne 'print "file $_"' | \
ffmpeg -f concat -i - -c copy Movie_Joined.mp4

Le "ls" contient les fichiers à joindre. Le "perl" crée le fichier de concaténation à la volée dans un tube. La partie "-i -" indique à ffmpeg de lire depuis le tube.

(note - mes fichiers n'avaient pas d'espaces ou de trucs bizarres - vous aurez besoin d'un encodage shell approprié si vous voulez réaliser cette idée avec des fichiers "durs").

2 votes

Je l'ai fait sous OSX et ça a très bien marché ! Une solution sans perte rapide et impressionnante avec peu d'exigences.

4 votes

Avec un échappement approprié pour les fichiers contenant des espaces : ls Movie_Part_1.mp4 Movie_Part_2.mp4 | perl -ne '$_ =~ s/\n$//; print "file '"'"'$_'"'"'\n"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4

4 votes

Vous pouvez aussi simplement faire ls * | perl -ne 'print "file $_"' | ffmpeg -f concat -i - -c copy Movie_Joined.mp4 si vos fichiers sont bien nommés et en ordre. Cela a très bien fonctionné pour moi sur OS X, exactement ce que je voulais.

43voto

Mark L Points 1554

J'ai fini par utiliser mpg comme format intermédiaire et cela a fonctionné (NOTE c'est un exemple dangereux, -qscale 0 va ré-encoder la vidéo...)

ffmpeg -i 1.mp4 -qscale 0 1.mpg
ffmpeg -i 2.mp4 -qscale 0 2.mpg
cat 1.mpg 2.mpg | ffmpeg -f mpeg -i - -qscale 0 -vcodec mpeg4 output.mp4

9 votes

A partir de ce commentaire, -sameq a été supprimé. Utilisez -qscale 0 à la place.

0 votes

Cela a fonctionné pour moi avec =-sameq=. J'ai utilisé =output.avi= au lieu de =output.mp4= car ce dernier donne un mauvais ratio d'aspect.

9 votes

-sameq ne signifie pas "même qualité". et a été retiré de ffmpeg comme mentionné par @XavierHo.

5voto

Reid Points 2082

Voici un script que j'ai réalisé pour concaténer plusieurs mp4 de GoPro en un mp4 720p. J'espère que ça pourra vous aider.

#!/bin/sh
cmd="( "
for i; do
    cmd="${cmd}ffmpeg -i $i -ab 256000 -vb 10000000 -mbd rd -trellis 2 -cmp 2 -subcmp 2 -g 100 -f mpeg -; "
done
cmd="${cmd} ) | ffmpeg -i - -vb 10000000 -ab 256000 -s 1280x720 -y out-`date +%F-%H%M.%S`.mp4"
echo "${cmd}"
eval ${cmd}

2 votes

Ce n'est PAS une concaténation. Ce code ne concatène pas les entrées, il les ré-encode. Il prend n'importe quel fichier vidéo arbitraire et le transforme en un bitrate audio et vidéo commun (indépendamment du bitrate ou de la taille d'image d'origine des fichiers sources). L'o/p voulait joindre deux fichiers en utilisant la copie de flux, pas les ré-encoder, donc cela ne répond pas à la question posée.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X