Montage vidéo en ligne de commande sous Linux (couper, joindre et prévisualiser)


32

J'ai des besoins d'édition assez simples - j'ai besoin de découper des vidéos, peut-être d'insérer des fichiers PNG entre eux, et de rejoindre ces vidéos (pas besoin de transitions, d'effets, etc.). Fondamentalement, pitiviferait ce que je veux - sauf que j'utilise des AVI 640x480 30 ips à partir d'un appareil photo, et dès que je mets plus de quelques minutes de ce type de matériel, pitivicommence à se figer sur l'aperçu et devient donc inutilisable.

J'ai donc commencé à chercher un outil de ligne de commande pour Linux; Je suppose que seuls ffmpeg( ligne de commande - Utilisation de ffmpeg pour couper la vidéo - Super User ) et mplayer( Sam - Édition du fichier vidéo avec mencoder sous linux ) sont à ce jour des candidats, mais je ne trouve pas d'exemples d'utilisation que j'ai en tête.

 

Fondamentalement, j'imagine qu'il existe un encodeur et des outils de lecture (comme ffmpegvs ffplay; ou mencodervs mplayer) - tels que, pour commencer, la séquence d'édition pourrait être spécifiée directement sur la ligne de commande, de préférence avec une résolution d'image - un pseudocode ressemblerait à:

videnctool -compose --file=vid1.avi --start=00:00:30:12 --end=00:01:45:00 --file=vid2.avi --start=00:05:00:00 --end=00:07:12:25 --file=mypicture.png --duration=00:00:02:00 --file=vid3.avi --start=00:02:00:00 --end=00:02:45:10 --output=editedvid.avi

... ou, il pourrait avoir un fichier texte "playlist", comme:

vid1.avi      00:00:30:12 00:01:45:00 
vid2.avi      00:05:00:00 00:07:12:25 
mypicture.png -           00:00:02:00
vid3.avi      00:02:00:00 00:02:45:10 

... donc on pourrait l'appeler avec

videnctool -compose --playlist=playlist.txt --output=editedvid.avi

L'idée ici serait que toutes les vidéos soient dans le même format - permettant à l'outil d'éviter le transcodage, et de faire juste une "copie brute" à la place (comme dans mencoderle codec de copie de : " -oac copy -ovc copy") - ou à défaut, l'audio / vidéo non compressé serait OK (même s'il consommerait un peu d'espace). Dans le cas de l'image fixe, l'outil utiliserait l'encodage défini par les fichiers vidéo.

 

Le fait est que je peux le voir jusqu'à présent mencoderet que je ffmpegpeux opérer sur des fichiers individuels; par exemple couper une seule section à partir d'un seul fichier, ou joindre des fichiers (a mencoderégalement Modifier les listes de décision (EDL) , qui peuvent être utilisées pour effectuer une découpe exacte du cadre - de sorte que vous pouvez définir plusieurs régions de découpe, mais elles sont à nouveau attribuées à un seul fichier ). Ce qui implique que je dois d'abord travailler sur la découpe de morceaux à partir de fichiers individuels (dont chacun exigerait son propre fichier temporaire sur le disque), puis les joindre dans un fichier vidéo final.

J'imagine alors qu'il existe un outil de lecture correspondant, qui peut lire le même fichier de format / playlist d'option de ligne de commande que l'outil de codage - sauf qu'il ne générera pas de fichier de sortie, mais lira à la place la vidéo; par exemple en pseudocode:

vidplaytool --playlist=playlist.txt --start=00:01:14 --end=00:03:13

... et, étant donné qu'il y a suffisamment de mémoire, il générerait un aperçu vidéo basse résolution dans la RAM, et le lireait dans une fenêtre, tout en offrant une interaction limitée (comme mplayerles raccourcis clavier pour la lecture, la pause, le rembobinage, la trame pas à pas) ). Bien sûr, j'imagine les heures de début et de fin pour faire référence à la liste de lecture entière et inclure tout fichier pouvant se retrouver dans cette région dans la liste de lecture.

Ainsi, le résultat final de tout cela serait: opération en ligne de commande; pas de fichiers temporaires lors de l'édition - et aussi pas de fichiers temporaires (ni de transcodage) lors du rendu de la sortie finale ... ce que je pense moi-même serait bien.

Donc, même si je pense que tout ce qui précède peut être un peu exagéré - existe-t-il quelque chose qui se rapprocherait du flux de travail décrit ci-dessus?


1
J'utilise également souvent mkvmerge lorsque j'ai besoin de séparer / joindre des vidéos.
Vi.

Merci pour cela, @Vi. - mkvmergeje n'en avais jamais entendu parler auparavant, je m'assurerai de le vérifier .. Santé!
sdaau

Réponses:



23

Ok, puisque je ne peux pas trouver grand-chose sur l' meltutilisation de la ligne de commande, voici quelques notes .. (et après cela, voir cette réponse Utiliser la substitution de processus pour tromper les programmes qui attendent des fichiers, avec des extensions spécifiques comme argument? - Unix & Linux Stack Exchange pour un script exemple via bash)

Pour commencer - il y a un paquet Ubuntu / Debian pour melt(j'ai Ubuntu 11.04 avec MLT melt 0.6.2); le lien donné par @Ielton est pour le wiki "Media Lovin 'Toolkit" (MLT), qui meltfait partie (mais aussi openshotet kdenlive). Voici le lien vers les fichiers texte de documentation de leur git: mltframework.org/mlt.git/tree - docs / ; notez que le wiki a une page sur BuildScripts .

Pour l'instant, le plus gros (seul) problème que j'ai avec cela, c'est que je ne trouve pas un moyen d'exporter une composition vidéo non compressée (soit sous forme d' pngimages, soit sous un format vidéo non compressé).

 

Tout d'abord, en ligne de commande, meltvous pouvez contrôler la lecture à travers des images; par exemple, pour "créer" un blanc long de 15 images et le visualiser avec le meltlecteur intégré, utilisez

melt -blank 15

Lorsque vous visualisez avec melt, vous obtiendrez également une information de ligne de commande stderrpour le lecteur intégré:

$ melt -blank 15 
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
|1=-10| |2= -5| |3= -2| |4= -1| |5=  0| |6=  1| |7=  2| |8=  5| |9= 10|
+-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
+---------------------------------------------------------------------+
|               H = back 1 minute,  L = forward 1 minute              |
|                 h = previous frame,  l = next frame                 |
|           g = start of clip, j = next clip, k = previous clip       |
|                0 = restart, q = quit, space = play                  |
+---------------------------------------------------------------------+
Current Position:         15

Une fois la meltlecture terminée, il ne se fermera pas - vous devez donc taper qpour le quitter.

Il convient de noter qu'il existe des soi-disant «producteurs» et «consommateurs» en melt. Si rien n'est spécifié, le "consommateur" par défaut est une fenêtre SDL (Simple DirectMedia Layer) lisant la vidéo; donc la commande ci-dessus est la même que:

melt -blank 15 -consumer sdl

Ainsi, si nous voulons enregistrer ce qui melts'affiche, nous devons changer le consommateur en quelque chose qui prendra en charge un format de fichier. Pour obtenir une liste de consommateurs:

$ melt -query "consumers"
---
consumers:
  - sdl
  - sdl_audio
  - sdl_preview
  - sdl_still
  - gtk2_preview
  - avformat
  - libdv
  - xml
  - decklink
  - null
...

Le libdvconsommateur sortira directement des données au format DV stdout, donc pour enregistrer la vidéo dans un .dvfichier que vous feriez:

melt -blank 15 -consumer libdv > test.dv

Notez que parmi les consommateurs répertoriés, le seul format que j'ai essayé, qui peut également être ouvert dans une autre application est libdv(j'ai utilisé vlccomme autre application); cependant, cela peut échouer pour un autre type de transcodage ( par exemple, si au lieu d'un blanc, j'essaie de convertir un extrait d'un .flvfichier, le fichier .dv résultant s'ouvre et joue vlc, mais est corrompu ).

 

Maintenant pour la partie édition ; essentiellement, vous pouvez spécifier une série de strophes nom de fichier / entrée / sortie directement sur la ligne de commande; dites que vous avez un fichier, video.avi- alors vous pourriez faire:

melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79

ou légèrement mieux formaté:

melt \ 
video.avi in=30 out=79 \ 
-blank 15 \
video.avi in=30 out=79

Cela signifie que video.avide sa trame 30 à sa trame 79 sera joué; puis un flan de 15 images; puis la video.aviséquence de l'image 30 à l'image 79 à nouveau.

Pour utiliser des images (disons .png) dans une composition de montage vidéo:

melt \
video.avi in=30 out=79 \
test.png in=0 out=15 \
video.avi in=30 out=79 \
-blank 15

Notez que pour test.png, le in=paramètre n'a pas besoin d'être 0 - cependant, l'image sera affichée pendant out- intemps; dans ce cas, il serait plus simple de laisser tout simplement le in=0paramètre complètement.

 

La bonne chose est que cette séquence d'édition peut être enregistrée - ou comme l' meltappelle, sérialisée - dans un fichier; notez qu'il existe deux manières de procéder à une telle sérialisation: "simple" ou XML. Par exemple, pour enregistrer la commande ci-dessus en tant que fichier sérialisé "simple", nous pouvons simplement ajouter le -serialise [filename]commutateur à la commande:

$ melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -serialise file.melt 
Project saved as file.melt.

Maintenant, le file.meltcontient:

video.avi
in=30
out=79
-blank
15
video.avi
in=30
out=79

Apparemment, ce format de fichier sérialisé "simple" ne contient pas de caractère "commentant" - si j'essaye d'ajouter une # commentligne " ", il se meltplaint de: " Impossible de charger" # commentaire " '(mais à part cela, il semble que une ligne est ignorée et la lecture continue quand même). " .melt" semble être une extension qui meltreconnaît comme un simple fichier sérialisé.

Maintenant, pour rejouer ce fichier sérialisé, nous pourrions en principe simplement appeler melt file.melt- cependant, une ligne de commande plus complète serait:

melt melt_file:file.melt -consumer sdl

... ce qui signifierait: utiliser le melt_file"producteur" pour ouvrir file.meltet rendre ses cadres sur le "consommateur" sdl(fenêtre).

Notez que j'ai l'expérience, que (disons) les .flvvidéos sont lues sans problème sur la ligne de commande - cependant, provoquent une erreur de segmentation lorsqu'elles sont spécifiées dans le file.meltfichier sérialisé! .dvles vidéos produites par elles- meltmêmes semblent bien fonctionner en file.melt...

 

Le type XML de sérialisation peut être obtenu en utilisant le -consumer xml:commutateur ( au lieu de-serialise ) - donc l'exemple ci-dessus serait maintenant:

melt video.avi in=30 out=79 -blank 15 video.avi in=30 out=79 -consumer xml:file.mlt

Pour "lire" le file.mltfichier XML nouvellement généré , on peut maintenant le faire directement melt file.mlt- ou, une ligne de commande plus complète serait:

melt xml:file.mlt -consumer sdl

... ce qui signifierait: utiliser le xml"producteur" ( notez, auparavant c'était un consommateur ) pour ouvrir file.mlt, et rendre ses frames sur le "consommateur" sdl(fenêtre).

Notez que dans ce cas, j'ai expérimenté que les mêmes .flvvidéos qui ont causé une erreur de segmentation avec un simple fichier de sérialisation - fonctionnent très bien avec un fichier de sérialisation XML!

Dans ce cas, le file.mltfichier XML résultant a beaucoup plus de paramètres, tels que la résolution, la fréquence d'images, les informations de codec, etc. - mais il est également plus difficile de travailler directement dans un éditeur de texte:

<?xml version="1.0" encoding="utf-8"?>
<mlt root="/path/to" title="video.avi">
  <profile description="automatic" width="320" height="240" progressive="1" sample_aspect_num="1" sample_aspect_den="1" display_aspect_num="320" display_aspect_den="240" frame_rate_num="25" frame_rate_den="1" colorspace="601"/>
  <producer id="producer0" in="30" out="79">
    <property name="mlt_type">producer</property>
    <property name="aspect_ratio">1.000000</property>
    <property name="length">125</property>
    <property name="eof">pause</property>
    <property name="resource">video.avi</property>
    <property name="meta.media.nb_streams">2</property>
    <property name="meta.media.0.stream.type">video</property>
    <property name="meta.media.0.stream.frame_rate">25.000000</property>
    <property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
    <property name="meta.media.0.codec.frame_rate">25.000000</property>
    <property name="meta.media.0.codec.pix_fmt">yuv420p</property>
    <property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
    <property name="meta.media.0.codec.colorspace">601</property>
    <property name="meta.media.0.codec.name">mpeg4</property>
    <property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
    <property name="meta.media.0.codec.bit_rate">0</property>
    <property name="meta.media.1.stream.type">audio</property>
    <property name="meta.media.1.codec.sample_fmt">s16</property>
    <property name="meta.media.1.codec.sample_rate">22050</property>
    <property name="meta.media.1.codec.channels">1</property>
    <property name="meta.media.1.codec.name">mp2</property>
    <property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
    <property name="meta.media.1.codec.bit_rate">64000</property>
    <property name="seekable">1</property>
    <property name="meta.media.sample_aspect_num">1</property>
    <property name="meta.media.sample_aspect_den">1</property>
    <property name="meta.attr.title.markup"></property>
    <property name="meta.attr.author.markup"></property>
    <property name="meta.attr.copyright.markup"></property>
    <property name="meta.attr.comment.markup"></property>
    <property name="meta.attr.album.markup"></property>
    <property name="audio_index">1</property>
    <property name="video_index">0</property>
    <property name="mlt_service">avformat</property>
  </producer>
  <producer id="producer1" in="30" out="79">
    <property name="mlt_type">producer</property>
    <property name="aspect_ratio">1.000000</property>
    <property name="length">125</property>
    <property name="eof">pause</property>
    <property name="resource">video.avi</property>
    <property name="meta.media.nb_streams">2</property>
    <property name="meta.media.0.stream.type">video</property>
    <property name="meta.media.0.stream.frame_rate">25.000000</property>
    <property name="meta.media.0.stream.sample_aspect_ratio">0.000000</property>
    <property name="meta.media.0.codec.frame_rate">25.000000</property>
    <property name="meta.media.0.codec.pix_fmt">yuv420p</property>
    <property name="meta.media.0.codec.sample_aspect_ratio">1.000000</property>
    <property name="meta.media.0.codec.colorspace">601</property>
    <property name="meta.media.0.codec.name">mpeg4</property>
    <property name="meta.media.0.codec.long_name">MPEG-4 part 2</property>
    <property name="meta.media.0.codec.bit_rate">0</property>
    <property name="meta.media.1.stream.type">audio</property>
    <property name="meta.media.1.codec.sample_fmt">s16</property>
    <property name="meta.media.1.codec.sample_rate">22050</property>
    <property name="meta.media.1.codec.channels">1</property>
    <property name="meta.media.1.codec.name">mp2</property>
    <property name="meta.media.1.codec.long_name">MP2 (MPEG audio layer 2)</property>
    <property name="meta.media.1.codec.bit_rate">64000</property>
    <property name="seekable">1</property>
    <property name="meta.media.sample_aspect_num">1</property>
    <property name="meta.media.sample_aspect_den">1</property>
    <property name="meta.attr.title.markup"></property>
    <property name="meta.attr.author.markup"></property>
    <property name="meta.attr.copyright.markup"></property>
    <property name="meta.attr.comment.markup"></property>
    <property name="meta.attr.album.markup"></property>
    <property name="audio_index">1</property>
    <property name="video_index">0</property>
    <property name="mlt_service">avformat</property>
  </producer>
  <playlist id="playlist0">
    <entry producer="producer0" in="0" out="49"/>
    <blank length="16"/>
    <entry producer="producer1" in="0" out="49"/>
  </playlist>
  <tractor id="tractor0" title="video.avi" global_feed="1" in="0" out="115">
    <track producer="playlist0"/>
  </tractor>
</mlt>

En outre, voici un exemple de coupes avec précision d'image: Coupez avec précision des fichiers vidéo à partir de la ligne de commande - Super User
sdaau

7

La solution ffmpeg à ce problème ressemble à ceci:

mkfifo temp1 temp2 temp3
ffmpeg -i input.wmv -ss 30 -to 60 -c copy output.wmv temp1 2> /dev/null & \
ffmpeg -i input2.wmv -t 60 -c copy temp2 2> /dev/null & \
ffmpeg -i input3.wmv -i image.png -filter_complex "[0:v][1:v] \
overlay=25:25:enable='between(t,0,20)'" -pix_fmt yuv420p -c:a copy temp3 2> /dev/null & \
ffmpeg -f mpegts -i "concat:temp1|temp2|temp3" -c copy output.mp4

Il utilise des canaux nommés, il n'y a donc pas de création de fichiers temporaires sur le disque et vous permet de découper des morceaux des clips vidéo et d'ajouter des images.

Cet exemple utilise le temps 30-60 de la première entrée, puis ajoute la première minute de la deuxième entrée, puis insère un fichier image, puis la troisième vidéo entière.

Code retiré de:

page de concaténation ffmpeg: https://trac.ffmpeg.org/wiki/Concatenate

page du superutilisateur Utilisation de ffmpeg pour couper une vidéo

page du superutilisateur /video/12105/add-an-image-in-front-of-video-using-ffmpeg


Merci pour cela, j'ai également récemment entendu parler de ffmpeg-concat , qui est écrit en JavaScript (et vous devez l' npminstaller), alors j'ai pensé le mentionner
sdaau

4

Moi aussi, je cherchais un tel outil et il semble que la fonte soit l'outil pour le travail, mais la documentation est presque impossible à comprendre / manquante. Vous pouvez effectuer presque n'importe quelle combinaison d'édition. J'avais quelques images de "caméra d'action" ... le son était cependant inutilisable. J'ai rejoint la vidéo (h264) ensemble, ajouté un fondu de 60 images et remplacé le son par une piste sonore en utilisant:

% melt -video-track vid1.avi vid2.avi -mix 60 -mixer luma vid3.avi \
   -mix 60 -mixer luma -audio-track vorbis:track1.ogg vorbis:track2.ogg \
   -consumer avformat:OUT.avi acodec=libmp3lame vcodec=libx264

Vous pouvez en lire plus ici . Le site Web principal est ici .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.