Comment couper les pièces vidéo indésirables et rejoindre les autres en une seule vidéo en utilisant FFmpeg?

J'ai lu sur la coupe et l'épissage en utilisant concat mais cela ne me suffit pas.

Je voudrais couper les pièces vidéo marquées et rejoindre un seul fichier vidéo sans recodage. Est-il possible de couper et de fusionner (en mémoire) d'une seule fois?

Il ne devrait pas y avoir de limite théorique sur le nombre de pièces vidéo à couper ou à se joindre. L'audio doit être synchronisé.

Vidéo: H.264 + AAC

Modifier:

À partir des réponses, j'ai appris que le recodage vidéo est encore nécessaire.

J'aimerais préciser que la réduction des clips vidéo du milieu d'un fichier vidéo pourrait se faire dans plusieurs étapes. Je pensais que le traitement de la vidéo en une seule fois serait performant en enregistrant certaines activités d'E / S. Cependant, ce n'est pas un objectif en soi.

Votre question, si j'ai bien compris, comporte quatre parties principales:

  • Comment couper un segment temporel d'un film
  • Comment fusionner plusieurs segments ensemble
  • Comment faire ce qui précède sans transcoder le film, donc ne pas perdre de qualité
  • Comment faire ce qui précède en termes de vitesse

Couper un segment de temps

Vous pouvez couper un segment en sautant à son point de départ avec l'option -ss , puis en définissant la durée du segment avec -t ou en définissant le point d'extrémité avec -to :

 # skip 30 seconds, then copy the next 60 seconds ffmpeg -ss 30 -t 60 full-movie.mp4 segment.mp4 

Dans la documentation ffmpeg, consultez la section 5.4 Principales options concernant la différence entre placer les options -ss et -t avant le fichier d'entrée ou avant le fichier de sortie. Une fois que vous avez expérimenté cela, vous pourriez trouver cette différence comme pertinente dans votre cas.

Remarque importante: l'exemple ci-dessus provoque la transcodage de la vidéo. Nous discuterons ci-dessous de la possibilité de procéder sans transcodage.

Fusion de plusieurs segments

Il existe trois méthodes principales pour effectuer une fusion de films, deux d'entre eux sont mieux expliqués dans cet article de ffmpeg wiki , et le troisième est le concat demuxer . Si tous vos segments sont identiques en termes de spécification de codage / format de conteneur / v, vous trouverez probablement la méthode la plus simple pour être le protocole concat: :

 # merge the segments ffmpeg -i "concat:seg1.mp4|seg2.mp4|seg3.mp4" final.mp4 

Il est important de noter que cette fusion, comme la découpe, transcode le film, nous avons ici une transcodage d'une transcodé, ce qui pourrait dégrader la qualité de la vidéo, alors nous voulons vraiment éviter ce transcodage autant que possible.

Couper et fusionner sans transcodage

La raison pour laquelle les exemples dans les sections précédentes nécessitent un transcodage est dû au fait que chaque fichier et chaque segment résultant est un film autonome qui a été chargé de fournir toutes les choses que vous attendez lorsque vous ouvrez un film complet, comme la durée du film et d'autres Métadonnées. Mais hey, vous ne cherchez pas à jouer ces films indépendants, vous voulez que ces segments deviennent une partie d'un flux vidéo plus grand. Donc, au lieu de servir ffmpeg avec des films encadrés, vous devriez mieux regrouper – re-mux – les fichiers d'entrée dans un conteneur de diffusion en temps réel, en oubliant les choses d'en-tête dont vous n'avez vraiment besoin à ce stade. Dans le cas de H.264, le format de streaming mux s'appelle MPEG-TS, et voici comment vous re-mux votre flux sans le transcoder:

 # re-muxing the whole movie (see a better option in next example) ffmpeg -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb full-movies-as-ts.ts 

