Sekwencja obrazów FFMPEG o różnych czasach trwania


16

Powiedzmy, że mam plik mp3 o długości 1 minuty. I mam 20 zdjęć PNG. Chcę połączyć te obrazy i dźwięk w plik wideo, ale nie chcę, aby każdy obraz trwał 3 sekundy na ekranie, chcę, aby niektóre obrazy trwały 5 sekund, inne 1 sekundę itp.

Jedyny sposób, jaki mogę wymyślić, to po prostu skopiować obrazy, które powinny trwać dłużej, np. Aby obraz1, obraz2, obraz3 były dokładnie takie same, daje mi to 3 razy więcej czasu na wideo.

Jest to jednak bardzo czasochłonne i zajmuje dużo miejsca. Czy jest jakiś przełącznik / parametr w ffmpeg, który pozwala mi to zrobić?


Jak się dowiedziałeś, ffmpeg powinien wyświetlać każdy obraz o tej samej długości. Jeśli chcesz zmienić długość, musisz wcześniej zduplikować obrazy lub utworzyć osobne filmy o każdym pożądanym czasie trwania, a następnie połączyć je. Może niektórzy inni użytkownicy mają lepsze pomysły, ale tego typu zadania mogą być łatwiejsze z edytora takiego jak Kdenlive itp
llogan

Robię to ze skryptu php, więc edytor nie jest tym, czego szukam.
Flot2011,

Odpowiedzi:


21

Za pomocą ffmpeg 2.0 można to zrobić na kilka sposobów:

  1. Jedną z metod jest użycie czasów modyfikacji plików. Najpierw ustaw czas modyfikacji plików obrazów, aby każdy plik obrazu miał czas modyfikacji dłuższy niż przed nim; różnica czasu to czas trwania poprzedniego obrazu (z rozdzielczością 1 sekundy). Następnie użyj opcji demuxera image2 -ts_from_file 1. Na przykład:

    touch -t 01010000.00 image01.png
    touch -t 01010000.03 image02.png
    touch -t 01010000.08 image03.png
    ...
    ffmpeg -ts_from_file 1 -i image%2d.png -i audio.mp3 -c:a copy -vf fps=25 out.avi
    
  2. Inną metodą jest użycie concatdemuxera , który pobiera listę plików do konkatenacji, z opcjonalnym czasem trwania. Najpierw utwórz plik z obrazami i czasem trwania, który wygląda następująco:

    ffconcat version 1.0
    file image01.png
    duration 3
    file image02.png
    duration 5
    file image03.png
    

    Następnie podaj ten plik jako dane wejściowe do ffmpeg. Na przykład:

    ffmpeg -i in.ffconcat -i audio.mp3 -c:a copy -vf fps=25 out.avi
    

Może być konieczne zduplikowanie ostatniego pliku po końcowym czasie trwania. -c:a copykopiuje niezmienione audio MP3; jeśli chcesz przekonwertować go na inny kodek audio, możesz to określić zamiast copy. Możesz także określić inny kodek wideo za pomocą -c:vlub inny format pikseli -pix_fmt, na przykład -c:v libx264 -pix_fmt yuv420p. -vf fps=25spowoduje, że wyjściowa liczba klatek na sekundę będzie wynosić 25 fps. Jeśli dźwięk jest dłuższy i chcesz go odciąć po obrazach, użyj tej -shortestopcji.


Każdy pomysł, dlaczego to po prostu nie działa (mam na myśli, podążyłem za drugą (i próbowałem najpierw) opcją do litery, ale po prostu wyświetla albo czarne wideo bez obrazów, albo obrazy po prostu migają dla jednej klatki, a nie kilku sekund, jak określono w pliku ffconcat.
sup

@sup: To nadal działa dla mnie. Jeśli wideo jest czarne, odtwarzacz może nie obsługiwać używanego formatu wideo; spróbuj -c:v libx264 -profile:v baseline -pix_fmt yuv420p out.mp4zamiast out.avi lub wypróbuj innego odtwarzacza, takiego jak mpv lub ffplay. Upewnij się także, że używasz bieżącej wersji FFmpeg, i powiel ostatnią nazwę pliku obrazu po końcowym czasie trwania.
mark4o

Hm, dziwne, U używa mpv i statycznej wersji ffmpeg pobranej z ffmpeg.org, i to po prostu ignoruje czas trwania. W każdym razie znalazłem inny sposób, jak to zrobić, więc nie jest to takie ważne: ffmpeg.org/pipermail/ffmpeg-user/2015-July/027702.html
sup

1

Zarozumiały ffmpeg -i in.ffconcat -vf fps=25 out.avi

(2018: zawartość pliku in.ffconcat) - to działa:

ffconcat wersja 1.0
plik tekst.png
czas trwania 30,0
plik tekst.png

podczas gdy tak nie jest

ffconcat wersja 1.0
plik tekst.png
czas trwania 30,0

tj. w drugim przypadku

ffprobe out.avi -show_entries format=duration -v 0

[FORMAT]
czas trwania = 0,040000
[/FORMAT]
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.