Como posso usar o FFmpeg para diminuir a qualidade do vídeo H264, mas mantê-lo no formato H264?

8

Eu sou um noob completo para edição de vídeo, então me perdoe se eu pedir algo ridículo.

Estou recebendo videoclipes de uma caixa de gravador de decodificador. Os clipes são arquivos AVI:

Resolution: 1920 x 1080
Frames Per Second: 60
Video Format: ITU H.264
Audio Format: MPEG 1 Audio, Layer 3 (MP3)

A resolução e o FPS estão muito além do que eu preciso, então estou tentando executar um comando para reduzir as coisas:

ffmpeg -i highres.avi -r 30 -s 960x540 lowerres.avi

Isso foi bem-sucedido ao fornecer a resolução desejada, a taxa de quadros e o tamanho menor do arquivo, mas também degradou a qualidade muito mais do que eu esperava.

Eu olhei para o novo arquivo e descobri que, por algum motivo, o FFmpeg converteu o formato usado:

Video Format: FFmpeg MPEG-4
Audio Format: MPEG 1 Audio, Layer 2

Não está claro para mim por que ele não usaria os mesmos formatos de saída que os formatos de entrada. Eu tentei usar este comando para forçá-lo a usar o H.264:

ffmpeg -i highres.avi -r 30 -s 960x540 -f h264 lowerresforceh264.avi

Infelizmente, falhou com a seguinte saída:

ffmpeg version 0.7.3-4:0.7.3-0ubuntu0.11.10.1, Copyright (c) 2000-2011 the Libav developers
  built on Jan  4 2012 16:21:50 with gcc 4.6.1
  configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --enable-shared --disable-static
  WARNING: library configuration mismatch
  avutil      configuration: --extra-version='4:0.7.3ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-libopenjpeg --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdirac --enable-libmp3lame --enable-librtmp --enable-libx264 --enable-libxvid --enable-libvo-aacenc --enable-version3 --enable-libvo-amrwbenc --enable-version3 --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  avcodec     configuration: --extra-version='4:0.7.3ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-libopenjpeg --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdirac --enable-libmp3lame --enable-librtmp --enable-libx264 --enable-libxvid --enable-libvo-aacenc --enable-version3 --enable-libvo-amrwbenc --enable-version3 --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  avformat    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  avdevice    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  avfilter    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  swscale     configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  postproc    configuration: --extra-version='4:0.7.3-0ubuntu0.11.10.1' --arch=i386 --prefix=/usr --enable-vdpau --enable-bzlib --enable-libgsm --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvorbis --enable-pthreads --enable-zlib --enable-libvpx --enable-runtime-cpudetect --enable-vaapi --enable-gpl --enable-postproc --enable-swscale --enable-x11grab --enable-libdc1394 --shlibdir=/usr/lib/i686/cmov --cpu=i686 --enable-shared --disable-static --disable-ffmpeg --disable-ffplay
  libavutil    51.  7. 0 / 51.  7. 0
  libavcodec   53.  6. 0 / 53.  6. 0
  libavformat  53.  3. 0 / 53.  3. 0
  libavdevice  53.  0. 0 / 53.  0. 0
  libavfilter   2.  4. 0 /  2.  4. 0
  libswscale    2.  0. 0 /  2.  0. 0
  libpostproc  52.  0. 0 / 52.  0. 0
Input #0, avi, from 'highres.avi':
  Metadata:
    comment         : Quality_GOOD
    encoder         : Lavf52.64.2
    encoded_by      : AverMedia_c281_1.7.2
  Duration: 00:01:59.28, start: 0.000000, bitrate: 10263 kb/s
    Stream #0.0: Video: h264 (High), yuv420p, 1920x1080, 59.94 fps, 59.94 tbr, 59.94 tbn, 119.88 tbc
    Stream #0.1: Audio: mp3, 48000 Hz, stereo, s16, 128 kb/s