Eh bien, puisque vous l'êtes déjà, vous pourriez utiliser cette opportunité pour réduire le segment dont vous avez besoin:

 # skip 30 seconds and re-mux a 60 seconds segment ffmpeg -ss 30 -t 60 -i full-movie.mp4 -c:v copy -c:a copy -bsf:v h264_mp4toannexb segment.ts 

Lorsque vous fusionnez les segments TS, vous pouvez également re-mux revenir à un conteneur mp4:

 # merge the segments and re-mux them as mp4 ffmpeg -i "concat:seg1.ts|seg2.ts|seg3.ts" -c:v copy -c:a copy -movflags empty_moov -flags global_header -bsf:v dump_extra edited-final.mp4 

Donc, maintenant, nous avons tout fait sans jamais transcoder le film, en conservant la qualité originale. Mais comme toujours, il y a une réserve …

CAVEAT : la coupe ne peut se faire que sur une limite de l'image clé. Explication: H.264 organise les images compressées en paquets, chacune commençant par une image complète mais compressée de la première image, suivie des deltas des trames suivantes, ce qui diminue le stockage requis pour chaque paquet. Pour notre but, chaque paquet est comme une fermeture à glissière scellée de tous les cadres pour cette durée – il est soit tout ou rien. Si vous voulez juste un morceau du paquet, vous devez le décompresser et le reculer, en d'autres termes – pour le transcoder. La méthode ci-dessus n'est donc pertinente que si vous avez une image clé dans chaque position où vous voulez couper le film. Par exemple, si vous avez une image clé toutes les 5 secondes, vous pouvez la découper toutes les 5 secondes.

Donc, maintenant, la question est de savoir si vous pouvez accepter les limitations sur les points de coupe, d'autant plus que vous n'avez probablement aucune idée où dans votre film, vous avez des images clés. Et c'est la raison pour laquelle j'ai suggéré ci-dessus de lire dans 5.4 Principales options sur la spécification -s et -t avant l'entrée ou avant la sortie. Si vous spécifiez avant l'entrée, ffmpeg trouvera une image clé à proximité pour effectuer votre demande, qui sera "plus ou moins" où vous souhaitez effectuer la coupe. Si vous ne vous dérangez pas de la précision de la coupe, alors, allez-y.

Mais si vous avez besoin de la coupe pour être à ce poste précis, alors vous n'avez pas le choix, vous devez décoder le film afin de repérer le cadre que vous recherchez. Eh bien, au moins, nous avons de bonnes nouvelles: au lieu de transcodage et de ré-transcodage, vous pouvez faire avec une seule transcode, ce qui améliore quelque peu la situation:

 # skip PRECISELY 30 seconds and transcode a 60 seconds TS segment ffmpeg -i full-movie.mp4 -ss 30 -t 60 -bsf:v h264_mp4toannexb segment.ts 

Étant donné que les segments résultants seront dans TS, aucun besoin d'autre transcode lors de la fusion des segments.

La vitesse

Dans l' article de ffmpeg wiki sur la fusion, il existe une explication sur la façon d'exécuter l'ensemble du processus à travers les tuyaux, ce qui élimine le besoin de fichiers intermédiaires et accélère l'ensemble du processus. NE PAS. Il vous faudra plus de temps . La raison pour laquelle tout cela dans la mémoire prend plus de temps n'est pas parce qu'il fonctionnera plus longtemps, mais parce que vous n'aurez pas de résultats intermédiaires tout en calculant comment faire l'ensemble, et vous vous retrouverez en train d'exécuter l'ensemble du processus à nouveau et encore. Donc, la théorie des pipes est bonne, mais dans votre cas, vous devriez commencer par travailler et perfectionner chaque étape. Vous constaterez que tout faire fonctionner et produire un résultat décent nécessitera un peu plus de réglage et de réglage. Une fois que vous maîtrisez l'ensemble du processus et que vous souhaitez effectuer des scripts pour l'édition automatisée de masse, vous pouvez revoir le concept de la tuyauterie.

J'espère que ce qui précède aide.