Comment fusionner plusieurs vidéos (plus de deux) sur Ubuntu?

39

Je souhaite fusionner des vidéos en lot de vingt (20). J'utilise une machine Linux. Les vidéos sont au format MP4 et de qualité moyenne. Certains ont même le flux audio manquant. Jusqu'ici j'ai essayéffmpeg , mencoder, cvlc/vlcet MP4Box. Pour ce faire, je souhaite écrire un script en ligne de commande, car je suis en train de traiter par lots.

Le problème principal est que certaines des solutions que j'ai essayées fonctionnent bien pour deux vidéos, certaines pour les vidéos avec flux audio et d'autres encore pour d'autres sous-ensembles de mon ensemble de vidéos. Cependant, je n'ai pas été en mesure de trouver une solution complète pour cette tâche.

Dhruv Singal
la source
2
S'il vous plaît, ne posez pas la même question dans plusieurs sites SE: superuser.com/questions/928548/…
Maythux
Pourriez-vous publier spécifiquement ce que vous avez essayé jusqu'à présent?
Ohaal
1
@ ohaal J'ai essayé d'utiliser diverses méthodes de concaténation ffmpeg, notamment les filtres et les protocoles de fichiers. J'ai aussi essayé d'utiliser la concatfonctionnalité de cvlc/vlc. J'ai aussi essayé la concatfonctionnalité de mencoder. Tous ont fonctionné partiellement. Cela m'a finalement aidé à résoudre le problème.
Dhruv Singal
Oui, vous avez déjà mentionné les outils. Ce que je voulais dire, c'était les commandes que vous avez exécutées. En outre, il serait bon que vous puissiez inclure la commande qui a fini par la résoudre pour vous (dans votre réponse), pour les futurs visiteurs.
Ohaal
Aah, je vois ce que tu veux dire. Malheureusement, je ne peux pas lister les commandes à cause du nombre important. La commande qui a résolu mon problème était celle-cimelt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264
Dhruv Singal le

Réponses:

41

J'utilise mkvmergepour joindre plusieurs fichiers MP4 en un seul:

mkvmerge -o outfile.mkv infile_01.mp4 \+ infile_02.mp4 \+ infile_03.mp4
Szabolcs Spindler
la source
3
Il est préférable d’utiliser l’extension .mkvpour le fichier de sortie, car c’est un conteneur Matroska, quelle que soit l’extension que vous donnez.
haridsv
Voici comment installer mkvmerge: tipsonubuntu.com
Morgoth le
Seule cette commande mkvmerge fonctionne. Tous les fichiers ffmpeg échouent avec l’audio décalé au moins.
42n4 le
25

Vous pouvez le faire en utilisant ffmpeg:

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

référence et plus d'infos

Maythux
la source
2
J'ai essayé de faire ça. Le problème avec ceci est que cela ne donne pas une sortie correcte. 1. Les pistes audio sont confuses. 2. La piste vidéo est perturbée.
Dhruv Singal
Je l'ai utilisé plus d'un échantillon, le résultat est de haute qualité, peut-être que la qualité de votre source vidéo pose problème?
Maythux
Vous avez probablement raison. Cela a résolu le problème: askubuntu.com/a/637179/420614
Dhruv Singal
2
N'utilisez pas le protocole concat pour concaténer MP4. Cela ne fonctionne qu'avec certains formats que la plupart des utilisateurs ne rencontrent pas. Utilisez plutôt un filtre démultiplexeur ou un filtre concat .
llogan
J'ai essayé ffmpeg avec 2 fichiers mp4 de 30min chacun. J'ai un fichier de sortie d'une longueur de 7 heures.
Guus
7

Cela a résolu le problème: https://stackoverflow.com/a/22324018/5014767

melt est un excellent utilitaire en ligne de commande pour cela. Voici la page

Editer des commentaires: La commande qui a résolu mon problème était ceci melt {input-sequence} -consumer avformat:{output-name} acodec=libmp3lame vcodec=libx264

Dhruv Singal
la source
4

J'ai écrit un petit script shell concaténant des MP4 sans transcodage à l'aide de ffmpeg.

for f in $(ls *.MP4); do
    ffmpeg -i $f -c copy -bsf:v h264_mp4toannexb -f mpegts $f.ts
done

CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")

ffmpeg -i "concat:$CONCAT" -c copy -bsf:a aac_adtstoasc output.mp4

rm *.ts

Cela crée des fichiers intermédiaires dans un conteneur MPEG, puis les concatène dans un MP4.

