FFmpeg scinder la vidéo et fusionner

8

Je suis en train d'utiliser FFmpeg à la vidéo divisée en fonction de certains start_timeet les end_timeentrées, et remplacer ceux avec d' autres fichiers vidéo. Par exemple, pour l'entrée, 10 15je devrai remplacer EXACT secondes 10 to 15par une autre vidéo.

D'ACCORD. Ce qui me vient à l'esprit est le suivant:

  1. Divisez d'abord la vidéo (dans ce cas, 0-10, 10-15 et 15)
  2. Remplacez le 10-15 par l'autre vidéo
  3. Fusionner toutes les sous-vidéos

Première question: est-ce la solution la meilleure et la plus rapide? Avons-nous une commande plus simple ou d'autres outils pour remplacer une période de temps spécifique en vidéo par une autre vidéo?

Deuxième question: en supposant que FFmpeg est la solution viable, lorsque j'utilise simplement la commande ffmpeg -I input.video -ss 10 -t 5 -c copy output.mp4, mon code de traitement vidéo ne peut pas lire et traiter le fichier. J'ai utilisé l' mediainfooutil pour comparer les deux fichiers et j'ai remarqué des différences dans les tailles d'en-tête alors que toutes les choses liées au codec vidéo étaient les mêmes. J'ai remarqué que la taille de l'en-tête est différente, ce qui est apparemment à l'origine du problème. Existe-t-il des moyens de forcer la même taille d'en-tête (à part les codecs)?

MISE À JOUR: Voici le .mp4fichier d' origine qui fonctionne bien dans l'émulateur.

Ariana
la source
Nous devons d'abord régler le problème que vous mentionnez dans votre deuxième question. Veuillez montrer la commande exacte que vous utilisez et la sortie de ligne de commande complète et non coupée que vous obtenez de ffmpeg. Indiquez également les erreurs réelles que vous obtenez lors de la lecture du fichier - il serait bon de savoir exactement quel est votre "code de traitement".
slhck
@slhck le code de traitement vidéo est une énorme base de code. Je ne peux pas le partager. C'est juste que, pour certaines raisons, le fichier d'origine est lu, mais pas le fichier régénéré. Je peux cependant partager le .mp4fichier d' origine si besoin.
Ariana
J'ai utilisé l'outil mediainfo pour comparer les deux fichiers et remarquer des différences dans les tailles d'en-tête et tout ça
Ariana
Avoir l'original aiderait, mais nous ne pourrons pas comprendre pourquoi il ne peut pas être lu, je le crains, s'il s'agit d'un code interne.
slhck
@slhck J'ai téléchargé le fichier. Ma question est mise à jour
Ariana

Réponses:

9

Utilisation de trimet concat- fichiers source avec différents codecs

Pour cela, assurez-vous que vos fichiers individuels ont la même résolution, et idéalement le même sous-échantillonnage de fréquence d'images et de chrominance, etc. Cela évitera des erreurs ou des problèmes pendant la concaténation.

Vous pouvez tout faire en une seule fois sans diviser le fichier, en utilisant les filtres trimet concat:

ffmpeg -i edv_g24.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[v0][v1][v2]concat=n=3:v=1:a=0[out]" \
-map "[out]" output.mp4

Ici, trimest utilisé pour spécifier les parties individuelles des flux vidéo d'entrée ( 0:v, 1:v) que vous souhaitez ultérieurement concaténer. Ces pièces sont nommées v0par v2. (Le setptsfiltre réinitialise les horodatages de ces parties individuelles à 0, ce qui est requis pour la concaténation). Plus tard, nous concaténons les trois parties.

Si vous souhaitez découper à partir d'un certain horodatage jusqu'à la fin, utilisez trim=start=15au lieu de spécifier la plage.

Si vos fichiers ont du son, vous devez couper ces flux séparément:

