Comment concaténer des clips d'une même vidéo avec ffmpeg

15

J'ai une longue vidéo avec différentes scènes. Je souhaite extraire et concaténer 2 scènes de la vidéo (qui ne démarrent pas sur une image I) à l'aide de ffmpeg 2.1.4.

Pour l'argument, disons que je veux 5 secondes de 01h00 et 02h00.

Je peux le faire:

ffmpeg -ss 01:00 -i in.mkv -ss 02:00 -i in.mkv -filter_complex "
  [0:v]select='lt(t,5)'[v0];
  [0:a]aselect='lt(t,5)'[a0];
  [v0][a0][1:v][1:a]concat=n=2:v=1:a=1
" -c:a libvorbis -t 10 out.mkv

Cela me donne le film que je veux, mais select force en fait ffmpeg à décoder tout le reste du film. Alors, comment puis-je lui dire de tronquer le premier film au lieu de le décoder?

Je préférerais le faire avec un filtre complexe ffmpeg, si possible. Je sais que je peux simplement utiliser -tpour recoder des films séparés en premier, mais l'étape d'encodage supplémentaire est très lente dans mon cas et perd également une bonne quantité de qualité pour cette vidéo.

Je n'arrive pas à trouver un filtre qui tronque la longueur d'une vapeur. Y a-t-il des nœuds de filtre qui correspondent aux paramètres -tou -ss?

frotté
la source

Réponses:

16

filtre concat

Cette méthode est préférable si vous devez effectuer un filtrage supplémentaire:

Utilisez les trim, atrim, setpts, asetpts, et les concatfiltres:

ffmpeg -i input -filter_complex \
"[0:v]trim=60:65,setpts=PTS-STARTPTS[v0]; \
 [0:a]atrim=60:65,asetpts=PTS-STARTPTS[a0]; \
 [0:v]trim=120:125,setpts=PTS-STARTPTS[v1];
 [0:a]atrim=120:125,asetpts=PTS-STARTPTS[a1]; \
 [v0][a0][v1][a1]concat=n=2:v=1:a=1[out]" \
-map "[out]" output.mkv
  • setptset asetptsempêchera une sortie saccadée en raison de problèmes d'horodatage de présentation.

  • Assurez-vous d'utiliser une version récente. Consultez la page de téléchargement FFmpeg pour les liens vers les versions pour Windows, OS X et Linux.


concat demuxer

Une autre méthode consiste à créer les segments individuellement et à les copier en flux au lieu de les réencoder (pour gagner du temps et de la qualité), et à les joindre avec le démultiplexeur concat .

$ ffmpeg -ss 60 -i input -t 5 -codec copy clip1.mkv
$ ffmpeg -ss 120 -i input -t 5 -codec copy clip2.mkv
$ echo "file 'clip1.mkv'" > concat.txt
$ echo "file 'clip2.mkv'" >> concat.txt
$ ffmpeg -f concat -i concat.txt -codec copy output.mkv
llogan
la source
2
Ah merci. c'est ce qui me manquait. Cependant, il faut beaucoup de temps pour arriver au décalage de temps que je spécifie, comme si tout décodait jusqu'à lui. De plus, une partie de la sortie manquait d'audio. Pour résoudre ce problème, j'ai spécifié plusieurs fois la même entrée avec -ss, puis j'utilise Trim pour tronquer la vidéo. Vous n'avez pas besoin de setpts dans ce cas, car ss met pts à 0. Cela semblait fonctionner et n'avait pas de pauses aléatoires étranges pendant l'encodage. En ce qui concerne la copie de flux, j'ai déjà essayé cela. Cela commence à l'image I précédente, vous obtenez donc une partie du film différente de celle que vous vouliez.
frotté
Veuillez répondre à ma question, elle est similaire à celle-ci. video.stackexchange.com/questions/18247/…
Eftekhari
Fait intéressant les -filter_complextravaux , mais les concatfichiers ne pas - à savoir le 1er aspect vidéo , mais bien la qualité du 2ème est horrible. Remarque, j'ai copié ces commandes exactement pour les deux (à l'exception du fichier d'entrée).
bobmarksie
7

Cela devrait fonctionner plus rapidement ...

ffmpeg -ss 1:00 -t 5 -i in.mkv -ss 2:00 -t 5 -i in.mkv \
  -filter_complex "[0][1]concat=n=2:v=1:a=1" \ 
  out.mkv

Il n'est pas nécessaire de spécifier -t sur la sortie. Il n'est pas nécessaire de diviser l'audio et la vidéo avant la concaténation.

William Frantz
la source
1
Cela utilise le filtre concat qui nécessitera un ré-encodage. Cela peut être souhaité ou non par l'utilisateur.
llogan