[buffer @ 0x8f438a0] w:1920 h:1080 pixfmt:yuv420p
[scale @ 0x8f431e0] w:1920 h:1080 fmt:yuv420p -> w:960 h:540 fmt:yuv420p flags:0x4
[libx264 @ 0x8f0fb40] broken ffmpeg default settings detected
[libx264 @ 0x8f0fb40] use an encoding preset (e.g. -vpre medium)
[libx264 @ 0x8f0fb40] preset usage: -vpre <speed> -vpre <profile>
[libx264 @ 0x8f0fb40] speed presets are listed in x264 --help
[libx264 @ 0x8f0fb40] profile is optional; x264 defaults to high
Output #0, h264, to 'lowerresforceh264.avi':
    Stream #0.0: Video: libx264, yuv420p, 960x540, q=2-31, 200 kb/s, 90k tbn, 30 tbc
Stream mapping:
  Stream #0.0 -> #0.0
Error while opening encoder for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height

Não sei por que não posso fazer isso. A execução de "ffmpeg -formats" listou o h264 como um que poderia ser usado para entrada e saída.

Se alguém pudesse me apontar na direção certa, eu agradeceria muito. Obrigado.

PS: Estou usando o FFmpeg versão 0.7.3-4: 0.7.3-0 no Ubuntu 11.10.

EDITAR

Encontrei uma solução para o uso de predefinições. Depois de procurar informações sobre predefinições, encontrei o seguinte tutorial discutindo-as:

http://juliensimon.blogspot.com/2009/01/howto-ffmpeg-x264-presets.html

Eu só precisava especificar o codec e a configuração adequada predefinida da seguinte forma:

ffmpeg -i highres.avi -r 30 -s 960x540 -vcodec libx264 -vpre medium lowerresforceh264vpremedium.avi

Eu ainda tenho alguns ajustes a fazer, mas é basicamente isso que eu queria. Obrigado.

BigBeagle
fonte
Certamente, algumas pessoas simplesmente querem saber como converter arquivos .avi do Avermedia .mp4 para reproduzir no Mountain Lion / Mavericks <pre> ffmpeg -i 140203-1229.avi -vcodec copy -acodec copy fromavermedia_cog.mp4 </pre>

Respostas:

3

Estou tentando ajudar. Primeiro, não entendo por que você está dizendo que o FFMPEG H.264 não é o formato de entrada?

Não conheço bem a linha de comando do FFMPEG (existe alguém que conhece?;)). Tem que haver um switch para codificação multipass. Eu sei que existem algumas predefinições internas que você provavelmente poderia usar e fazer quase certamente o que está buscando. Estes são normalmente chamados de predefinições x264 ou sintonia x264. Você consegue encontrar algo assim?

Zettt
fonte
Obrigado. Sua palestra sobre predefinições me ajudou a encontrar uma solução provável. Vou editar a postagem para mostrar o que fiz.
precisa saber é o seguinte
Ótima solução. Adicionado à minha coleção de trechos. Obrigado.
Zettt
2
@BigBeagle: Quando você encontrar uma resposta para sua pergunta, poderá publicá-la como resposta. A edição da sua pergunta é feita para fornecer mais clareza à pergunta. Pelo que entendi, as respostas estão na seção de respostas.
Nav
8

O ffmpeg removeu suas predefinições x264 para que a configuração -vpre não funcione mais.

Agora, eu tenho um script para converter arquivos de vídeo em um formato que meu celular possa suportar.

ffmpeg -i input.avi -sws_flags lanczos+accurate_rnd -vf "scale=320:240" -c:v libx264 -crf 20 -preset veryslow -profile:v main -tune fastdecode -c:a copy output.mkv

Vou explicar cada opção

-sws_flags lanczos+accurate_rnd essa opção é o algoritmo de redução de escala, lanczos é recomendado, pois produz o mínimo de artefatos sem bluring, mas é lento.

-vf "scale=..." é auto-explicativo, especifique a resolução de saída

-crf 20essa é a qualidade, 20 é uma boa configuração final de saída (não a use antes da edição), é uma qualidade constante e é a melhor opção quando o tamanho do arquivo não é reduzido e produzirá melhor qualidade no menor tamanho de arquivo do que qualquer outra coisa , caso contrário, use duas passagens para obter a qualidade máxima em um tamanho de arquivo específico (como a necessidade de ajustá-la em um CD ou DVD); a taxa de bits fixa (por exemplo -b 2000k) deve ser usada apenas durante a transmissão; um caso especial é '0', sem perdas e O intervalo dessa opção é de 1 (qualidade mais alta) a 50 (qualidade mais baixa).

