Edycja wideo z wiersza poleceń w systemie Linux (wycinanie, łączenie i podgląd)

32

Mam raczej proste potrzeby edycji - muszę wyciąć niektóre filmy, może wstawić między nimi PNG i dołączyć do tych filmów (nie potrzebuję przejść, efektów itp.). Zasadniczo pitivizrobiłbym to, co chcę - poza tym, że używam AVI 640x480 30 fps z aparatu i jak tylko wrzucę kilka minut tego rodzaju materiału, pitivizaczyna się zawieszać na podglądzie, a zatem staje się bezużyteczny.

Zacząłem więc szukać narzędzia wiersza polecenia dla systemu Linux; Chyba tylko ffmpeg( linia poleceń - Używanie ffmpeg do cięcia wideo - Super Użytkownik ) i mplayer( Sam - Edycja pliku wideo z mencoderem pod linuksem ) są jak dotąd kandydatami, ale nie mogę znaleźć przykładów zastosowania, które mam na myśli.

 

Zasadniczo wyobrażam sobie, że istnieje koder i narzędzia odtwarzacza (takie jak ffmpegvs ffplay; lub mencodervs mplayer) - takie, że na początek sekwencja edycji może być określona bezpośrednio w wierszu polecenia, najlepiej z rozdzielczością ramki - pseudokod wyglądałby następująco:

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

... lub może mieć plik tekstowy „listy odtwarzania”, taki jak:

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 

... więc można to nazwać

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

