Recodificando a biblioteca de vídeos em x265 (HEVC) sem perda de qualidade


43

Estou tentando converter minha videoteca para o formato HEVC para ganhar espaço. Executei o seguinte comando em todos os arquivos de vídeo da minha biblioteca:

#!/bin/bash
for i in *.mp4;
do 
    #Output new files by prepending "X265" to the names
    avconv -i "$i" -c:v libx265 -c:a copy X265_"$i"
done

Agora, a maioria dos vídeos converte-se bem e a qualidade é a mesma de antes. No entanto, alguns vídeos de qualidade muito alta (por exemplo, uma impressão de filme de 5 GB) perdem a qualidade - o vídeo é todo pixelizado.

Não tenho certeza do que fazer neste caso. Preciso modificar o crfparâmetro na minha linha de comando? Ou alguma outra coisa?

O problema é que estou fazendo uma conversão em massa. Então, preciso de um método em que avconvajuste automaticamente qualquer parâmetro que precise de ajuste para cada vídeo.

UPDATE-1

Descobri que crfé o botão que preciso ajustar. O CRF padrão é 28. Para obter melhor qualidade, eu poderia usar algo menor que 28. Por exemplo:

avconv -i input.mp4 -c:v libx265 -x265-params crf=23 -c:a copy output.mp4

No entanto, o problema é que, para alguns vídeos, o valor de CRF 28 é bom o suficiente, enquanto para alguns vídeos é necessário um CRF menor. Isso é algo que eu tenho que verificar manualmente convertendo pequenas seções dos vídeos grandes. Mas na conversão em massa, como eu verificaria cada vídeo manualmente? Existe alguma maneira de avconvajustar a CRF de acordo com a entrada de vídeo de maneira inteligente?

UPDATE-2

Descobri que há uma --losslessopção no x265: http://x265.readthedocs.org/en/default/lossless.html .

No entanto, não sei como usá-lo corretamente. Tentei usá-lo da seguinte maneira, mas produziu resultados opostos (o vídeo ficou ainda mais pixelizado):

avconv -i input.mp4 -c:v libx265 -x265-params lossless -c:a copy output.mp4

1
--losslessde fato, pode ampliar o arquivo, se ele decodificar o codec anteriormente com perdas e, em seguida, incluir o que decodificou sem perdas. A qualidade permanecerá exatamente igual à entrada.
Golar Ramblar

2
Se suas fontes estão codificadas com perdas (o que é mais provável), o que você está tentando obter é impossível. Qualquer transcodificação que não seja sem perda prejudicará ainda mais a qualidade (mesmo que não seja imediatamente visível para você) e se você converter de com perda para sem perda, obterá tamanhos de arquivo maiores.
Sarge Borsch

Respostas:


58

Pela minha própria experiência, se você não quer absolutamente nenhuma perda de qualidade, - sem perda é o que você está procurando.

Não tenho certeza, avconvmas o comando digitado parece idêntico ao que eu faço FFmpeg. Em FFmpegvocê pode passar o parâmetro assim:

ffmpeg -i INPUT.mkv -c:v libx265 -preset ultrafast -x265-params lossless=1 OUTPUT.mkv

A maioria dos x265comutadores (opções sem valor) pode ser especificada como esta (exceto aqueles somente da CLI, esses são usados ​​apenas com o x265binário diretamente).

Com isso fora do caminho, gostaria de compartilhar minha experiência com a x265codificação. Para a maioria dos vídeos (seja WMV, MPEG ou AVC / H.264) eu uso crf=23. x265decide o restante dos parâmetros e geralmente faz um trabalho suficientemente bom.

No entanto, muitas vezes antes de me comprometer a transcodificar um vídeo por inteiro, testo minhas configurações convertendo uma pequena parte do vídeo em questão. Aqui está um exemplo, suponha que um arquivo mkv com fluxo 0 seja vídeo, fluxo 1 seja áudio DTS e fluxo 2 seja uma legenda:

ffmpeg -hide_banner \
-ss 0 \
-i "INPUT.mkv" \
-attach "COVER.jpg" \
-map_metadata 0 \
-map_chapters 0 \
-metadata title="TITLE" \
-map 0:0 -metadata:s:v:0 language=eng \
-map 0:1 -metadata:s:a:0 language=eng -metadata:s:a:0 title="Surround 5.1 (DTS)" \
-map 0:2 -metadata:s:s:0 language=eng -metadata:s:s:0 title="English" \
-metadata:s:t:0 filename="Cover.jpg" -metadata:s:t:0 mimetype="image/jpeg" \
-c:v libx265 -preset ultrafast -x265-params \
crf=22:qcomp=0.8:aq-mode=1:aq_strength=1.0:qg-size=16:psy-rd=0.7:psy-rdoq=5.0:rdoq-level=1:merange=44 \
-c:a copy \
-c:s copy \
-t 120 \
"OUTPUT.HEVC.DTS.Sample.mkv"