RawwrBag
la source
Il est important de noter que ce script échouera si l'un des noms de fichiers contient des espaces ou, dans certains cas, des caractères spéciaux. Pour la boucle, il est nettement préférable d'utiliser juste for f in *.MP4sans utiliser ls. (Vous devriez toujours éviter d'utiliser des lsscripts pour plusieurs raisons importantes; il existe de meilleures options.) Utilisez également des guillemets pour les variables, sauf si vous êtes certain qu'il n'y a pas d'espaces ou d'autres caractères spéciaux, donc "${f}"(ou tout simplement "$f") au lieu de non mis entre guillemets $f.
Paddy Landau
CONCAT=$(echo $(ls *.ts) | sed -e "s/ /|/g")ne fonctionne pas bien avec les noms de fichiers 1, 2, 3 ... 10 ... 20. Il finit par les analyser comme 1, 10 ... 2, 20 ... etc. Je suggère que CONCAT=$(echo $(ls -v *.ts) | sed -e "s/ /|/g")cela assurera l'ordre .
tisaconundrum
2

Créez un fichier fichier.txt avec tous les fichiers à concaténer sous la forme suivante (les lignes commençant par # sont ignorées):

# this is a comment
file 'file1.mp4'
file '/path/to/file2.mp4'
file 'file3.mp4'

Notez qu'il peut s'agir de chemins relatifs ou absolus. Ensuite, vous pouvez diffuser en streaming ou recoder vos fichiers:

ffmpeg -f concat -safe 0 -i files.txt -c copy output.mp4
ShaDeRzz
la source
0

Mon script, purement dans bashet ffmpeg. Re-code les fichiers donnés sur une ligne de commande en un seul.

Nécessite que les fichiers aient la même résolution. Accepte différentes rotations de métadonnées, ce qui ffmpeg concat:n'est pas le cas.

rm ffmpeg-concat-output.mkv

FILE_COUNT=$#
INPUTS=""
FILTER=""
INDEX=0
for FNAME in $@; do
    echo "Processing ${FNAME}"
    INPUTS="${INPUTS} -i $FNAME"

    if [ -z "${FILTER}" ]; then
        FILTER="[$INDEX:v:0] [$INDEX:a:0]"
    else
        FILTER="${FILTER} [$INDEX:v:0] [$INDEX:a:0]"
    fi
    let INDEX+=1
done

COMMAND="ffmpeg ${INPUTS} \
    -filter_complex '${FILTER} \
        concat=n=${INDEX}:v=1:a=1 [v] [a]' \
    -map '[v]' -map '[a]' \
    ffmpeg-concat-output.mkv"

#   -af 'volume=15dB' # won't work with -filter_complex

bash -c "${COMMAND}"
Victor Sergienko
la source
0

J'ai créé un script Python qui, à l'aide de moviepy , peut également concaténer des sous-segments (utile si vous souhaitez par exemple supprimer certaines parties d'une vidéo).

Utilisez-le avec:

vcat -i inputfile1,inputfile2[start-end],... -o <outputfile>
Antonello
la source
-1

En plus de la réponse de Maythux, de :

Quelques conteneurs multimédia (MPEG-1, MPEG-2 PS, DV) permettent de concaténer une vidéo en ne faisant que concaténer les fichiers qui les contiennent.

Par exemple, les vidéos à concaténer utilisent l'un des conteneurs vidéo susmentionnés (auquel j'ajouterai MPEG-4 Part 14 pour une expérience personnelle), vous pouvez simplement:

cat video1.ext video2.ext video3.ext > video4.ext
kos
la source
1
J'ai essayé cela mais il ne retourne que la première vidéo en sortie. J'ai lu quelque part que cela ne fonctionnait pas, même si je ne me souvenais pas de la raison derrière tout cela.
Dhruv Singal
@DhruvSingal Oui, je peux le confirmer. J'ai déjà essayé cette vidéo sur deux vidéos MP4 avec exactement le même encodage vidéo / audio et, en tant que vous, je ne pouvais parcourir que la première vidéo. Ce qui semble raisonnable, mais je suis presque sûr d'avoir déjà fait cela auparavant avec quelques vidéos MP4. Peut-être que la mémoire ne sert pas bien ici, ou il y a d'autres exigences pour que cela fonctionne. Je veux faire une recherche là-dessus car je suis intéressé aussi, si je trouve quelque chose, je mettrai à jour la réponse et vous laisserai un commentaire
kos
Nous devons en quelque sorte modifier les métadonnées au début de la première vidéo pour englober toute la durée du film combiné, entre autres choses, probablement. Seuls quelques fichiers MPEG4 me permettent de voir les métadonnées.
Ken Mollerup