Converti AVI (Xvid) in MP4 (H.264) mantenendo la stessa qualità


48

Voglio comprimere un file AVI in MP4 usando un codec h.264. Non ho potuto ottenere la stessa qualità. Come posso comprimerlo?

Video originale:

Schermo video originale:

Uscita console 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

Comando FFmpeg:

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

Schermata Test 1:

Uscita console 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

Comando 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

Schermata Test 2:

Uscita console 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

Risposte:


60

Prima di tutto, installa una versione più recente di FFmpeg: prendi una build statica dalla pagina di download .

L'uso dei vprepreset (che è un modo per impostare valori predefiniti per le impostazioni di ffmpeg , non per le impostazioni dell'encoder) non è realmente necessario; di solito si desidera utilizzare le -presetopzioni definite dagli encoder.

I motivi per cui si ottiene una bassa qualità di output sono i seguenti, rispettivamente per i due casi:

  1. Nel primo caso che usi crf 25, un fattore di frequenza costante che ti darà una qualità peggiore rispetto al valore predefinito per l'encoder x264 (che è 23). Il CRF controlla la qualità. Prova a impostare un CRF inferiore, forse 20, 18, ecc. Qui, inferiore significa migliore qualità, ma aumenterà la dimensione del file. Un cambio di 6 nel CRF ti dà il doppio / metà del bitrate medio originale, approssimativamente parlando.

    Dovrai impostare un CRF inferiore a causa della perdita di generazione . Stai codificando qualcosa che era già codificato, quindi stai di nuovo gettando via informazioni visive. Non va mai bene, ma se è necessario, dovrai impostare una qualità superiore per non rimuovere troppe informazioni dal video di input.

  2. Nel secondo caso stai cercando di impostare un bit rate costante di 2 MBit / s. Il video in ingresso ha approssimativamente la stessa velocità in bit. Ora, x264 offre una qualità visiva molto migliore rispetto a un codificatore MPEG-4 Visual per lo stesso bitrate, ma a causa della perdita di generazione, di nuovo, potresti voler utilizzare un bitrate ancora più alto rispetto all'originale, altrimenti finirai per comprimere troppe informazioni.

    Inoltre, la codifica bitrate costante potrebbe far apparire bene alcuni passaggi, ma altre parti del video potrebbero apparire peggiori. Se non lasci che l'encoder scelga liberamente la quantità di bit che vuole spendere per qualcosa, sacrificherai la qualità a spese della conoscenza della dimensione del file di destinazione.

    x264 ha una modalità di velocità in bit costante, ma è considerata inferiore agli altri metodi di codifica. In realtà, la codifica a due passaggi non ha lo scopo di indirizzare la qualità ottimale, quindi graffialo.

Detto questo, prova qualcosa nel modo seguente:

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

Se libfdk_aacnon è disponibile, utilizzare questo invece:

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

La manopola di controllo qualità principale sarà la tua impostazione CRF. Sperimenta con questo e usa un valore inferiore se hai bisogno di una migliore qualità.

Puoi anche scegliere il veryslowpreset, che ti darà una migliore compressione, ma la codifica richiederà ovviamente più tempo.

Se non riesci a ottenere un file di qualità decente con una dimensione del file ragionevole, sei sfortunato. Meglio mantenere il file originale così com'è, senza ricodificare. Non c'è magico strumento "mantenendo la stessa qualità" quando comprimi qualcosa che è già compresso.


Se il tuo video ha dimensioni inferiori dopo la conversione con due passaggi, devi specificare un bitrate più elevato. Prova -b:v 3Mo più; ma consiglierei di usare il metodo CRF invece della variante a due passaggi.
slhck,

10
@AhmetKa Un'altra opzione è quella semplicemente ri-MUX i flussi da contenitore AVI a MP4 contenitore: ffmpeg -i input.avi -c copy -map 0 output.mp4. Non c'è ricodifica, quindi non c'è perdita di qualità.
llogan,

1
@AhmetKa Avrei dovuto menzionare che il muxing non funzionerà sempre se il formato del contenitore di output non supporta i formati multimediali dell'input. Vedi Confronto dei formati contenitore per avere un'idea generale di ciò che funziona.
Llogan,

Ciao di nuovo @slhck Crf non è corretto. Bitrate, larghezza, altezza, ecc. Posso calcolare?
Ahmet KAPIKIRAN,

3
@hyde Dovresti preferire -c:a aac -strict experimentalinvece che libvo_aacenc, perché offre una migliore qualità.
Slhck,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.