Observe que a linha do sinal de barras invertidas quebra em um comando longo; eu faço isso para me ajudar a acompanhar vários bits de uma entrada CLI complexa. Antes de explicar linha por linha, a parte em que você converte apenas uma pequena parte de um vídeo é a segunda e a segunda última linha: -ss 0significa procurar 0 segundo antes de começar a decodificar a entrada e -t 120parar de escrever na saída depois de 120 segundos. Você também pode usar os formatos de hora hh: mm: ss ou hh: mm: ss.sss.

Agora, linha por linha:

  1. -hide_bannerimpede FFmpegde mostrar informações de compilação no início. Eu só não quero vê-lo quando rolar para cima no console;
  2. -ss 0procura 0 segundo antes de começar a decodificar a entrada. Observe que, se esse parâmetro for fornecido após o arquivo de entrada e antes do arquivo de saída, ele se tornará uma opção de saída e informará ffmpegpara decodificar e ignorar a entrada até x segundos e, em seguida, comece a gravar na saída. Como opção de entrada, é menos preciso (porque a busca não é precisa na maioria dos formatos de contêiner), mas não leva tempo. Como opção de saída, é muito preciso, mas leva bastante tempo para decodificar todo o fluxo antes do tempo especificado e, para fins de teste, você não deseja perder tempo;
  3. -i "INPUT.mkv": Especifique o arquivo de entrada;
  4. -attach "COVER.jpg": Anexe uma capa (imagem em miniatura, pôster, o que for) à saída. A arte da capa geralmente é mostrada nos exploradores de arquivos;
  5. -map_metadata 0: Copie todos e quaisquer metadados da entrada 0, que no exemplo é apenas a entrada;
  6. -map_chapters 0: Copie as informações do capítulo (se houver) da entrada 0;
  7. -metadata title="TITLE": Defina o título do vídeo;
  8. -map 0:0 ...: Mapeie o fluxo 0 da entrada 0, o que significa que queremos que o primeiro fluxo da entrada seja gravado na saída. Como esse fluxo é um fluxo de vídeo, é o primeiro fluxo de vídeo na saída , daí o especificador de fluxo :s:v:0. Defina sua tag de idioma para inglês;
  9. -map 0:1 ...: Semelhante à linha 8, mapeie o segundo fluxo (áudio DTS) e defina seu idioma e título (para facilitar a identificação na escolha dos players);
  10. -map 0:2 ...: Semelhante à linha 9, exceto que este fluxo é uma legenda;
  11. -metadata:s:t:0 ...: Defina metadados para a capa. Isso é necessário para o formato de contêiner MKV;
  12. -c:v libx265 ...: Opções de codec de vídeo. É tanto tempo que eu quebrei em duas linhas. Essa configuração é boa para vídeo bluray de alta qualidade (1080p) com bandas mínimas em gradiente (que x265 é uma porcaria). Provavelmente é um exagero para DVDs, programas de TV e vídeos por telefone. Essa configuração é principalmente roubada desta postagem do Doom9 ;
  13. crf=22:...: Continuação dos parâmetros do codec de vídeo. Veja a postagem do fórum mencionada acima;
  14. -c:a copy: Copiar em áudio;
  15. -c:s copy: Copiar sobre legendas;
  16. -t 120: Pare de gravar na saída após 120 segundos, o que fornece um clipe de 2 minutos para a visualização da qualidade da trancoding;
  17. "OUTPUT.HEVC.DTS.Sample.mkv": Nome do arquivo de saída. Eu codifico meus nomes de arquivos com o codec de vídeo e o codec de áudio principal.

Ufa. Esta é a minha primeira resposta, por isso, se houver algo que eu perdi, por favor deixe um comentário. Não sou especialista em produção de vídeo, sou apenas um cara com preguiça de assistir a um filme colocando o disco no aparelho.

PS. Talvez essa pergunta pertença a outro lugar, pois não está fortemente relacionada ao Unix e Linux.


2
Exatamente o que eu estava procurando! Boa cobertura de opções. Você sabe se o ffmpeg vai recusar c:s copyse não houver conteúdo de legendas?
Elder Geek

1
@ElderGeek Não, o ffmpeg só dirá algo se essa opção tiver algum efeito.
Yifeng Mu