ffmpeg -i edv_g24_2.mp4 -i short-video.mp4 -filter_complex "\
[0:v]trim=0:10,setpts=PTS-STARTPTS[v0]; \
[0:a]atrim=0:10,asetpts=PTS-STARTPTS[a0]; \
[1:v]trim=0:5,setpts=PTS-STARTPTS[v1]; \
[1:a]atrim=0:5,asetpts=PTS-STARTPTS[v1]; \
[0:v]trim=15:30,setpts=PTS-STARTPTS[v2]; \
[0:a]atrim=15:30,asetpts=PTS-STARTPTS[a2]; \
[v0][a0][v1][a1][v2][a2]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mp4

Notez que la vidéo et l'audio seront ré-encodés dans ce cas - assurez-vous de spécifier des cibles de qualité de sortie appropriées (par exemple -crfpour x264, x265 ou libvpx-vp9). Vous pouvez en savoir plus à ce sujet sur le Wiki FFmpeg, par exemple pour VP9 ou H.264 .

Utilisation de segments individuels

Si vous souhaitez diviser les clips et les réassembler ultérieurement:

ffmpeg -i edv_g24.mp4 -ss 0 -to 10 -c copy part1.mp4
ffmpeg -i edv_g24.mp4 -ss 10 -to 15 -c copy part2.mp4
ffmpeg -i edv_g24.mp4 -ss 15 -c copy part3.mp4

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][1:v][2:v]concat=n=3:v=1:a=0[outv]" \
-map "[outv]" -t 30 output.mp4

Si les fichiers ont du son, utilisez la même approche que ci-dessus:

ffmpeg -i part1.mp4 -i short-video.mp4 -i part3.mp4 -filter_complex \
"[0:v][0:a][1:v][1:a][2:v][2:a]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" -t 30 output.mp4

Cela réencodera à nouveau le flux vidéo. C'est un peu plus simple, mais sinon, cela devrait être équivalent à la méthode ci-dessus.

Utilisation de concatdemuxer

Vous pouvez en principe également essayer de concaténer les flux binaires sans les recoder, en utilisant le démultiplexeur concat. Créez un fichier appelé concat.txtet ajoutez les entrées suivantes (correspondant aux clips vidéo créés ci-dessus):

file 'part1.mp4'
file 'short-video.mp4'
file 'part3.mp4'

Ensuite, concaténez ces fichiers individuels:

ffmpeg -f concat -i concat.txt -c copy output.avi

Cela nécessite cependant que vos clips aient le même codec, la même résolution, la même fréquence d'images, etc. - donc cela ne fonctionne pas avec toutes sortes de sources hétérogènes.

Utiliser le concatprotocole

Le type de concaténation de niveau fichier ci-dessus peut également être réalisé en utilisant le concatprotocole, avec le même type de contraintes que ci-dessus (même codec, résolution, etc.):

ffmpeg -i "concat:part1.avi|part2.avi|part3.avi" -c copy output.mp4

Pour plus d'informations sur la concaténation, lisez la page Wiki FFmpeg correspondante .

slhck
la source
Cela semble très complet! Merci. Je vais les essayer!
Ariana
Idk pourquoi l'utilisation de la concatméthode génère une erreur:[concat @ 00000000025c2560] Line 1: unknown keyword 'part1.mp4 \\ text.txt: Invalid data found when processing input
Ariana
Pour "utiliser des segments individuels", je vois un arrêt et une petite coupure de la sortie. Existe-t-il des moyens de résoudre ce problème?
Ariana
La méthode 1 fonctionne parfaitement. Une chose: comment spécifier "jusqu'à la fin" sans indiquer un nombre spécifique (au lieu de 30 s)
Ariana
1
Désolé, j'ai fait une erreur. Pour le concatdémultiplexeur, la syntaxe était différente. Fixé maintenant. Pour aller jusqu'à la fin, utilisez trim=start=15, consultez la documentation du filtre de trim: ffmpeg.org/ffmpeg-filters.html#trim - comme pour les problèmes de timing, cela dépend vraiment de votre matériel source. Je n'ai pas eu de problèmes de concaténation avec le clip que vous avez téléchargé.
slhck