Chodzi o to, że wszystkie filmy są w tym samym formacie - umożliwienie narzędzia aby uniknąć transkodowanie, i po prostu zrobić „raw copy” zamiast (jak w mencoder„s skopiować kodek:" -oac copy -ovc copy„) - lub w braku tego, nieskompresowane audio / wideo byłoby OK (choć zjadłoby trochę miejsca). W przypadku obrazu nieruchomego narzędzie użyłoby kodowania ustawionego przez pliki wideo.

 

Chodzi o to, że do tej pory widzę to mencoderi ffmpegmogę operować na pojedynczych plikach; np. wyciąć pojedynczą sekcję z jednego pliku lub połączyć pliki ( mencoderma również Edycję list decyzyjnych (EDL) , których można użyć do wycinania z dokładnością do ramki - dzięki czemu można zdefiniować wiele regionów wycinania, ale ponownie przypisuje się je do jednego pliku ). Co oznacza, że ​​najpierw muszę wyciąć elementy z poszczególnych plików (z których każdy wymagałby własnego pliku tymczasowego na dysku), a następnie połączyć je w końcowy plik wideo.

Wyobrażam sobie wtedy, że istnieje odpowiednie narzędzie odtwarzacza, które może odczytać ten sam format opcji / plik listy odtwarzania z wiersza poleceń co narzędzie do kodowania - z wyjątkiem tego, że nie wygeneruje pliku wyjściowego, ale zamiast tego odtworzy wideo; np. w pseudokodzie:

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

... i, biorąc pod uwagę nie ma wystarczającej ilości pamięci, byłoby wygenerować podgląd niskiej rozdzielczości wideo w pamięci RAM i odtworzyć go w oknie, jednocześnie oferując pewną ograniczoną interakcję (jak mplayer„s skrótów klawiaturowych na odtwarzanie, pauza, przewijanie do tyłu, krok ramie ). Oczywiście wyobrażam sobie, że czasy rozpoczęcia i zakończenia odnoszą się do całej listy odtwarzania i zawierają na liście dowolny plik, który może znaleźć się w tym regionie.

Tak więc końcowym wynikiem tego wszystkiego byłoby: działanie wiersza poleceń; żadnych plików tymczasowych podczas edycji - a także żadnych plików tymczasowych (ani transkodowania) podczas renderowania końcowego wyniku ... co, moim zdaniem, byłoby fajne.

Tak więc, chociaż uważam, że wszystkie powyższe mogą być nieco rozciągnięte - czy istnieje coś, co przybliżałoby opisany powyżej przepływ pracy?

sdaau
źródło
1
Często też używam mkvmerge, kiedy muszę dzielić / dołączać filmy.
Vi.
Dziękuję za to, @Vi. - nigdy wcześniej o tym nie słyszałem mkvmerge, upewnię się, że to sprawdzę .. Pozdrawiam!
sdaau

Odpowiedzi:

17

Tak jest. Spróbuj użyć aplikacji o nazwie „Stop”. Zobacz dokumentację tutaj:

https://www.mltframework.org/docs/melt/

Jeśli używasz dystrybucji wywodzącej się z Debiana:

apt-get install melt
Ielton
źródło
na komputerze Mac:brew install mlt
kraftydevil,
23

Ok, ponieważ nie mogę znaleźć dużo informacji na temat meltkorzystania z wiersza poleceń, oto kilka uwag .. (a następnie zobacz tę odpowiedź Używanie podstawiania procesów w celu oszukania programów oczekujących plików, z określonymi rozszerzeniami jako argumentem? - Wymiana stosu Unix i Linux dla skryptu przykład przez bash)

Na początek - jest pakiet Ubuntu / Debian dla melt(Mam Ubuntu 11.04 z MLT melt 0.6.2); link podany przez @Ielton jest dla Wiki „Media Lovin 'Toolkit” (MLT), który meltjest częścią (ale także openshoti kdenlive). Oto link do plików tekstowych dokumentacji z ich git: mltframework.org/mlt.git/tree - docs / ; zwróć uwagę, że wiki ma stronę o BuildScripts .

Na razie największym (jedynym) problemem, jaki mam z tym, jest to, że nie mogę znaleźć sposobu na eksport nieskompresowanej kompozycji wideo (jako pngramki lub jakiś nieskompresowany format wideo).

 

Po pierwsze, w wierszu poleceń meltmożesz sterować odtwarzaniem poprzez klatki; na przykład, aby „utworzyć” 15-ramkowy biały blank i wyświetlić go za pomocą wbudowanego meltodtwarzacza, użyj

melt -blank 15

Podczas przeglądania za pomocą meltpojawi się także informacja wiersza poleceń stderrdla wbudowanego odtwarzacza:

$ 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

Po zakończeniu meltodtwarzania nie zakończy się - powinieneś więc wpisać, qaby wyjść.

Należy zauważyć, że są tak zwani „producenci” i „konsumenci” melt. Jeśli nic nie zostanie określone, wówczas domyślnym „konsumentem” jest okno SDL (Simple DirectMedia Layer) odtwarzające wideo; więc powyższe polecenie jest takie samo jak:

melt -blank 15 -consumer sdl

Dlatego jeśli chcemy zapisać meltwyświetlane dane, powinniśmy zmienić konsumenta na coś, co będzie obsługiwać format pliku. Aby uzyskać listę konsumentów:

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

libdvWyjście DV wola konsumentów sformatowane dane bezpośrednio stdout, tak aby zapisać plik wideo do .dvpliku chcesz zrobić:

melt -blank 15 -consumer libdv > test.dv

Zauważ, że spośród wymienionych klientów jedynym formatem, który wypróbowałem, który można również otworzyć w innej aplikacji jest libdv(użyłem vlcjako innej aplikacji); może to jednak nie powieść się w przypadku innego rodzaju transkodowania ( np. jeśli zamiast pustego miejsca spróbuję przekonwertować fragment .flvkodu z pliku, powstały plik .dv otworzy się i odtworzy vlc, ale jest uszkodzony ).

 

Teraz część do edycji ; w zasadzie można podać serię sekcji nazwa-pliku / wejście / wyjście bezpośrednio w wierszu poleceń; powiedzmy, że masz plik, video.avi- wtedy możesz zrobić:

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

lub nieco lepiej sformatowany:

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

Oznacza to, że video.aviz ramki 30 do ramki 79 będzie odtwarzany; następnie 15-ramka pusta; a następnie ponownie video.avisekwencja od ramki 30 do ramki 79.

Aby wykorzystać obrazy (powiedzmy .png) w kompozycji do edycji wideo:

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

Należy pamiętać, że dla test.png, in=parametr nie musi być 0 - jednak obraz zostanie wyświetlony na out- inczas; w takim przypadku najłatwiej byłoby po prostu in=0całkowicie pominąć parametr.

 

Dobrą rzeczą jest to, że sekwencję edycji można zapisać - lub jak meltto się nazywa, serializować - do pliku; Uwaga: istnieją dwa sposoby serializacji: „prosty” lub XML. Na przykład, aby zapisać powyższe polecenie jako „prosty” plik serializowany, możemy po prostu dodać -serialise [filename]przełącznik do polecenia:

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

Teraz file.meltzawiera:

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

Pozornie ten „prosty” serializowany format pliku nie zawiera znaku „komentującego” - jeśli spróbuję dodać # commentwiersz „ ”, meltnarzeka: „ Nie udało się załadować„ # komentarza ” ” (ale poza tym wydaje się, że takie wiersz jest ignorowany, a odtwarzanie i tak jest kontynuowane). .meltWydaje się, że „ ” jest rozszerzeniem, które meltrozpoznaje zwykły plik serializowany.

Teraz, aby odtworzyć ten zserializowany plik, możemy w zasadzie po prostu wywołać melt file.melt- jednak bardziej kompletna linia poleceń to:

melt melt_file:file.melt -consumer sdl

... co oznaczałoby: użyj melt_file„producenta”, aby otworzyć file.melti renderować jego ramki w „konsumentu” sdl(oknie).

Zauważ, że mam doświadczenie, że (powiedzmy) .flvfilmy odtwarzane są bez problemu w wierszu poleceń - powodują jednak błąd segmentacji, gdy są określone w file.meltpliku zserializowanym! .dvwyprodukowane przez meltsiebie filmy wydają się działać dobrze w file.melt...

 

Serializację typu XML można osiągnąć za pomocą -consumer xml:przełącznika ( zamiast-serialise ) - więc powyższy przykład byłby teraz:

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

Aby „odtworzyć” nowo wygenerowany file.mltplik XML, można teraz zrobić bezpośrednio melt file.mlt- lub bardziej kompletnym wierszem poleceń byłoby:

melt xml:file.mlt -consumer sdl

... co oznaczałoby: użyj xml„producenta” ( uwaga, wcześniej był konsumentem ), aby otworzyć file.mlti renderować swoje ramki na „konsumentu” sdl(okno).

Zauważ, że w tym przypadku zauważyłem, że te same .flvfilmy, które spowodowały segfault z prostym plikiem serializacji - działają dobrze z plikiem serializacji XML!

W takim przypadku wynikowy file.mltplik XML ma o wiele więcej ustawień, takich jak rozdzielczość, liczba klatek na sekundę, informacje o kodekach itp. - ale trudniej jest pracować bezpośrednio w edytorze tekstu:

<?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>
sdaau
źródło
Również tutaj jest przykład na klatkach dokładne cięcie: Precyzyjnie wycięte pliki wideo z linii poleceń - Super User
sdaau
7

Rozwiązanie ffmpeg tego problemu wygląda mniej więcej tak:

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

Używa nazwanych potoków, więc nie ma potrzeby tworzenia plików tymczasowych na dysku i pozwala na cięcie fragmentów klipów wideo i dodawanie obrazów.

Ten przykład wykorzystuje czas 30–60 pierwszego wejścia, a następnie dodaje pierwszą minutę drugiego wejścia, następnie wstawia plik obrazu, a następnie cały trzeci film.

Kod usunięty z:

Strona konkatenacji ffmpeg: https://trac.ffmpeg.org/wiki/Concatenate

strona superużytkownika Używanie ffmpeg do cięcia wideo

strona superużytkownika https://video.stackexchange.com/questions/12105/add-an-image-in-front-of-video-using-ffmpeg

codeMonkey
źródło
Dzięki za to niedawno dowiedziałem się o ffmpeg-concat , który jest napisany w JavaScript (i trzeba npmgo zainstalować), więc pomyślałem, że wspomnę o tym
sdaau
4

Ja również szukałem takiego narzędzia i wydaje się, że stop jest narzędziem do tego zadania, jednak dokumentacji nie można zrozumieć / brakuje. Możesz wykonać prawie dowolną kombinację edycji. Miałem trochę materiału z kamery akcji ... dźwięk był jednak bezużyteczny. Połączyłem wideo (h264), dodałem 60 klatek i zastąpiłem dźwięk ścieżką dźwiękową, używając:

% 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

Możesz przeczytać więcej na ten temat tutaj . Główna strona jest tutaj .

użytkownik196805
źródło