Essa opção gera o menor tamanho de arquivo possível para a codificação h265 verdadeiramente sem perdas? Caso contrário, existe uma maneira de fazer isso?
Buffer Over Leia

1
@TheBitByte Não acho que exista um nível de compactação sem perdas no h265. Para a opção sem compressão, é apenas --lossless. Procurei em vão uma conversão sem perdas de h264 para h265, e o que aprendi me diz que é matematicamente impossível.
Yifeng Mu

1
Você realmente deve editar o comando que contém a --losslessopção de sair desta resposta, porque, como resposta a essa pergunta, parece que você está dizendo que é uma compactação sem perdas, o que é enganoso.
Hashim

8

Recentemente, passei pelo problema de transcodificar todo o meu catálogo de vídeos para o HEVC. Eu uso https://github.com/FallingSnow/h265ize com as seguintes configurações.

h265ize -v -m medium -q 20 -x --no-sao --aq-mode 3 --delete --stats

-v - Saída detalhada -
m média - Velocidade média de codificação (menor qualidade superior, qualquer coisa mais lenta que eu acho que não compensa o tempo / qualidade dif)
-q 20 - a CRF usada, 20 é semelhante a 18 em x264, mas ei. Isto é para conteúdo 1080p (90% da minha TV), eu costumo usar 22 nos meus filmes em 4K -
x - Usar comandos centrais definidos x265 - no
-sao desativa Deslocamento adaptativo de amostra (melhora a velocidade de codificação)
- modo aq 3 - use a Quantização Adaptativa com variação automática, ajuda os códigos de 8 bits, especialmente em áreas escuras, interrompe a maior parte das faixas que podem acontecer (às custas do tempo de codificação)
--delete - substitui o arquivo de codificação pelo arquivo codificado (teste antes de usar este) )
--stats - Escreva as estatísticas em um arquivo csv na raiz do caminho a partir do qual você executou.

As velocidades de codificação estão em torno de 30 fps (para a maioria das coisas em 1080p) no meu equipamento. Dual Xeon E5 2687W v2, mas forço o processo FFMPEG a não usar o primeiro lado de um dos processadores (é o meu servidor Plex, por isso, certifique-se de que haja sobrecarga para transcodificação, se necessário na reprodução, etc.)

Sim, demorou um tempo para converter a maior parte, e agora eu tenho uma tarefa agendada que é executada duas vezes por dia para codificar o material desse dia para x265.

A economia de espaço tem sido enorme. Minha SAN inicial estava em uso de 20 TB, agora é cerca de 12, mas obviamente também foi adicionada com 6 meses a mais de conteúdo.

Também comecei a transcodificar todos os meus filmes, no entanto, esse é um processo contínuo, pois preciso identificar os níveis de qualidade (Radarr felizmente rotula muito bem) e usar uma das três configurações de transcodificação:

-m slower -q 18 -x --no-sao --aq-mode 3para 720p transcodifica
-m medium -q 20 -x --no-sao --aq-mode 3para 1080p
-m medium -q 22 -x --no-saopara 2160p

Espero que ajude algumas pessoas. Grite se alguém precisar de uma mão para configurar tudo. E antes de codificar tudo para x265, pense em reprodução, se o cliente não suportar x265 nativo, a transição pode ser cara em termos de CPU e qualidade.


Com o x265 2.4 e posterior (com as novas tabelas lambda que fornecem codificações mais nítidas), o SAO geralmente é bom para a qualidade por taxa de bits. Ele ainda mancha um pouco, mas reduz outros artefatos o suficiente para valer a pena.
Peter Cordes

-q 20não é CRF 20, é controle constante de controle de qualidade . O padrão e o modo recomendado, CRF, levanta a QP alguns em cenas de alta complexidade para que ele não gastar demasiado muitos bits em cenas que são muito difíceis de codificar. (Se você quiser mais perto do QP uniforme, aumente qcompdo padrão 0,6 para talvez 0,7 ou 0,8. Mais perto de 1,0 está mais próximo do CQP.)
Peter Cordes

3

A sintaxe correta para ativar o modo sem perdas para o codificador x265 no ffmpeg é -x265-params lossless=1(você precisa anexar =1).

No entanto, para codificação sem perdas, existem melhores opções de codec. Descobri testando que o FFV1 compacta muito melhor (tamanho do arquivo = ~ 80% de x265) pelo menos em alguns tipos de vídeo (se as melhores configurações forem escolhidas para ambos os codecs). E também funciona mais rápido e (AFAIK) não é onerado por patentes. Ou seja, é superior ao H.265 sem perdas em todos os aspectos para arquivamento de vídeo.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.