Jak utworzyć wideo z obrazów za pomocą FFmpeg?

86

Czy można użyć opcji ffmpegUtwórz wideo z zestawu sekwencji, w których liczba nie zaczyna się od zera?

Na przykład mam kilka zdjęć [test_100.jpg, test_101.jpg, test_102.jpg, ..., test_200.jpg] i chcę je przekonwertować na wideo. Próbowałem następującego polecenia, ale nie zadziałało (wygląda na to, że liczba powinna zaczynać się od zera):

ffmpeg -i test_% d.jpg -vcodec mpeg4 test.avi

Jakaś rada?

JakeGould
źródło
Minęło trochę czasu, odkąd zadałeś to pytanie, ale jeśli nadal jesteś zainteresowany pytaniem, odpowiedź brzmi TAK - opublikowałem szczegóły i przykład poniżej: stackoverflow.com/a/12160155/181638
Assad Ebrahim
@casperOne przydałby się pomysł, dlaczego to nie jest temat. Wydaje się, że jest to specyficzny problem z programowaniem. Tag FFmpeg ma 3,7 tys. Obserwujących, a przy 27 tys. Wyświetleń ludzie uważają, że jest on przydatny ..
geotheory
2
@geotheory Statystyki tagów są nieistotne. ffmpeg to program na wiele sposobów, na przykład WinRar. Chociaż można zaprogramować w stosunku do bibliotek w ffmpeg , to pytanie nie jest o tym. Używanie ffmpeg z wiersza poleceń należy zapytać na Super User , gdzie jest na temat.
casperOne

Odpowiedzi:

81

Nie trzeba zmieniać nazw plików, jeśli używasz -start_numberprzełącznika w taki sposób:

ffmpeg -start_number n -i test_%d.jpg -vcodec mpeg4 test.avi

gdzie njest początek sekwencji zdjęć.

Uwaga: będzie to działać, dopóki sekwencja nie zostanie przerwana po uruchomieniu. Jeśli są luki i chcesz uwzględnić wszystkie kadry, może być konieczna ponowna numeracja w celu uzupełnienia luk.

Istnieje kilka innych przełączników, które mogą okazać się przydatne.

Używam poniższej linijki, aby uzyskać wolniejszą częstotliwość klatek i kompresować obrazy i uzyskać mniejszy wynikowy film:

ffmpeg.exe -f image2 -framerate 25 -pattern_type sequence -start_number 1234 -r 3 -i Imgp%04d.jpg -s 720x480 test.avi

Ta -r 3opcja ustawia liczbę klatek na sekundę uzyskanego wideo na 3 klatki na sekundę, dzięki czemu widzę każdą nieruchomą przez krótki czas. -sOpcja przeskalowanie zdjęcia do żądanej rozdzielczości zarządzać rozmiar wynikowego filmu.

