Jak w danym momencie wyodrębnić 1 zrzut ekranu dla wideo za pomocą ffmpeg?

109

Istnieje wiele samouczków i materiałów pokazujących, jak wyodrębnić wiele zrzutów ekranu z wideo za pomocą ffmpeg. Ustawiasz -r i możesz nawet zacząć od określonej kwoty w.

Ale chcę tylko 1 zrzut ekranu, powiedzmy 01:23:45 cala. Lub 1 zrzut ekranu przy 86% cala.

To wszystko jest możliwe dzięki ffmpegthumbnailer, ale jest to kolejna zależność, na której nie chcę polegać. Chcę móc to zrobić za pomocą ffmpeg.

Peter Bengtsson
źródło

Odpowiedzi:

208

Skorzystaj z -ssopcji:

ffmpeg -ss 01:23:45 -i input -vframes 1 -q:v 2 output.jpg
  • W przypadku formatu JPEG służy -q:vdo kontrolowania jakości wyjściowej. Pełny zakres to liniowa skala od 1 do 31, gdzie niższa wartość daje wyższą jakość. 2-5 to dobry zakres do wypróbowania.

  • Wybrać filtr stanowi alternatywny sposób do bardziej złożonych potrzeb, takich jak wybór tylko niektóre typy ramek, albo 1 na 100, etc.

  • Umieszczenie -ssprzed wejściem będzie szybsze. Zobacz FFmpeg Wiki: Seeking i ten fragment ffmpegdokumentacji narzędzia CLI :

-ss pozycja (wejście / wyjście)

Gdy jest używana jako opcja wejściowa (wcześniej -i), szuka w tym pliku wejściowym pozycji. Zwróć uwagę, że w większości formatów nie jest możliwe dokładne wyszukiwanie, więc ffmpegbędzie szukać najbliższego punktu wyszukiwania przed pozycją. Podczas transkodowania i-accurate_seek jest włączone (domyślnie), ten dodatkowy segment między punktem wyszukiwania a pozycją zostanie zdekodowany i odrzucony. Podczas kopiowania strumieniowego lub gdy -noaccurate_seekjest używany, zostanie zachowany.

Gdy jest używana jako opcja wyjściowa (przed nazwą pliku wyjściowego), dekoduje, ale odrzuca dane wejściowe, dopóki znaczniki czasu nie osiągną pozycji.

pozycja może być w sekundach lub w hh:mm:ss[.xxx]formie.

llogan
źródło
2
To DUŻO szybciej. Dziękuję bardzo. Umieszczenie -ss na pierwszym miejscu robi ogromną różnicę.
Peter Bengtsson,
czy istnieje sposób na uzyskanie n-tej klatki po określonym czasie?
dorien
@GuntherPiez Nie widzę żadnej wzmianki o możliwych artefaktach.
Stefan Reich
2
Zauważ, że vframesjest to przestarzałe w (przynajmniej) wersji 4.2.2. Według instrukcji „[ vframes] jest przestarzałym aliasem dla„ -frames:v”, którego należy używać zamiast tego”.
Synexis
Działa doskonale i szybko.
Smeterlink
37

FFMpeg może to zrobić, szukając podanej sygnatury czasowej i wyodrębniając dokładnie jedną klatkę jako obraz, patrz na przykład:

ffmpeg -i input_file.mp4 -ss 01:23:45 -vframes 1 output.jpg

Wyjaśnijmy opcje:

-i input file           the path to the input file
-ss 01:23:45            seek the position to the specified timestamp
-vframes 1              only handle one video frame
output.jpg              output filename, should have a well-known extension

-ssParametr przyjmuje wartość w formie HH:MM:SS[.xxx]lub jako liczbę w sekundach. Jeśli potrzebujesz wartości procentowej, musisz wcześniej obliczyć czas trwania wideo.

Sir Darius
źródło
Wydaje się, że działa zgodnie z oczekiwaniami. Obecnie przeprowadzam testy porównawcze, jeśli jest to ta sama prędkość, co przy użyciu ffmpegthumbnailer.
Peter Bengtsson,
Tak, to podejście jest bardzo powolne. Zobacz peterbe.com/plog/fastest-way-to-take-screencaps-out-of-videos
Peter Bengtsson
7
spróbuj użyć opcji -ss przed -i, ponieważ pominie ona część dekodowania potoku. Może to przyspieszyć proces.
SirDarius
1
Czy istnieje sposób na wyprowadzenie jako PNG do strumienia zamiast do pliku?
Nicke Manarin
1
@NickeManarin Tak .. ffmpeg -ss 01:23:45 -i video.mp4 -c:v png -frames:v 1 image.jpg. Zauważ, że umieściłem również -ssopcję "seek" przed plikiem wejściowym w linii poleceń, tak jak zalecali inni.
Glenn Slayden