Concaténation interactive de fichiers vidéo

9

Comment concaténer (joindre) plusieurs fichiers vidéo MP4 en un seul fichier de manière interactive?

Il existe de nombreux programmes qui le font pour deux fichiers à partir de la ligne de commande. Par exemple:

  • ffmpeg
  • avconv
  • MP4Box

Mais nous avons souvent besoin d'une solution pour le faire de manière interactive.

Slyx
la source
1
Pouvez-vous décrire ce que vous entendez par interactif?
slm
@slm Je veux dire un programme qui demande à l'utilisateur de saisir les fichiers d'entrée un par un, puis le fichier de sortie à créer. puis effectuez la concaténation.
Slyx
Je n'ai jamais vu un programme qui fait cela directement, c'est comme vous l'avez conçu, un script shell qui recueille les informations puis assemble la ligne de commande. Cherchez-vous des améliorations par rapport à ce que vous avez?
slm
@slm j'ai posté cela car c'est un besoin fréquent d'utilisateurs multimédias comme moi. J'espère donc que cela aide quelqu'un d'autre. Bien sûr, toutes les améliorations sont les bienvenues!
Slyx
1
@gold J'ai mis une modification dans la file d'attente. ffmpegn'est en aucun cas mort ou obsolète: le dernier gitcommit à masterdate d'il y a 15 minutes et je l'utilise quotidiennement.
Anko

Réponses:

8

Je n'ai pas essayé cette méthode récemment, mais je ne vois pas pourquoi cela ne fonctionnerait toujours pas. Je pense que vous pouvez simplement cat .mp4créer des fichiers ensemble si vous ne voulez rien faire d'autre que de les concaténer.

1. Utilisation de chat

$ cat file1.mp4 file2.mp4 > file3.mp4
$ ffmpeg -i file3.mp4 -qscale:v 2 output.avi

J'utilise toujours ffmpegtout le temps, il peut aussi concaténer des fichiers.

2. Utilisation de ffmpeg

  1. Faire une liste de fichiers à concaténer

    $ cat inputs.txt 
    file sample_mpeg4.mp4
    file sample_mpeg4.mp4
  2. enchaîner

    $ ffmpeg -f concat -i inputs.txt -c copy out.mp4
    
    $ ll |grep -E "sample|out"
    -rw-rw-r--. 1 saml saml 491860 Feb 19 23:36 out.mp4
    -rw-r--r--. 1 saml saml 245779 Feb 19 23:32 sample_mpeg4.mp4

    D'autres méthodes sont décrites dans le wiki FFmpeg: Comment concaténer (joindre, fusionner) des fichiers multimédias .

    REMARQUE: Ubuntu ne semble pas prendre en charge le concatformat. Vous devez utiliser le protocole concat. De plus, il dispose d'options de codec par flux. Ainsi, l'utilisation des résultats du protocole concat comme suit:

    $ ffmpeg -i input1.mp4 -vcodec copy -acodec copy \
         -vbsf h264_mp4toannexb -f mpegts intermediate1.ts
    
    $ ffmpeg -i input2.mp4 -vcodec copy -acodec copy \
         -vbsf h264_mp4toannexb -f mpegts intermediate2.ts
    
    $ ffmpeg -i "concat:intermediate1.ts|intermediate2.ts" \
         -vcodec copy -acodec copy -absf aac_adtstoasc output.mp4

    Les options Ubuntu ffmpeg sont documentées ici .

slm
la source
Intéressant ! Je ne savais pas que catc'était suffisant pour les fichiers MP4! la solution n'est cependant pas interactive!
Slyx
@Slyx - oui, c'est pourquoi j'ai demandé ce que vous entendiez par interactif. Laissez-moi voir ce que vous en avez dit et voir ce que je peux ajouter à cela. Vérifiez que cela catfonctionne bien. La dernière fois que je l'ai utilisé, c'était avec des .mpgfichiers et il a déf. travaillé avec ceux-ci.
slm
2
Je l'ai vérifié. L'utilisation catn'est pas une solution valable. Le fichier généré par catdeux fichiers ne montre que le contenu du premier fichier d'entrée!
Slyx
@Slyx - cat fonctionne mais les horodatages ne sont pas corrects, donc lorsque vous essayez de le lire, le lecteur vidéo devient confus par le saut d'horodatage de 00 à la fin, puis de nouveau à 00. Si vous deviez transcoder la vidéo cette serait fixé dans le cadre de ce processus. Il existe également des moyens de régénérer les horodatages.
slm
C'est ce que je veux dire aussi. Les deux contenus sont là mais le lecteur multimédia détecte juste le premier.
Slyx
4

J'utilise MP4Box comme base de travail.
Le script que je suggère lit tous les fichiers un par un, en vérifiant chacun (qu'il s'agisse d'un fichier ordinaire), demande à l'utilisateur le nom du fichier d'entrée à créer.

#!/bin/bash
printf "###  Concatenate Media files ###\n"
fInputCount=0
# Reading input files
IFS=''
while (true)
do
    let currentNumber=$fInputCount+1 
    printf "File n°%s (\"ok\" to finish): " $currentNumber
    read inputFile
    [ "$inputFile" == "ok" ] && break
    [ ! -e "$inputFile" ] || [ ! -f "$inputFile" ] && printf "\"%s\" : Invalid filename. Skipped !\n" "$inputFile" && continue
    ((fInputCount++))
    inputFileList[$fInputCount]=$inputFile
    printf "\"%s\" : Added to queue !\n" "$inputFile"
done
[ "$fInputCount" == "0" ] || [ "$fInputCount" == "1" ] && echo "No enough input data. BYE ! " && exit
# Listing the input file list 
for ((i=1;i<=$fInputCount;i++))
do
    printf "%2d : %s\n" $i ${inputFileList[$i]}
done
# Reading the output filename
while (true)
do
    printf "Output file without extention (\"none\" to dismiss) : "
    read outputRead
    [ "$outputRead" == "none" ] && echo "Dismissed. BYE ! " && exit
    [ "$outputRead" == "" ] && echo "Try again ! " && continue
    [ -e "$outputRead" ] && echo "\"$outputRead\" exists. Try again !" && continue
    outputFile=$outputRead.mp4
    echo "Output to \"$outputFile\". Go !" && break
done
# Creating a random temporary filename
tmpOutFile="/tmp/concatMedia"`date +"%s%N"| sha1sum | awk '{print $1}'`".mp4"
# Joining the two first input files
MP4Box -cat "${inputFileList[1]}" -cat "${inputFileList[2]}" $tmpOutFile
# Adding all other files
for ((i=3;i<=$fInputCount;i++))
do
    tmpIntermediateFile=$tmpOutFile
    tmpOutFile="/tmp/concatMedia"`date +"%s%N"| sha1sum | awk '{print $1}'`".mp4"
    MP4Box -cat $tmpIntermediateFile -cat "${inputFileList[$i]}" $tmpOutFile
    rm $tmpIntermediateFile
done
mv $tmpOutFile "$outputFile"
# Finished
echo "\"$outputFile\" Saved !"
Slyx
la source