Jak obniżyć próbkowanie z 4K na 1080p przy użyciu ffmpeg przy zachowaniu jakości?

21

Mam trochę materiału 4K 3840x2160 w formacie MP4, który muszę obniżyć do 1080p. Próbowałem biec

ffmpeg -i orig.mp4 -vf scale=1920:1080 smaller.mp4  

ale wynik jest bardzo złej jakości, a cały obraz składa się z kwadratowych „kafelków”, jak gdybym powiększał 4: 1.

Oto wynik działania tego polecenia:

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'origs/P1000003.MP4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp42avc1
    creation_time   : 2015-02-19 17:10:38
  Duration: 00:05:14.48, start: 0.000000, bitrate: 95903 kb/s
    Stream #0.0(und): Video: h264 (High), yuvj420p, 3840x2160 [PAR 1:1 DAR 16:9], 95792 kb/s, 25 fps, 25 tbr, 90k tbn, 50 tbc
    Metadata:
      creation_time   : 2015-02-19 17:10:38
    Stream #0.1(und): Audio: aac, 48000 Hz, stereo, s16, 125 kb/s
    Metadata:
      creation_time   : 2015-02-19 17:10:38
Incompatible pixel format 'yuvj420p' for codec 'mpeg4', auto-selecting format 'yuv420p'
[buffer @ 0x22a3420] w:3840 h:2160 pixfmt:yuvj420p
[scale @ 0x22a3ce0] w:3840 h:2160 fmt:yuvj420p -> w:1920 h:1080 fmt:yuv420p flags:0x4
Output #0, mp4, to '1-short.mp4':
  Metadata:
    major_brand     : mp42
    minor_version   : 1
    compatible_brands: mp42avc1
    creation_time   : 2015-02-19 17:10:38
    encoder         : Lavf53.21.1
    Stream #0.0(und): Video: mpeg4, yuv420p, 1920x1080 [PAR 1:1 DAR 16:9], q=2-31, 200 kb/s, 25 tbn, 25 tbc
    Metadata:
      creation_time   : 2015-02-19 17:10:38
    Stream #0.1(und): Audio: libvo_aacenc, 48000 Hz, stereo, s16, 200 kb/s
    Metadata:
      creation_time   : 2015-02-19 17:10:38
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
Press ctrl-c to stop encoding
frame=  125 fps=  6 q=31.0 Lsize=     968kB time=5.00 bitrate=1586.7kbits/s    
video:842kB audio:123kB global headers:0kB muxing overhead 0.421047%

Wiem z doświadczenia, że ​​ffmpeg jest doskonałym narzędziem, więc muszę jakoś popsuć opcje / parametry ...

W jaki sposób mogę to zrobić?

Lara Michaels
źródło
Pokaż pełne, kompletne wyjście konsoli z twojego polecenia. Możesz po prostu zakodować krótki segment, więc dodaj, -t 10aby uzyskać wynik 10 sekund. Dlaczego chcesz zmniejszyć skalę? Jaki jest przypadek użycia skalowanego wyjścia? Te informacje pomogą mi udzielić dokładniejszej odpowiedzi.
llogan
@ LordNeckbeard Właśnie dodałem dane wyjściowe konsoli. Chcę zmniejszyć skalę, aby łatwiej udostępniać te klipy osobom, które ze mną pracują.
Lara Michaels,
1
Nie zapomnij -c:a copy, ponieważ nie chcesz lub nie musisz ponownie kodować strumienia audio. Służy -map 0do kopiowania metadanych rozdziałów lub innych rzeczy. (ffmpeg domyślnie przyjmuje tylko 1 vid + 1 aud.)
Peter Cordes
1
Ponadto -sws_flags lanczos+print_infoużyje lepszego skalowania algo niż domyślny (myślę, że dwuliniowy). Odpowiedź stlb obejmuje część procesu kodowania wideo.
Peter Cordes
2
@PeterCordes Ewentualnie scale=1920:-2:flags=lanczos. Chciałem również wspomnieć -2o skali for w mojej nieistniejącej odpowiedzi. Dla tych, którzy nie wiedzą, możesz ustawić -2szerokość lub wysokość, a to automatycznie zapewni poprawną wartość, zachowując proporcje i dzieląc wartość przez 2 (wymagane przez libx264 dla wyjść yuv420p).
llogan

Odpowiedzi:

17

Domyślne ustawienia ffmpeg są bardzo niskiej jakości, a ponieważ nie określasz żadnych kodeków ani parametrów jakości, to po prostu używam wartości domyślnych (nie wiem, dlaczego deweloperzy tego nie naprawiają, ponieważ generuje wiele pytań na forach wszędzie).

Edycja : ustawienia domyślne są teraz całkiem rozsądne. Dzięki najnowszej wersji ffmpeg nie musisz określać niczego więcej niż pliki wejściowe i wyjściowe, aby uzyskać dobre użyteczne wyniki. Możesz oczywiście dostosować się do pragnienia twojego serca.

Spróbuj dodać -c:v libx264 -crf 20 -preset slowdo polecenia.

  • -c:v libx264 każe mu używać kodera libx264,
  • crf 20 używa kwantyzatora Constant Rate Factor (co paradoksalnie oznacza zmienną przepływność, ale stałą jakość) o wartości 20 (całkiem dobra jakość; niższa jest lepsza jakość / większe pliki, wyższa jest szybsza / mniejsza),
  • slowustawiony jest skrótem dla pęczek ustawień kodera Oznacza to, że stawia się nieco więcej wysiłku w to niż domyślny (średnia).

Możesz dostosować te ustawienia, zapoznaj się z instrukcją kodowania h.264, aby dowiedzieć się, jakie pokrętła pokręcać.

A jeśli używasz audio w obecnej postaci, dodaj c:a copy. Spowoduje to wykonanie prostej kopii strumienia audio bez ponownego kodowania.

dźgnięcie
źródło
Domyślne ustawienia zależą od enkodera. libx264 jest zwykle używany domyślnie do wyjścia MP4 i zapewnia dobrą jakość wydruku bez żadnych dodatkowych opcji, ale wersja ffmpeg w pytaniu wydaje się nie obsługiwać tego kodera i dlatego używa starożytnego kodera mpeg4produkującego wideo MPEG-4 część 2, i wartości domyślne były bardziej rozsądne w czasach świetności (np. 320 x 240 itd.).
llogan
Dobrze jest usłyszeć, że libx264 jest teraz domyślny.
stib
Powiedziałbym CRF 20 jest całkiem cholernie dobry. 18 jest funkcjonalnie bezstratny. Większość moich filmów
nagrywam o
Większość mojej pracy jest wyświetlana na urządzeniach odtwarzających pracujących lokalnie z karty SD. Nie muszę wiele optymalizować pod kątem rozmiaru, więc zostawiam jakość tak wysoką, jak to tylko możliwe. Zgadzam się, wybrałbym to, gdybym dostarczał przez Internet.
stib
To mi nie pomogło. Nadal mam blokową dziwność wszędzie tam, gdzie występuje ruch na filmie. CRF 18, ustawiony na wolny. 2,7k-> 1080p.
rewolf
0

Użyj avconv, jeśli chcesz:

avconv -i 4kfile.mp4 -s hd1080 -c:v libx264 -c:a copy fullhdfile.mp4
Guray Celik
źródło