Redimensionando vídeos com ffmpeg / avconv para caber em players de tamanho estático

53

Eu tenho um player de vídeo html 5 com 700px de largura e 400px de altura. Estou tentando usar avconv para usar o ffmpeg para redimensionar (mantendo a proporção) e certificando-se de que ele se encaixe no meu player.

A entrada pode ser um arquivo de qualquer tamanho, então eu preciso redimensionar os maiores, mas centralizar os menores com barras pretas. Até agora, tentei: -s e -aspect , vi pad sendo usado com a opção -vf , mas não entendi como funciona o suficiente para conseguir o que preciso.

Esta é uma ideia aproximada do que preciso. Não tenho certeza se é possível. É quase como a largura máxima / max do CSS. Eu percebo que isso pode ser apenas uma confusão de palavras, mas se alguém entender o que eu estou falando, eu agradeceria a ajuda, obrigado.

comando avconv:

avconv -y -i control.avi -vcodec libx264 -b 2000k -bufsize 20M -acodec aac -strict experimental -ar 44100 -ab 256k bigbuck_out.mp4

    
por Jamie Taylor 06.02.2013 / 10:20

3 respostas

35

Um método simples é usar a opção force_original_aspect_ratio no filtro de escala .


Imagemoriginal.Representaumvídeodeproporçãodeaspectode640x480,4:3.

Nessesexemplos,aimagemoriginalserádimensionadaparacaberemumasaídadeproporçãode16:9,preservandoaproporçãooriginal.Parafazerisso,vocêpode:

Pillarbox ou letterbox


imagemPillarboxed.Encaixeumaentradade640x480(4:3)emumasaídade1280x720(16:9).

ffmpeg-iinput-vf"scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output
  • Isso aumentará a imagem. Se você quiser evitar o upscaling, veja o exemplo abaixo.

  • O letterboxing ocorre em vez disso, se a proporção da entrada for maior que a taxa de proporção da saída. Por exemplo, uma entrada com uma proporção de 2,35: 1 ajustada em uma saída de 16: 9 resultará em letterboxing.

O mesmo que acima, mas sem upscaling


<6>640x480(4:3)entradaem1280x720(16:9)saídasemupscaling.

ffmpeg-iinput-vf"scale='min(1280,iw)':min'(720,ih)':force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output

Recorte


Imagemrecortada.Proporçãodeentradade4:3,relaçãodeaspectodesaídade16:9.

ffmpeg-iinput-vf"scale=1280:720:force_original_aspect_ratio=increase,crop=1280:720" output
    
por 18.10.2016 / 20:51
59

Aqui está o comando que adiciona pilar ou letterbox para uma largura de saída fixa. É um pouco longo, mas você terá que especificar o preenchimento de alguma forma.

Primeiro, no seu shell, defina a largura e a altura da saída:

width=700
height=400

Em seguida, execute o comando:

ffmpeg -i in.mp4 -filter:v "scale=iw*min($width/iw\,$height/ih):ih*min($width/iw\,$height/ih), pad=$width:$height:($width-iw*min($width/iw\,$height/ih))/2:($height-ih*min($width/iw\,$height/ih))/2" out.mp4

Isso é reduzido ao essencial necessário para redimensionar e preencher o teclado - adicione suas outras opções de vídeo e áudio como achar melhor. Observe que os números de width e height precisam ser divisíveis por 2 para funcionar na maioria dos codecs.

Aqui está a explicação do que está acontecendo:

  • Escala:
    • Primeiro, precisamos descobrir se escalar por largura ou altura.
    • Para fazer isso, dividimos a largura de saída pela largura de entrada e a altura de saída pela altura de entrada. Isso nos dará os fatores de escala para cada dimensão.
    • Em seguida, verificamos qual é menor (com min() ) e escolhemos apenas esse fator para redimensionar.
    • Finalmente, multiplicamos a largura e a altura de entrada por esse fator ( iw*min(…):ih*min(…) ).
  • preenchimento:
    • $width:$height é a largura e altura de saída
    • Para descobrir onde colocar o vídeo resultante, precisamos subtrair a largura escalonada da largura máxima de saída e a altura escalonada da altura máxima de saída.
    • As larguras e alturas escaladas são as expressões do filtro scale .
    • dividimos o deslocamento resultante por 2 para adicionar bordas em ambos os lados.
por 06.02.2013 / 15:36
8

Parece-me que você precisa fazer isso em três etapas:

  1. Verifique a proporção da entrada
  2. Redimensione vídeos com um DAR > 7/4 de largura (altere a largura para 700 e dimensione a altura para manter a proporção) e dimensione os com DAR < 7/4 em altura
  3. Pad o vídeo para que ele se encaixe no espaço 700: 400.

O FFmpeg / avconv pode fazer o escalonamento / preenchimento com filtros de vídeo em uma única etapa, transcodificando apenas uma vez. Por exemplo, para obter um vídeo de 16: 9, dimensione-o em largura e, em seguida, coloque os resultados em caixa de correio:

ffmpeg -i input.avi -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
-c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k output.mp4

... mas para o primeiro passo (detectar o formato e compará-lo com o 7: 4 que você precisa) você terá que usar um script de algum tipo.

ffprobe input.avi 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0-9]*\)].*//p'

... você obterá a proporção do vídeo, que será semelhante a "16: 9" ou "4: 3". Em um script bash, eu usaria algo como:

#!/bin/bash

##  Get the aspect ratio in the form x/y
dar=$(ffprobe test0.mp4 2>&1 | sed -n '/Video:/s/.*DAR \([0-9]*:[0:9]*\)].*//p' | sed 's|:|/|')
##  use bc to do x/y*100 (bash can't handle floats)
DAR=$(bc <<< 'scale=2; $dar*100')

##  ${DAR%.00} will remove the trailing .00 left by bc
if [ ${DAR%.00} -ge 175 ]; then
    ffmpeg -i "$1" -filter:v 'scale=700:-1,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
else
    ffmpeg -i "$1" -filter:v 'scale=-1:400,pad=700:400:(ow-iw)/2:(oh-ih)/2' \
    -c:v libx264 -b:v 2000k -bufsize 20M -c:a aac -strict experimental -ar 44100 -b:a 256k "${1%.*}.mp4
fi

exit 0

Obviamente, você terá que adaptá-lo às suas necessidades.

    
por 06.02.2013 / 15:31