Konwertuj AVI (Xvid) na MP4 (H.264) zachowując tę ​​samą jakość

48

Chcę skompresować plik AVI do MP4 przy użyciu kodeka h.264. Nie mogłem uzyskać tej samej jakości. Jak mogę to skompresować?

Oryginalne wideo:

Oryginalny ekran wideo:

Dane wyjściowe konsoli FFmpeg ( ffmpeg -i input.avi):

FFmpeg version SVN-r26402, Copyright (c) 2000-2011 the FFmpeg developers
  built on Dec 28 2012 10:03:40 with gcc 4.4.6 20120305 (Red Hat 4.4.6-4)
  configuration: --enable-shared --enable-gpl --enable-version3 --enable-nonfree                                                                                         --enable-pthreads --enable-x11grab --enable-libopencore-amrnb --enable-libopenc                                                                                        ore-amrwb --enable-libdc1394 --enable-libfaac --enable-libmp3lame --enable-libop                                                                                        enjpeg --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libx264                                                                                         --enable-libxvid --enable-zlib --enable-filter=drawtext
  libavutil     50.36. 0 / 50.36. 0
  libavcore      0.16. 1 /  0.16. 1
  libavcodec    52.108. 0 / 52.108. 0
  libavformat   52.93. 0 / 52.93. 0
  libavdevice   52. 2. 3 / 52. 2. 3
  libavfilter    1.74. 0 /  1.74. 0
  libswscale     0.12. 0 /  0.12. 0
[mpeg4 @ 0x626b50] Invalid and inefficient vfw-avi packed B frames detected
Input #0, avi, from 'input.avi':
  Metadata:
    encoder         : VirtualDubMod 1.5.10.2 (build 2542/release)
  Duration: 01:32:38.13, start: 0.000000, bitrate: 2094 kb/s
    Stream #0.0: Video: mpeg4, yuv420p, 720x304 [PAR 1:1 DAR 45:19], 23.98 tbr,                                                                                         23.98 tbn, 23.98 tbc
    Stream #0.1: Audio: ac3, 44100 Hz, 5.1, s16, 384 kb/s
At least one output file must be specified

Test 1

Komenda FFmpeg:

ffmpeg -i input.avi -vcodec libx264 -vpre lossless_slow -crf 25 -acodec libfaac -threads 0 -t 60 1.mp4

Ekran testu 1:

Dane wyjściowe konsoli FFmpeg ( ffmpeg -i 1.mp4)

    FFmpeg version SVN-r26402, Copyright (c) 2000-2011 the FFmpeg developers
  built on Dec 28 2012 10:03:40 with gcc 4.4.6 20120305 (Red Hat 4.4.6-4)
  configuration: --enable-shared --enable-gpl --enable-version3 --enable-nonfree --enable-pthreads --enable-x11grab --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libdc1394 --enable-libfaac --enable-libmp3lame --enable-libopenjpeg --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-zlib --enable-filter=drawtext
  libavutil     50.36. 0 / 50.36. 0
  libavcore      0.16. 1 /  0.16. 1
  libavcodec    52.108. 0 / 52.108. 0
  libavformat   52.93. 0 / 52.93. 0
  libavdevice   52. 2. 3 / 52. 2. 3
  libavfilter    1.74. 0 /  1.74. 0
  libswscale     0.12. 0 /  0.12. 0
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '1.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:01:00.01, start: 0.000000, bitrate: 618 kb/s
    Stream #0.0(und): Video: h264, yuv420p, 720x304 [PAR 1:1 DAR 45:19], 437 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #0.1(und): Audio: aac, 44100 Hz, 5.1, s16, 176 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
At least one output file must be specified

Test 2

Komenda FFmpeg:

ffmpeg -y -i input.avi -pass 1 -vcodec libx264 -vpre slow -b 2000k -threads 0 -t 60 -f mp4 -an -y /dev/null
ffmpeg -y -i input.avi -pass 2 -vcodec libx264 -vpre slow -b 2000k -threads 0 -t 60 -acodec libfaac -ab 128k -ac 2 2.mp4

Ekran testu 2:

Dane wyjściowe konsoli FFmpeg ( ffmpeg -i 2.mp4)

FFmpeg version SVN-r26402, Copyright (c) 2000-2011 the FFmpeg developers
  built on Dec 28 2012 10:03:40 with gcc 4.4.6 20120305 (Red Hat 4.4.6-4)
  configuration: --enable-shared --enable-gpl --enable-version3 --enable-nonfree --enable-pthreads --enable-x11grab --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libdc1394 --enable-libfaac --enable-libmp3lame --enable-libopenjpeg --enable-libspeex --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-zlib --enable-filter=drawtext
  libavutil     50.36. 0 / 50.36. 0
  libavcore      0.16. 1 /  0.16. 1
  libavcodec    52.108. 0 / 52.108. 0
  libavformat   52.93. 0 / 52.93. 0
  libavdevice   52. 2. 3 / 52. 2. 3
  libavfilter    1.74. 0 /  1.74. 0
  libswscale     0.12. 0 /  0.12. 0
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '2.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf52.93.0
  Duration: 00:01:00.01, start: 0.000000, bitrate: 1097 kb/s
    Stream #0.0(und): Video: h264, yuv420p, 720x304 [PAR 1:1 DAR 45:19], 1028 kb/s, 23.98 fps, 23.98 tbr, 24k tbn, 47.95 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
    Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16, 63 kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
