44 votes

Ffmpeg joindre deux fichiers mp4 avec ffmpeg en ligne de commande

Je peux joindre avec succès plusieurs fichiers en utilisant la commande suivante :

ffmpeg -f concat -i input.txt -codec copy output.mp4

Le seul problème avec cette commande est que vous devez lire les chemins d'accès aux fichiers à partir du fichier texte appelé input.txt avec le contenu suivant :

file 'C:\Users\fabio\Downloads\Super\Sharks\01.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\02.mp4'
file 'C:\Users\fabio\Downloads\Super\Sharks\03.mp4'

Y a-t-il un moyen d'atteindre le même objectif sans avoir à lire les chemins d'accès aux fichiers à partir d'un fichier ? J'ai essayé ce qui suit sans succès :

ffmpeg -f concat -i file "C:\a\b\01.mp4" file "C:\a\b\02.mp4" -codec copy output.mp4
ffmpeg -f concat -i "C:\a\b\01.mp4" "C:\a\b\02.mp4" -codec copy output.mp4

Dois-je utiliser une commande différente ?

54voto

apocalysque Points 646

Mise à jour 2019 :

Comme mentionné dans les commentaires, Stack Overflow a une excellente description des options disponibles pour la concaténation, ainsi qu'une discussion sur la méthode à utiliser en fonction des types de fichiers que vous utilisez :

Comment concaténer deux fichiers MP4 en utilisant FFmpeg ?

Réponse originale de 2016 :

Vous devriez être en mesure d'utiliser la méthode du protocole de concaténation pour combiner les fichiers :

ffmpeg -i "concat:input1.mp4|input2.mp4|input3.mp4" -c copy output.mp4

De plus, le manuel FFmpeg explique une méthode spécifique pour les fichiers MP4, afin de les concaténer de manière lossless, mais cela nécessite de créer des fichiers temporaires (ou des tuyaux nommés) :

ffmpeg -i input1.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate1.ts
ffmpeg -i input2.mp4 -c copy -bsf:v h264_mp4toannexb -f mpegts intermediate2.ts
ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" -c copy -bsf:a aac_adtstoasc output.mp4

10voto

Qwertiy Points 256

Vous pouvez remplacer le fichier par une liste en affichant la liste sur stdout et en lisant la liste depuis stdin par ffmpeg :

(echo file 'a.mp4' & echo file 'b.mp4') | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy "result.mp4"

2voto

Joe Points 71

Non, il semble qu'il n'y ait pas de moyen d'utiliser le démultiplexeur de concaténation ffmpeg sur une seule ligne de commande sans quelques astuces. Vous devez créer le fichier texte d'entrée avec la liste des fichiers. J'ai trouvé cela bizarre moi-même, peut-être que quelqu'un ajoutera cela à FFMpeg ultérieurement.

La réponse acceptée à cette question utilise le protocole de concaténation, pas le démultiplexeur de concaténation comme l'a demandé l'OP.

2voto

pureocean Points 21

Sans fichier texte externe, une commande en une ligne pour fusionner tous les fichiers MP4 dans un dossier :

dans CMD (l'invite de commandes) :

(FOR /R %A IN (*.mp4) DO @ECHO file '%A') | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy "Videos_Merged.mp4"

dans un fichier BAT :

(FOR /R %%A IN (*.mp4) DO @ECHO file '%%A') | ffmpeg -protocol_whitelist file,pipe -f concat -safe 0 -i pipe: -vcodec copy -acodec copy "Videos_Merged.mp4"

P.S. : la commande CHCP 65001 est nécessaire si le répertoire contient des caractères unicode.

(Ce code est basé sur la commande en une ligne de Qwertiy. Je suis à nouveau reconnaissant à Qwertiy pour les informations dans sa réponse. J'ai donc corrigé le code.

1voto

Richard Betel Points 41

Vous pourriez toujours le faire dans un script sans changer la commande. Quelque chose comme :

echo "file fname1" >$$.tmp    #single redirect creates or truncates file
echo "file fname2" >>$$.tmp   # double redirect appends
echo "file fname3" >>$$.tmp   # do as many as you want.

ffmpeg -f concat -i $$.tmp -codec copy output.mp4

rm $$.tmp  # just to clean up the temp file. 
           # For debugging, I usually leave this out.

Le $$ se développe en l'identifiant du processus du shell exécutant la commande, donc le nom de fichier sera différent à chaque fois que vous l'exécutez. donc vous pourriez utiliser $$.txt si vous préférez. Ou autre chose...

De plus, vous pouvez utiliser des fichiers ici pour ajouter une série de données au fichier :

cat <$$.tmp
file fname1
file fname2
file fname3
EOF

La substitution de variable bash fonctionne, donc vous pouvez déterminer de manière programmée le contenu du fichier, il n'a pas à être fixe. J'inclus ce genre de chose dans des boucles for tout le temps. Enfin, la redirection fonctionne de la même manière que ci-dessus, donc >$$.tmp tronque puis écrit, >>$$.tmp ajoute.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X