(W powłoce systemu Windows, należy wymienić -i Imgp%04d.jpgz -i "Imgp%%04d.jpg". Kredyt na ten Mike Fitzpatrick https://superuser.com/a/344178/153054 )

Assad Ebrahim
źródło
4
jaka jest różnica między -r a -framerate?
1
są takie same IIRC
rogerdpack
22
Nie ma potrzeby numerowania bzdur, o ile z przyjemnością zaakceptujesz kolejność, w jakiej pojawiają się w (powiedzmy) ls ... po prostu użyj: ffmpeg -pattern_type glob -i '* .jpg' movie.mp4
Orwellophile
2
Czy jest jakiś przełącznik kontrolujący odstęp czasowy między obrazami, powiedzmy, chciałbym pokazać pierwszy obraz 13s, drugi 15s, 24s dla trzeciego, odstęp czasu jest zdefiniowany przez użytkownika, czy to możliwe?
zionpi
2
patrz także trac.ffmpeg.org/wiki/…
david.libremone 20.04.2016
38

możesz użyć tego fragmentu kodu:

 cat *.jpg | ffmpeg -f image2pipe -r 1 -vcodec mjpeg -i - -vcodec libx264 out.mp4

źródło
Nie powoduje to obracania plików JPG do obrotu określonego w metadanych.
Erik Johansson,
17

Przykładowy skrypt można znaleźć w dokumentacji ffmpeg :

3.2 Jak zakodować pojedyncze zdjęcia w filmach?

Jeśli masz dużo zdjęć do zmiany nazwy, możesz użyć następującego polecenia, aby zmniejszyć obciążenie. Polecenie, używając składni powłoki bourne, symbolicznie łączy wszystkie pliki w bieżącym katalogu, które pasują * jpg do /tmp' directory in the sequence ofimg001.jpg ', `img002.jpg' i tak dalej.

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i" /tmp/img"$counter".jpg; x=$(($x+1)); done

Następnie uruchomić:

ffmpeg -f image2 -i /tmp/img%03d.jpg /tmp/a.mpg
gaizka
źródło
2
Lepiej byłoby, gdyby x = 0 zaczął, więc nazwa obrazu zaczyna się img000.jpg, ponieważ tego oczekuje ffmpeg. Również symlinkowanie nie działało dla mnie, ponieważ ffmpeg nie mógł znaleźć plików, więc zamiast tego musiałem użyć cp (oczywista prędkość i spowolnienie przestrzeni, ale i tak jestem nimi). mv zadziała również, jeśli nie masz nic przeciwko utracie oryginałów.
Zauważ, że w tej odpowiedzi podane polecenie tworzy dowiązania twarde, a nie dowiązania symboliczne. Jeśli chodzi o użycie, cpjeśli linkowanie nie działa, jeśli twój system plików obsługuje, cp --reflink=autoosiągnie znacznie lepsze wykorzystanie prędkości / miejsca.
Félix Saparelli
12

Z dokumentów ffmpeg:

Używanie wzorca globu

ffmpeg obsługuje również globowanie w stylu bash (* reprezentuje dowolną liczbę dowolnych znaków).

Jest to przydatne, jeśli obrazy są sekwencyjne, ale niekoniecznie w kolejności numerycznej, jak w poprzednich przykładach.

ffmpeg -r 1 -pattern_type glob -i 'test_*.jpg' -c:v libx264 out.mp4

Tak więc, dopóki pliki są posortowane, korzystanie z -pattern_type globprzełącznika powinno działać dla Ciebie.

Nevin Williams
źródło
Zauważ, że ten glob jest bardziej ograniczony niż zwykłe globusy powłoki: trac.ffmpeg.org/ticket/3620 najwyraźniej ponieważ typ obrazu jest wywnioskowany z rozszerzenia.
Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
11

O ile mi wiadomo, nie można rozpocząć sekwencji w liczbach losowych (nie pamiętam, czy powinieneś ją rozpocząć od 0 lub 1), a ponadto nie może mieć przerw, jeśli tak, ffmpeg przyjmie, że sekwencja się skończyła i przestań dodawać więcej zdjęć.

Ponadto, jak stwierdzono w komentarzach do mojej odpowiedzi, pamiętaj, że musisz określić szerokość swojego indeksu. Lubić:

obraz% 03d.jpg

A jeśli używasz typu indeksu% 03d, musisz uzupełnić nazwy plików 0, na przykład:

image001.jpg image002.jpg image003.jpg

itp.

Francisco Soto
źródło
1
Jeśli nazwy plików obrazów zawierają wiodące zera, łańcuch formatu musi również określać szerokość, np. „% 03d”.
1
Jeśli jest to jedyna przeszkoda, możesz po prostu napisać skrypt, aby zmienić nazwę lub dowiązać symbolicznie swoje obrazy do zestawu o prawidłowej reindeksacji.
Cascabel
1
Tak, pracowałem z tym wcześniej, napisałem jakiś czas temu opakowanie w Ruby, w którym wywołałeś instance.addImage (), a następnie instance.processVideo () i utworzy katalog tymczasowy, skopiuje / zmieni nazwę obrazów z odpowiednimi indeksami i utwórz film. To całkiem proste.
@Jefromi Utworzyłem dowiązanie symboliczne, ale jak podać ścieżkę pliku symlink do ffmpeg? Zakłada tylko, że plik dowiązania symbolicznego to obraz, który próbuję przekonwertować? Jestem na Win7 BTW
Sekwencja może rozpocząć się od 0 do 4 włącznie.
Assad Ebrahim
5

Zgadzam się z Francisco, ale w celu obejścia tego problemu możesz po prostu napisać szybki skrypt, aby przenieść lub utworzyć dowiązania symboliczne do plików z numerami sekwencji, których potrzebuje ffmpeg. Skrypt może następnie wywołać ffmpeg, a następnie usunąć łącza lub przenieść pliki z powrotem do ich pierwotnych lokalizacji.

Jason B.
źródło
1

sprawdzać

x=1; for i in *jpg; do counter=$(printf %03d $x); ln "$i"
/tmp/img"$counter".jpg; x=$(($x+1)); done

źródło
1

Wiem, że to stare pytanie, ale natknąłem się na nie w Google, szukając tej samej odpowiedzi. Żadna z odpowiedzi tutaj nie zadowoliła mnie całkowicie, więc zacząłem więcej wyszukiwać i czytać, i to jest polecenie, które wymyśliłem dla własnego problemu.

cat {0032..1501}*.png | ffmpeg -f image2pipe -framerate 5 -i - -s 720x480 test2.avi

Powodem, dla którego użyłem takiego polecenia jest ...

  1. Funkcje Cat i -f image2pipe zapewniają lepszą kontrolę nad używanymi obrazami. Na przykład pozwala używać funkcji bash, takich jak rozwijanie nawiasów klamrowych i innych poleceń, takich jak grep, w celu precyzyjnego dostrojenia wyników według własnego wyboru.
  2. Mniej przełączników do zapamiętania.
  3. NIE polecam używać opcji -r, a zamiast tego używam opcji -framerate. Z mojego doświadczenia wynika, że ​​-r częściej upuszcza ramki.
  4. Mniej skomplikowane, bez zbędnych przełączników w użyciu i będzie działać tak, jak jest. Możesz dodać większą złożoność (na przykład określenie enkodera) i dostosować go do swoich potrzeb.
David Bobb
źródło
Na pytanie PO wystarczy -start_numberwszystko.
Gyan
0

Używałem kodera flv, ponieważ moje wideo było odtwarzane we Flash Playerze (Jwplayer)

ffmpeg -i% d.jpg -vcodec flv test.flv


źródło
0

Z dokumentacji wynika , że możesz po prostu użyć *

For example, for creating a video from filenames matching the glob pattern foo-*.jpeg:

ffmpeg -f image2 -pattern_type glob -framerate 12 -i 'foo-*.jpeg' -s WxH foo.avi

Uwaga: aby poprawić wpływ na jakość, szybkość / liczba klatek na sekundę może być ważna (np. Najpierw określając bardzo niską / wysoką częstotliwość klatek, a następnie przechodząc z drugiego filtra, który sprawi, że wideo w zwolnionym tempie powróci do normy?

ntg
źródło
0

W moim przypadku było to trochę trudniejsze ze względu na liczby w plikach. Oto jak wyglądają moje obrazy:

$ ls | head -5
2014_aq_unprocessed 001.jpg
2014_aq_unprocessed 002.jpg
2014_aq_unprocessed 003.jpg
2014_aq_unprocessed 004.jpg
2014_aq_unprocessed 005.jpg

a oto polecenie, którego użyłem:

ffmpeg -i 2014_aq_unprocessed\ %3d.jpg  -vcodec mpeg4 test.avi
Mona Jalal
źródło
0

Możesz to zrobić za pomocą convert -morph:

convert *.jpg -delay 10 -morph 10 %05d.jpg

Jeśli chcesz użyć ffmpeg, użyłem

ffmpeg -pattern_type glob -i '*.jpg' -vf "setpts=10*PTS" movie.mp4

gdzie 10*PTSkaże ffmpeg spowolnić 10 razy. Możesz też mieć ułamki, aby przyspieszyć.

Martin Thoma
źródło
To po prostu interpoluje oryginalną sekwencję obrazów do nowej przestrzeni, nie tworzy pliku wideo, tak jak poprosił OP.
f0ster,
0

-pattern_type glob konkretne przykłady z dźwiękiem

Ta opcja została wspomniana na stronie : https://superuser.com/a/782520/128124, ale oto kilka konkretnych przykładów jej zastosowania, w tym dodawania dźwięku do wyjściowego wideo.

Pokaz slajdów z jednym obrazem na sekundę

ffmpeg -framerate 1 -pattern_type glob -i '*.png' \
  -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Dodaj do niego trochę muzyki, odetnij, gdy dźwięk skończy się, gdy obrazy się kończą:

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libx264 -r 30 -pix_fmt yuv420p out.mp4

Oto dwa dema na YouTube:

Bądź hipisem i użyj nieobciążonego patentem formatu wideo Theora :

ffmpeg -framerate 1 -pattern_type glob -i '*.png' -i audio.ogg \
  -c:a copy -shortest -c:v libtheora -r 30 -pix_fmt yuv420p out.ogg

Twoje zdjęcia powinny oczywiście być sortowane alfabetycznie, zwykle jako:

0001-first-thing.jpg
0002-second-thing.jpg
0003-and-third.jpg

i tak dalej.

Zobacz także: http://unix.stackexchange.com/questions/68770/converting-png-frames-to-video-at-1-fps/339399#339399

Normalna prędkość wideo z jednym obrazem na klatkę przy 30 FPS

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -c:v libx264 -pix_fmt yuv420p out.mp4

Oto jak to wygląda:

GIF wygenerowany za pomocą: https://askubuntu.com/questions/648603/how-to-create-an-animated-gif-from-mp4-video-via-command-line/837574#837574

Dodaj do niego trochę dźwięku:

ffmpeg -framerate 30 -pattern_type glob -i '*.png' \
  -i audio.ogg -c:a copy -shortest -c:v libx264 -pix_fmt yuv420p out.mp4

Wynik: https://www.youtube.com/watch?v=HG7c7lldhM4

Konwertuj jeden plik muzyczny na wideo ze stałym obrazem do przesłania do YouTube

Odpowiedzi na: Jak przekonwertować MP3 na format wideo dozwolony na Youtube?

Uzyskaj syntetyczne obrazy wejściowe testu

Oto obrazy testowe, których użyłem w tej odpowiedzi:

wget -O opengl-rotating-triangle.zip https://github.com/cirosantilli/media/blob/master/opengl-rotating-triangle.zip?raw=true
unzip opengl-rotating-triangle.zip
cd opengl-rotating-triangle
wget -O audio.ogg https://upload.wikimedia.org/wikipedia/commons/7/74/Alnitaque_%26_Moon_Shot_-_EURO_%28Extended_Mix%29.ogg

Obrazy generowane za pomocą: https://stackoverflow.com/questions/3191978/how-to-use-glut-opengl-to-render-to-a-file/14324292#14324292

Fajnie jest obserwować, o ile wideo kompresuje sekwencję obrazów znacznie lepiej niż ZIP, ponieważ jest w stanie kompresować między ramkami za pomocą specjalistycznych algorytmów:

  • opengl-rotating-triangle.mp4: 340 tys
  • opengl-rotating-triangle.zip: 7,3 mln

Informacje o opcjach CLI

Zauważ jednak, że pomimo nazwy, -globnie jest to tak ogólne jak wzorce globu powłoki, np .: -i '*'zawodzi: https://trac.ffmpeg.org/ticket/3620 (najwyraźniej ponieważ typ pliku jest wywnioskowany z rozszerzenia).

-r 30sprawia, że -framerate 1wideo 30 FPS w celu przezwyciężenia błędów w odtwarzaczach takich jak VLC dla niskich klatek na sekundę: https://stackoverflow.com/questions/19267443/playback-issues-in-vlc-with-low-fps-video-from-images-using- ffmpeg / 41797724 # 41797724 Dlatego powtarza każdą klatkę 30 razy, aby zachować pożądany efekt 1 obrazu na sekundę.

Następne kroki

Będziesz także chciał:

DO ZROBIENIA: naucz się wycinać i łączyć wiele plików audio w wideo z wiersza poleceń:

Testowane na

ffmpeg 3.4.4, vlc 3.0.3, Ubuntu 18.04.

Bibliografia

Ciro Santilli
źródło