Um bom teste para isso é executar a codificação com -crf 20, anote a taxa de bits e use-a como configuração -b para uma segunda versão do arquivo; ambos devem ter o mesmo tamanho, comparar os dois pela qualidade diferenças.

-preset veryslow isso escolhe quanto CPU você deseja usar, quanto mais lento, menor o tamanho do arquivo e a melhor qualidade.

-profile:v maineste é o perfil H.264 a ser usado. alto é o tamanho de arquivo mais eficiente, mas usa muita CPU para decodificar em comparação com outros formatos, sendo dito que é o mais popular, já que a maioria dos celulares tem um decodificador de hardware embutido e o flash player suporta, o meu não é necessário. use main.

-tune fastdecode meu celular não gosta de reproduzir os arquivos sem essa opção, mas geralmente isso pode ser deixado em branco ou definido como 'filme' para jogos de vídeo, a principal razão pela qual você usa isso é obter um pouco de qualidade extra.

E a última coisa que eu recomendo usar um formato de contêiner moderno .avi não foi projetado para conter o H.264 e, pelo que entendi, não há um padrão para armazenar o H.264 ou aumentar o arquivo com mais de 2 GB, a maioria das implementações é invasiva e propensa para ter problemas, use mkv ou mp4.

Daniel Hill
fonte
As predefinições para libx264 agora são especificadas por -presetcomo-preset slow
stib
-tune fastdecodedesabilita o desbloqueio e os quadros B e P ponderados, bem como o CABAC. Existem decodificadores que podem lidar com quadros B, mas não CABAC? Eu sugeriria -profile:v baseline, se você precisar direcionar decodificadores de hardware antigos. ( fastdecodepoderia ser útil se visar um decodificador de software em uma CPU lenta, mas não um decodificador de hardware.) Principal com quadros B, mas sem desbloqueio ou CABAC pode ou não parecer melhor do que a linha de base com desbloqueio. +1 por recomendar não-AVI para armazenar h.264. IIRC, o principal são os quadros B, mas sim o h.264 em avi não é bem padronizado e é hacky.
Peter Cordes
Eu chamaria -crf 20uma final alta. Você pode mudar isso para 22 ou até 24 e provavelmente ficará bem, a menos que esteja em movimento alto, como um evento esportivo.
usar o seguinte comando
2

Há algumas coisas a esclarecer:

  • Um formato não é um codec; você deseja obter um arquivo no formato avi com vídeo codificado com o codec h264 . Basta usar -vcodec libx264 e um nome de arquivo com .avi . O Ffmpeg deve reconhecer um formato olhando para uma extensão de arquivo, mas você também pode ser específico adicionando -f avi . Definitivamente, você não deseja usar o mpeg1, porque ele oferece uma qualidade pior que o mpeg2 ou ainda pior em comparação com o mpeg4, o que eu recomendo.
  • Seu problema era que o ffmpeg usava a menor qualidade possível porque você não especificou nenhuma. A opção -sameq raramente parece funcionar para mim. De fato, é muito difícil definir a taxa de bits manualmente. Adicione, por exemplo, -vb 3000k para obter um arquivo com taxa de bits de vídeo média de 3Mb / s, o que fornece uma qualidade muito boa. Eu acho que seria o suficiente para você ter 2Mb / s para a resolução mencionada.
  • A chave para diminuir o tamanho do arquivo não é a resolução, mas a taxa de bits mencionada acima. Prefiro manter a resolução original e apenas manipular a taxa de bits.
  • Eu acho que você também deseja manter o áudio sem conversão (portanto, sem perda de qualidade), então use -acodec copy .

Tente isto: ffmpeg -i highres.avi -acodec copy -vcodec libx264 -vb 2000k lowerres.avi

Piotr
fonte
4
A taxa de bits constante é a pior (em termos de qualidade versus tamanho) de todos os modos de controle de taxa em x264 e deve ser evitada. Use -crfpara definir um modo de qualidade constante.
usar o seguinte código