fredericopissarra Posted December 30, 2019 at 12:34 AM Share Posted December 30, 2019 at 12:34 AM Tenho uma antiga TV Sony Bravia de 42"... Tive certos problemas com ela em relação à vídeos que posso "tocar", via pendrive: Se o vídeo têm um bitrate muito alto, nada feito; Se o vídeo não estiver nos containers MPEG-1, MPEG-2, MPEG-4 ou WMV, nada feito; Se o vídeo estiver num aspect ratio diferente de 16/9, a imagem distorce. O último parece ser verdadeiro para todas as TVs em que testei o player de vídeo embutido nelas. Aparentemente o SAR (source aspect ratio) e DAR (display aspect ratio) não são respeitados se o DAR não for 16/9 ou 4/3. ffmpeg ao resgate: Bem... eis a linha de comando para conversão de um vídeo qualquer para um formato que pode ser "universal" para todas as TVs e, ainda assim, criar o menor arquivo possível, sem perda de qualidade significativa... O primeiro passo é calcular o bitrate correto para o vídeo. Isso pode ser feito com a seguinte equação: Como exemplo, para um vídeo em 1280x720 @ 29.97 fps, o bitrate ficará em 1.998 Mb/s. O outro passo é determinar a resolução do vídeo original. Podemos usar o próprio ffmpeg para isso, mas prefiro usar o mediainfo: $ mediainfo --inform='Video;%Width%' videoin.mp4 $ mediainfo --inform='Video;%Height%' videoin.mp4 Se, escalonando o vídeo obtivermos o tamanho vertical menor que a resolução máxima vertical, estamos no caminho certo. Por exemplo... suponha que tenhamos um vídeo com uma resolução maluca como 1316x638. Se quisermos, aqui, uma resolução HD (1280x720) o vídeo terá que ser escalonado para 1280x620: $ bc <<< 'scale=3; 1280/(1316/638)' 620.756 Como o valor é par, ignoramos a parte fracionária... Agora, estamos prontos para recodificar o vídeo: $ ffmpeg -hwaccel cuvid -i videoin.mp4 \ -c:v h264_nvenc -r ntsc \ -maxrate 1.998M -bufsize 1.998M -b:v 1.998M \ -vf 'scale=1280:620:flags=lanczos,pad=1280:720:0:(720-620)/2:black,setdar=16/9' \ -c:a ac3 -b:a 128k -ac 2 -ar 44.1k -async 1 \ videoout.mp4 Aqui uso os CUDA cores da placa de vídeo nVidia para decodificar os frames (-hwaccel cuvid) e o encoder da placa de vídeo para recodificá-los (-c:v h264_nvenc). Ajusto o bitrate fixo (constant bitrate) para 1.998 Mb/s, ajusto o framerate para o padrão NTSC (30000/1001 fps). Uso o filtro de escalonamento dos frames para ajustar a resolução que quero (1280x620), usando o método 'lanczos' de extrapolação para minimizar os artefatos que podem surgir no escalonamento e depois uso o filtro 'pad' para preencher o espaço de 100 pixels com um fundo preto, colocando a imagem exatamente no meio desse grande quadro de 1280x720... Por fim, ajusto os aspect ratios SAR e DAR, ajustanto o DAR para 16/9. Você pode deixar que o próprio ffmpeg calcule o escalonamento vertical modificando o filtro scale para 'scale=1280:-1:flags=lanczos', mas se o tamanho vertical for ímpar o ffmpeg pode reclamar. Prefiro eu mesmo ajustar o valor desejado, mesmo porque ele será usado no filtro pad... Só tenha certeza que o tamanho vertical será menor ou igual a 720 (no caso da resolução 1280x720)... No que tange o áudio, minha TV não suporta AAC, então uso AC3 e acho o bitrate de 128 kb/s suficiente, mas converto o sampling rate para 44.1 kHz para diminuir o stream de áudio, bem como garanto que a saída seja 'stereo' (-ac 2)... Como estou modificando o framerate do vídeo, aplico também o filtro de áudio de sincronização a cada 1 segundo (-async 1). O arquivo videoout.mp4 conterá o vídeo no container MPEG-4 (o ffmpeg pega pela extensão), usando codecs h264 e ac3 e estará na resolução 1280x720 com DAR setado em 16/9... Vídeo "pequeno" (com essa técnica consigo um vídeo com tamanho de 28% do vídeo original, dependendo do caso), que tocará sem distorções e excelente qualidade. Se você gosta de assistir vídeos em FullHD (1920x1080), basta modificar os cálculos de acordo. PS: Se você não tem uma placa nVidia pode tentar usar um decoder VAAPI (Intel) ou não usar a aceleração (retire o -hwaccel cuvid, acima)... Ainda, terá que modificar o encoder para 'libx264', ao invés de 'h264_nvenc'. Link to comment Share on other sites More sharing options...
fredericopissarra Posted December 31, 2019 at 11:05 AM Author Share Posted December 31, 2019 at 11:05 AM Existia um erro no texto com relação ao uso dos filtros scale e pad, em sequência... Corrigi o texto... O problema era que as pseudo-variáveis ih e iw do filtro pad levam em consideração a altura e comprimento, respectivamente, do vídeo de entrada (não do vídeo escalonado - ao que parece)... daí, substituí pelos valores fixos ao invés de usar as variáveis. Link to comment Share on other sites More sharing options...
fredericopissarra Posted December 31, 2019 at 12:40 PM Author Share Posted December 31, 2019 at 12:40 PM Considerações sobre aspect rations comuns. São 2: WideScreen (16/9) e LetterBox (4:3). O segundo é o aspecto das antigas TVs com CRTs. Uma resolução de 640x480 tem aspecto 4:3, por exemplo. Se formos fazer padding sempre para Widescreen isso tem que ser levado em consideração: No caso de um vídeo widescreen, mas com aspecto diferente de 16:9 (resolução não padrão), barras horizontais devem ser colocadas. Mas, note que elas não consumirão muito do espaço útil da tela (a não ser que a resolução vertical seja mesmo pequena). O escalonamento do vídeo original deve ser feito de forma que o width seja o mesmo do espaço do padding... No caso do formato letterbox (4:3), barras verticais devem ser adicionadas (a centralização do vídeo será feita horizontalmente e o vídeo original deve ser escalonado para fazer com que height seja o mesmo do espaço do padding)... Mas, note que muito do espaço útil é perdido: Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.