Mam duży zestaw plików JPG, które chcę bezstratnie przekonwertować na wideo (lub przynajmniej bardzo blisko bezstratnie, o ile czas kodowania nie jest znacznie dłuższy niż w innym przypadku).
Naiwnie sądzę, że powinien istnieć kodek, który może przechowywać każdą indywidualną ramkę jpg w stanie niezmienionym (bez ponownej kompresji) i być może osiągnąć pewną dobrą kompresję, zastępując niektóre ramki tylko informacjami o delcie z poprzedniej ramki. W moim przypadku istnieje wiele sekwencji ramek, które są identyczne lub mają niewielką różnicę między nimi.
Czy jest jakiś kodek i odpowiednie ustawienia dla ffmpeg, które mogą to osiągnąć?
Odpowiedzi:
Po prostu zmiksuj obrazy
Możesz po prostu zmiksować obrazy JPG, aby utworzyć wideo:
Zauważ, że jeśli pominiesz,
-framerate
wówczas-framerate 25
do danych wejściowych zostanie zastosowana wartość domyślna .Bezstratna optymalizacja
Możesz użyć
jpegtran
do bezstratnej optymalizacji każdej ramki, co może zapewnić znaczne oszczędności rozmiaru pliku:Teraz wymieszaj z
ffmpeg
jak pokazano powyżej.Sprawdzanie, czy faktycznie jest bezstratne
Framehash muxer mogą być wykorzystane w celu porównania unikalny hash każdej ramki, aby zapewnić, że wynik jest naprawdę bezstratne:
W powyższych przykładach każda powiązana ramka dla wejścia i wyjścia ma ten sam skrót, zapewniając, że ramki są identyczne i że dane wyjściowe są bezstratne.
Zobacz także
źródło
framemd5
polecenia mają osiągnąć poza zwykłą listą skrótów? jak uzyskać dodatkową kompresję, gdy w ten sposób zostaną zidentyfikowane identyczne ramki?Spowoduje to wygenerowanie bezstratnego wideo H.264, w którym klatki będą wykorzystywać informacje z innych klatek
ffmpeg -f image2 -r 30 -i %09d.jpg -vcodec libx264 -profile:v high444 -refs 16 -crf 0 -preset ultrafast a.mp4
Objaśnienie opcji:
-f image2
- mówi ffmpeg, aby wybrał grupę obrazów-r 30
- mówi ffmpeg do kodowania z prędkością 30 klatek (lub obrazów) na sekundę (zmień to na żądaną szybkość klatek)-i %09d.jpg
- informuje ffmpeg, aby używał obrazów 000000000.jpg do 999999999.jpg jako danych wejściowych. Zmień9
in%09d.jpg
na ile zer ma nazwa sekwencji obrazów. Jeśli twoje nazwy plików to na przykład img0001.jpg, wówczas będzie to wyrażone jako img% 04d.jpg-vcodec libx264
- informuje ffmpeg, aby wyprowadzał dane do pliku zgodnego z H.264-profile:v high444
- mówi libx264, aby używał profilu predykcyjnego bezstratnego High 4: 4: 4, umożliwiając bezstratne kodowanie-refs 16
- mówi libx264, aby 16 buforów zapisało 16 obrazów, aby mogły się do nich odwoływać inne obrazy w filmie-crf 0
- nakazuje libx264 wykonanie bezstratnego kodowania-preset ultrafast
- mówi libx264, aby priorytetem była szybkość kodowania nad rozmiarem pliku wyjściowegoa.mp4
- informuje ffmpeg, aby zapisał dane wyjściowe w pliku MP4 o nazwie a.mp4. Zmień to na nazwę pliku i format, którego chcesz używaćźródło
-f image2
tutaj jest zbyteczne. Plik obrazu demuxer powinien używać-framerate
zamiast-r
. libx264 automatycznie wybierze odpowiednie-profile
dla bezstratnych i-preset
zajmie się tym-refs
.-refs 5
w MOST, chyba że wiesz, że twoja treść ma identyczne obrazy oddzielone kilkoma innymi, co może spowodować, że x264 straci referencję, zanim dotrze do duplikatu. Wyższy niżultrafast
niewiele różni się w trybie bezstratnym, inny niż ~ 10% zysk CABAC w porównaniu z CAVLC (dla wysokiego kosztu procesora przy przepływności wymaganej dla bezstratnej). Poważnie, w niektórych działaniach na żywo 720x480p60 (wyjście z przeplotem),superfast
było 28 GB,slower
było 27 GB. Jeśli czas kodowania nie ma znaczenia, ale czas dekodowania ma znaczenie, pamiętaj, aby unikać CABAC. Może nawet-tune fastdecode
. Umiarkowana liczba referencji nie powinna boleć.-preset placebo
uzyskać kilka dodatkowych ułamków procent.-vcodec libx265 -x265-params lossless=1
jest równoważną opcją. (Ale z mojego doświadczenia (= nagrywanie prezentacji pokazu slajdów Powerpoint), niekoniecznie jest to lepsze i jest znacznie wolniejsze niż h264) Bądź na bieżąco z przyszłoroczną AVOM A1 / IETF NETVC1 / Xiph Daala / cokolwiek, do tego czasu zostanie zmieniona ... tryb bezstratnyMożesz utworzyć
avi
animację jako seriępng
obrazów (png
jest bezstratna, więcjpeg => png
konwersja nie powinna degradować twoich zdjęć):jeśli twoje zdjęcia są nazwane
img_0001.jpg
gdzie „25” to żądana liczba klatek na sekundę w powstałym filmie.
-start_number
nie jest potrzebny, jeśli jest to 1, ale jest przydatny, jeśli Twój pierwszy numer wideo nie jest 1.Jeśli chcesz zakodować za
mjpeg
pomocą wiersza polecenia najwyższej jakości:Zaletą tego jest to, że możesz przekonwertować wideo z powrotem na serię zdjęć:
itp...
źródło
Aby rozwinąć odpowiedź LordNeckbearda, tak, po prostu zmiksuj dane JPEG w strumieniu wideo MJPEG. Będzie to najmniejsza reprezentacja dokładnej sekwencji obrazów wyjściowych, mimo że MJPEG jest okropnie nieefektywnym kodekiem według dzisiejszych standardów. (brak czasowej redundancji, a nawet brak prognoz wewnętrznych).
Możesz utworzyć wideo MJPEG ze zmienną liczbą klatek na sekundę, aby wykorzystać zduplikowane obrazy na wejściu.
Hmm, to nie zadziała, ponieważ mpdecimate nie będzie działać na skompresowanych danych i nie możemy pozwolić, aby ffmpeg zdekodował, a następnie ponownie JPEG zdjęć bez strat i kosztów procesora.
Może jeśli zastąpisz zduplikowane pliki źródłowe jpg pustymi plikami o tym numerze sekwencji lub coś takiego?
Ponieważ to pytanie nie jest jeszcze aktualne, nie będę się zastanawiać, jak to zrobić, chyba że ktoś odpowie na pytanie, jak to zrobić. Ale ponieważ MJPEG może przejść do kontenera mkv, jestem pewien, że możliwe jest posiadanie pliku, który nie powiela danych jpeg dla powtarzających się ramek, ale zamiast tego nie ma ramki wyjściowej do zdekodowania, dopóki sekwencja duplikatów nie będzie koniec.
Och, oto pomysł:
Następnie usuń (lub przenieś na bok) wszystkie pliki JPEG dla ramek, które mpdecimate chce upuścić (prawdopodobnie ma kilka opcji rejestrowania? Lub -vf showinfo i przeanalizuj to, i przenieś lub dowiązaj tylko ramki, które pojawiają się na wyjściu, pozostawiając za sobą upuszczone pliki JPEG?). prześlij to do pliku MJPEG.mkv, a następnie zrób coś z mkvmerge, aby zastąpić znaczniki czasu ramki znacznikami czasu z
mpdecimate.timestamps
.Gdybyś był kodowaniem x, zamiast po prostu miksować dane jpeg do MJPEG, byłoby to DUŻO łatwiejsze, ponieważ użyłbyś mojej pierwszej komendy z mpdecimate i dowolnym innym kodekiem innym niż
copy
i działałoby to po prostu (tm).Nie próbowałem tego, ponieważ było to stare pytanie. Również powód, dla którego nie uzupełniałem luk w sposobie filtrowania katalogu plików JPEG w oparciu o dane wyjściowe mpdecimate lub w jaki sposób faktycznie korzystać ze strumienia sygnatury czasowej.
źródło