No FFMPEG, qual é o método mais eficiente para redimensionar um vídeo?

2

Eu tenho uma grande coleção de arquivos de vídeo mkv e mp4 no formato 4: 3. Eu estou tentando redimensionar o maior deles, até um tamanho mais gerenciável de 640x480. Isso é em parte para economizar espaço em disco, mas também para torná-los mais fáceis de assistir em uma tela de laptop e consumir menos ciclos de processador para reproduzi-los.

Mas não encontrei um meio eficiente de redimensioná-los. Eu tenho tentado aderir de perto à codificação usada para o arquivo original, conforme relatado pelo MediaInfo (usando a opção x264opts para reproduzir as variáveis ​​relatadas pelo MediaInfo, onde elas diferem de uma predefinição padrão). Baseado na codificação de vídeo de 2 passagens.

Mas isso me deixa com um comando muito complexo para ffmpeg, mostrado abaixo. O que eu estou negligenciando? Existe uma linha de comando mais direta que eu possa usar com o ffmpeg, que ainda fará um bom trabalho ao reproduzir a codificação usada no arquivo de entrada?

::  Resize Image to 640x480 (e.g. 960x720 x 2/3)

::  Input File (WITH .ext)
SET input=video_960x720_320kbps.mkv

::  Resize from 960x720 to 640x480 (i.e. 960x720 x 2/3)

::  Resize Picture to 2/3rd
    SET multiply=2
    SET divide=3

::  Location of FFMPEG (64-bit)
SET ffmpeg="C:\Program Files\FFmpeg\ffmpeg.exe" -hide_banner -threads 1


::  *** MATCH INPUT FILE'S SETTINGS : Input file analysed by MediaInfo ***

::  **  Command Line : 2 Pass Encoding : 320 kbps x 2/3 + Headroom = 240 kbps : Input = MKV  **

::  Video - Advanced Video Codec (AVC), High@L5 - Constant Bitrate, Framerate defaults to Input file's framerate

::  Overwrite a Profile with the x264-params option
SET x264opts="ref=16:deblock=1,1,2:me_range=32:trellis=0:bframes=5:open_gop=0:min-keyint=300:keyint_min=23:bitrate=240:qpmin=12:qpmax=60:qpstep=10:threads=1"

SET mapping=-i "%input%" -itsoffset 0 -i "%input%"  -map 0:v -map 1:a  -copyts
SET options=-preset veryslow  -profile:v high -level 5 -x264-params %x264opts%  -pix_fmt yuv420p
SET command=%ffmpeg% %mapping% -c:v libx264 %options% -vf "scale=iw*%multiply%/%divide%:-1" -c:a copy  -sn  -map_metadata 0
%command% -y -pass 1 -flags global_header -f matroska nul  &&  %command% -pass 2 -flags global_header -movflags faststart "output_640x480_240kbps.mkv"
Ed999
fonte

Respostas:

2

Não há sentido " reproduzindo a codificação usada ". Isso é apenas informação histórica, e usar as mesmas configurações não resultará em uma codificação mais eficiente. Se você quiser diminuir a carga do processador, use um perfil mais baixo. refs=16 e bframes=5 fará exatamente o oposto de consome menos ciclos de processador . CRF single-pass fará, não há necessidade de dois modos de taxa de bit médio de passes.

Você também ingere a entrada duas vezes e aplica um deslocamento TS de 0 (!). Por quê?

ffmpeg -i in -vf scale=640:480:force_original_aspect_ratio=decrease,pad=640:480:(ow-iw)/2:(oh-ih)/2,setsar=1,format=yuv420p -c:v libx264 -crf 22 -profile:v main -c:a copy -sn -map_metadata 0 out.mkv

Você pode omitir o filtro de bloco se a entrada for exatamente 4: 3.

Se o tamanho resultante for muito grande, aumente o valor do CRF.

Gyan
fonte
Obrigado por responder. Talvez eu tenha me expressado mal: não estou tentando tornar o processo de recodificação mais eficiente. Eu só quero acabar com um arquivo menor, de modo que a reprodução usa menos recursos do que reproduzir o arquivo original muito maior. Eu estou tentando manter os parâmetros de codificação originais, para que o arquivo de saída seja mais parecido com o arquivo de entrada, em termos de qualidade; mas eu gostaria de simplificar a linha de comando do ffmpeg. Espero que exista uma maneira menos incômoda de expressar a linha de comando.
Ed999
Por exemplo, o ffmpeg pode fazer uso dos parâmetros originais codificados no arquivo de entrada? Atualmente estou obtendo essas manualmente, usando o MediaInfo para analisar o arquivo de entrada, modificando minha linha de comando.
Ed999
Estou usando o modo de 2 passagens porque minhas tentativas demonstram conclusivamente que obtenho melhor compactação - um arquivo de saída menor sempre - se eu usar a codificação de 2 passagens. Além disso, ao incluir um '-itsoffset' de 0, juntamente com as opções '-tscopy' e '-map', forço o arquivo de saída a espelhar todos os timestamps no arquivo de entrada, por mais estranho que seja o arquivo de entrada, e assim eu obtenho exatamente no arquivo de saída em sincronia - mas, é claro, se o arquivo de entrada estava fora de sincronia o que eu recebo é um exatamente arquivo de saída fora de sincronia! (Neste último caso, tenho a opção de omitir essas opções.)
Ed999
1
acabar com um arquivo menor - & gt; O tamanho do arquivo é apenas um dos determinantes da carga de recursos. E com suas configurações atuais, não a mais onerosa. refs = 16 é um colaborador muito maior. Em qualquer caso, para diminuir o tamanho do arquivo, aumente o CRF. reter os parâmetros originais de codificação - & gt; não é assim que os codificadores funcionam. Por um lado, sua fonte não é a mesma que a fonte original. Os resíduos de erro serão diferentes, então sua fixação de qp em x264opts poderá ser sub-ótima. Seu me_range pode ser desnecessariamente alto demais para uma codificação de segunda geração.
Gyan