At least one output file must be specified
Ahmet KAPIKIRAN
źródło

Odpowiedzi:

60

Przede wszystkim zainstaluj nowszą wersję FFmpeg - pobierz statyczną kompilację ze strony pobierania .

Użycie vpreustawień wstępnych (które jest sposobem na ustawienie wartości domyślnych dla ustawień ffmpeg , a nie ustawień enkodera) nie jest tak naprawdę konieczne; zwykle chcesz skorzystać z -presetopcji zdefiniowanych przez kodery.

Powody, dla których otrzymujesz niską jakość wyjściową, są następujące, odpowiednio w dwóch przypadkach:

  1. W pierwszym przypadku użyjesz crf 25współczynnika stałej szybkości , który da ci gorszą jakość niż domyślny dla enkodera x264 (czyli 23). CRF kontroluje jakość. Spróbuj ustawić niższy CRF, może 20, 18 itd. Tutaj niższy oznacza lepszą jakość, ale zwiększy rozmiar pliku. Zmiana 6 w CRF daje z grubsza dwa razy połowę pierwotnej średniej przepływności.

    Musisz ustawić niższy CRF ze względu na utratę generacji . Kodujesz coś, co już zostało zakodowane, więc ponownie wyrzucasz informacje wizualne. To nigdy nie jest dobre, ale jeśli musisz, musisz ustawić wyższą jakość, aby nie usunąć zbyt dużej ilości informacji z wejściowego wideo.

  2. W drugim przypadku próbujesz ustawić stałą szybkość transmisji 2 MBit / s. Twoje wideo wejściowe ma mniej więcej tę samą szybkość transmisji. Teraz x264 zapewnia znacznie lepszą jakość obrazu niż koder wizualny MPEG-4 dla tej samej przepływności, ale ze względu na utratę generacji, możesz chcieć użyć jeszcze wyższej przepływności niż oryginał - w przeciwnym razie kompresujesz za dużo informacji.

    Ponadto ciągłe kodowanie przepływności może spowodować, że niektóre fragmenty będą wyglądały dobrze, ale inne części filmu będą wyglądały gorzej. Jeśli nie pozwolisz enkoderowi swobodnie wybierać ilość bitów, na które chce on wydać, poświęcisz jakość kosztem znajomości docelowego rozmiaru pliku.

    x264 ma tryb stałej przepływności, ale jest uważany za gorszy od innych metod kodowania. W rzeczywistości kodowanie dwuprzebiegowe nie ma na celu osiągnięcia optymalnej jakości, więc zrób to.

Biorąc to wszystko pod uwagę, spróbuj wykonać następujące czynności:

ffmpeg -i input.avi -c:v libx264 -crf 19 -preset slow -c:a libfdk_aac -b:a 192k -ac 2 out.mp4

Jeśli libfdk_aacnie jest dostępny, użyj tego zamiast:

ffmpeg -i input.avi -c:v libx264 -crf 19 -preset slow -c:a aac -b:a 192k -ac 2 out.mp4

Głównym pokrętłem kontroli jakości będzie twoje ustawienie CRF. Eksperymentuj z tym i użyj niższej wartości, jeśli potrzebujesz lepszej jakości.

Możesz także wybrać veryslowustawienie wstępne, które zapewni lepszą kompresję, ale kodowanie oczywiście potrwa dłużej.

Jeśli nie możesz uzyskać pliku o przyzwoitej jakości w rozsądnym rozmiarze, nie masz szczęścia. Lepiej zachowaj oryginalny plik w niezmienionej postaci, bez ponownego kodowania. Nie ma magicznego narzędzia „utrzymywania tej samej jakości”, gdy kompresujesz coś, co już zostało skompresowane.

slhck
źródło
Jeśli Twój film ma mniejszy rozmiar po konwersji z dwoma przejściami, musisz określić wyższą szybkość transmisji. Spróbuj -b:v 3Mlub więcej; ale zalecałbym użycie metody CRF zamiast wariantu dwuprzebiegowego.
slhck
10
@AhmetKa Innym rozwiązaniem jest po prostu ponownie MUX strumieni ze zbiornika do pojemnika MP4 AVI: ffmpeg -i input.avi -c copy -map 0 output.mp4. Nie ma ponownego kodowania, więc nie ma utraty jakości.
llogan 28.12.12
1
@AhmetKa Powinienem wspomnieć, że multipleksowanie nie zawsze będzie działać, jeśli format pojemnika wyjściowego nie obsługuje formatów wejściowych. Zobacz Porównanie formatów kontenerów, aby uzyskać ogólne pojęcie o tym, co działa.
llogan 28.12.12
Witaj ponownie @slhck Crf nie jest poprawnie. Szybkość transmisji, szerokość, wysokość itp. Czy mogę obliczyć?
Ahmet KAPIKIRAN
3
@hyde Wolisz -c:a aac -strict experimentalzamiast libvo_aacenc, ponieważ zapewnia lepszą jakość.
slhck