Definir tamanho máximo para vídeo

Iniciado por brunosantos, 17 de Outubro de 2017, 21:29

tópico anterior - próximo tópico

brunosantos

Pessoal, já pesquisei no Google e vi que é possível diminuir o tamanho de um vídeo sem muita perda de qualidade, minha pergunta agora é:
Tem como definir o tamanho que o vídeo poderá ter? Por exemplo: um vídeo de 16MB fazer algo para que ele tenha exatamente 12MB sem fazer corte
Sei que terei perda de qualidade
Petição para que a SiS libere os drivers para linux:
http://www.petitiononline.com/sislinux/

druidaobelix

#1
É possível reduzir e fixar o tamanho de forma razoavelmente aproximada de um arquivo de vídeo usando o pacote ffmpeg.
Uma das formas é alterando para menor o bitrate do arquivo.

O pacote ffmpeg evidentemente precisa estar instalado:

sudo apt install ffmpeg

Para essa finalidade o processamento ffmpeg possui a sintaxe geral:

ffmpeg -i input.mp4 -b bitrate output.mp4

A essa fórmula geral pode ser necessário acrescentar os codecs utilizados e outros parâmetros dependendo do que se queira obter.

Informações gerais sobre um arquivo de vídeo se pode obter através do ffmpeg usando o comando:

ffmpeg -i nome_do_arquivo_video

exemplos:

ffmpeg -i video.mp4

ffmpeg -i Trio_Sinha_Flor-Forro_Floreado-Sr_Brasil-221115.mp4

ffmpeg -i "Marcus Viana-Raya Hilal-Transfônica Orkestra-SOB-O-SOL-em_Árabe.mp4"

O 'bitrate' do comando acima mencionado corresponde a um valor numérico, que pode ser expresso em kbps (kilobit ou mil bits por segundo).

De uma forma geral o bitrate que corresponde ao tamanho de arquivo final desejado é o quociente da divisão entre o tamanho desejado medido em bits e o tempo de duração do arquivo de vídeo medido em segundos.

Assim sendo:

Citarnovo bitrate = tamanho desejado do arquivo de saída / tempo de duração do vídeo

O tempo de duração do arquivo de vídeo é fácil de ser obtido, bastando usar qualquer player de vídeo (totem, vlc, etc)  e dele capturar a informação que servirá de denominador na fórmula acima ou ainda usando o ffmpeg -i antes mencionado.

Além dessa forma manual e empírica de obtenção do tempo de duração do arquivo de vídeo, também se pode utilizar o próprio ffmpeg para obter essa informação de maneira mais direta e precisa da seguinte forma:

ffprobe -v error -select_streams v:0  -show_entries stream=duration -of default=nk=1:nw=1 nome_arquivo_entrada

Dessa forma, exemplificando:

Um arquivo original que possui o tamanho de 28,1 MB, o que corresponde a 28.107.356 bytes ou 28.107 Kbytes e que possui um bitrate original de 2269 kbps, se quer que o arquivo de saída que se pretende obter seja de 20MB (uma redução aproximada de 30%), então se faz:

tamanho desejado do arquivo de saída=20*1000*8 = 160.000

O ffmpeg utiliza o sistema internacional de unidades (SI), também conhecido como sistema comercial de unidades de medida, então os prefixos métricos são expressos em 1000 e não em 1024 do sistema binário.

Se o tempo de duração apurado desse arquivo de vídeo for, por exemplo, de 1 minuto e 39 e 8 décimos de segundos, ou seja, de 99 segundos, então o novo bitrate alvo será:

160.000 / 99.08 =  1615 kbps (aproximados)

Esse é o valor que deverá ser levado para aquele primeiro comando mencionado no início deste post, ficando dessa forma:

ffmpeg -i input.mp4 -b 1615k output.mp4

onde evidentemente input.mp4 se substitui pelo nome concreto do arquivo de entrada e output.mp4 pelo nome do arquivo que se deseja na saída do processamento.

Se um maior grau de aproximação for desejável se pode descontar desse valor o bitrate que corresponde ao áudio integrado no arquivo containner, uma vez que ele ocupa certo espaço (geralmente não muito significativo, notadamente para arquivos de vídeo grandes), obtendo-se então o novo bitrate alvo líquido a ser atingido.

O bitrate do arquivo de áudio embutido se pode obter através do ffmpeg fazendo:

ffprobe -v error -select_streams a:0  -show_entries stream=bit_rate -of default=nk=1:nw=1 nome_do_arquivo_entrada

O valor do bitrate que se obtiver desse comando se divide por 1000 e então se desconta o resultado daquele valor alvo antes obtido, dessa forma se obtendo o bitrate líquido necessário para atingir o tamanho alvo desejado do arquivo de saída.

No exemplo, supondo que o resultado para o bitrate de áudio seja:

bitrate de áudio = 125.639 / 1000 = 125

Apurando-se então o bitrate líquido necessário mediante a subtração entre os dois valores:

bitrate líquido necessário = 1615 - 125 = 1490 kbps

Logo, esse novo valor de bitrate líquido é o que será levado para o comando de redimensionamento do arquivo de entrada:

ffmpeg -i input.mp4 -b 1490k output.mp4

O tamanho do arquivo de saída que se obtém é um valor aproximado àquele estipulado como alvo, pois como um arquivo de vídeo é, desde sempre, composto de inúmeros frames (=fotogramas) é utilizado um critério médio de redução de bits em cada frame, cuja soma irá compor o arquivo final, porém o número não é exatamente preciso, embora muito aproximado para arquivos suficientemente grandes. Arquivos pequenos, exatamente pela pequena amostragem, tendem a apresentar uma variação maior entre o desejado e o realmente obtido.

Há outras formas de obter esse redimensionamento de arquivo de vídeo ainda através do ffmpeg mediante a utilização do parâmetro crf (Constant Rate Factor), mas que não está aqui abordado.

Note que o foco do que aqui se aborda é o cálculo do bitrate necessário e não o comando final propriamente dito, pois esse, dependendo do tipo de arquivo que entrada que se quer manipular e com qual finalidade, pode requerer tais e quais parâmetros, especialmente definição de codecs, assunto esse que não é objeto destas considerações.

Não sou especialista no segmento audiovisual e na verdade muito pouco concretamente conheço sobre essas técnicas, os eventuais usos são apenas amadorísticos, se tanto, além do que também não me é uma área de interesse mais direto, certamente haverá pessoal melhor qualificado aqui no Fórum, verdadeiramente profissional, que poderá adicionar informações relevantes sobre arquivos audiovisuais, além do que Fóruns realmente especializados nesse segmento talvez sejam uma melhor opção do que este Fórum, cuja temática central é sistema operacional, para obter informações técnicas mais precisas e detalhadas.

Na essência é isso.

www.arredondar.org.br
Vencedor Desafio de Impacto Social Google 2016!
Você também pode participar e fazer a diferença.

druidaobelix

#2
O simples script a seguir, batizado de videosize.sh, sem nenhum pretensão, procura automatizar esse processo mencionado no post anterior, deverá dar conta do recado.

O script não foi exaustivamente testado (na verdade só com arquivos mp4) e não possui sofisticação de consistências preliminares que um bom programa deve ter, enfim, é apenas uma roteirização do que antes dito e eventualmente pode facilitar o trabalho.

Note especialmente que o comando final de redimensionamento do arquivo de entrada circunstancialmente deverá ser modificado para acrescentar parâmetros e codecs necessários ao processamento.

Na execução do script preferencialmente o arquivo de entrada deverá estar no mesmo diretório local do script.

A execução pede a sintaxe:

./videosize.sh <nome_do_arquivo_de_entrada> <tamanho desejado do arquivo de saída>

O tamanho desejado do arquivo de saída deverá ser informado em MB.

O ponto e a barra antes do nome do script é o padrão de execução local de scripts.

Por exemplo:

./videosize.sh video.mp4 15

./videosize.sh Trio_Sinha_Flor-Forro_Floreado-Sr_Brasil-221115.mp4 20

./videosize.sh "Marcus Viana-Raya Hilal-Transfônica Orkestra-SOB-O-SOL-em_Árabe.mp4" 135

Nos exemplos acima os números 15, 20 e 135 seriam o tamanho desejado do arquivo de saída, em MB.

Como é habitual, as "aspas" envolvendo o nome de arquivo deverá ser usada quando existir espaços no nome.
www.arredondar.org.br
Vencedor Desafio de Impacto Social Google 2016!
Você também pode participar e fazer a diferença.

druidaobelix

#3
Esse o videosize.sh


#!/bin/sh

#UbuntuForum-BR
#tópico: https://ubuntuforum-br.org/index.php?topic=122341.msg672520#msg672520

#Redimensiona arquivo de vídeo para o tamanho desejado alterando o bitrate


#verifica se foram informados os parâmetros necesssários

if [ -z "$1" ] || [ -z "$2" ];
then
echo "Os parâmetros necessários não foram informados."

echo "Uso: videosize.sh <nome do arquivo de entrada> <tamanho alvo em MB>"

echo "exemplo: ./videosize.sh video.mp4 20"

echo "video.mp4 é  o nome do arquivo de vídeo de entrada"

echo "20 é a medida em MB (megabyte) que se quer para o arquivo de saída"

echo "Calcula o bitrate necessário ao vídeo para atingir o tamanho alvo especificado."

exit 1
fi

#Registra a data e hora do início da tarefa

INICIO=$(date)
echo "tarefa iniciada em:" >> videosize.txt
echo $INICIO >> videosize.txt
echo >> videosize.txt


#Calcula a duração do arquivo em segundos

TIMETOTAL="`ffprobe -v error -select_streams v:0  -show_entries stream=duration -of default=nk=1:nw=1 "$1"`" ;

echo "Duração do vídeo em segundos:" $TIMETOTAL

#Calcula o tamanho do arquivo alvo desejado em bit

echo "Tamanho alvo do arquivo de saída em MB - MegaByte:" $2

SIZEALVO_MB=$2

SIZEALVO_BIT=$((SIZEALVO_MB*1000*8))

echo "Tamanho alvo do arquivo de saída em bits:" $SIZEALVO_BIT


#Calcula o bitrate primário para atingir o tamanho do arquivo alvo

BITRATEPRIMARIO=$( echo $SIZEALVO_BIT / $TIMETOTAL | bc ) ;

echo "Bitrate primário para atingir o alvo:" $BITRATEPRIMARIO


#Calcula em kb o bitrate do arquivo de audio incorporado no arquivo containner

BITRATEAUDIO="`ffprobe -v error -select_streams a:0  -show_entries stream=bit_rate -of default=nk=1:nw=1 "$1"`" ;

echo "Bitrate do áudio em bits:" $BITRATEAUDIO

BITRATEAUDIO_KB=$((BITRATEAUDIO/1000))

echo "Bitrate do áudio em KB:" $BITRATEAUDIO_KB

#Calcula o bitrate líquido para atingir o tamanho do arquivo alvo
#descontando do bitrate primário o bitrate do arquivo de áudio

BITRATENEW=$(($BITRATEPRIMARIO - $BITRATEAUDIO_KB))

echo "Bitrate líquido para atingir o alvo (sem audio):" $BITRATENEW

#Faz o redimensionamento do arquivo de vídeo
#o parâmetro -strict -2 pode ser necessário
#o arquivo de saída será sempre videoout.mp4

ffmpeg -i "$1" -c:v libx264 -preset veryslow -b:v "$BITRATENEW"k -strict -2 videoout.mp4

#registra data e hora do término da tarefa

TERMINO=$(date)
echo
echo "tarefa terminada em:" >> videosize.txt
echo $TERMINO >> videosize.txt
echo >> videosize.txt

#reporta na tela data e hora do início e fim da tarefa

echo "Duração da tarefa de redimensionamento do vídeo"

echo "Início:     " $INICIO
echo "Término:" $TERMINO


echo
echo "=============="
echo

echo Foram digitados $# parâmetros. São eles: $*.

echo O primeiro parâmetro foi: $1

echo O segundo parâmetro foi: $2

echo O nome do script é: $0



Basta copiar o conteúdo para um arquivo texto e salvar.

Não esquecer que precisa atribuir permissão de execução ao script.

chmod +x videosize.sh

Se quiser baixar o script já pronto:

https://drive.google.com/file/d/0B4-_QQ0rcvfTQlBMTFVtVFdzdHc/view?usp=sharing


www.arredondar.org.br
Vencedor Desafio de Impacto Social Google 2016!
Você também pode participar e fazer a diferença.

druidaobelix

Como última consideração, o redimensionamento de arquivos de vídeo pode ser um trabalho longo e demorado, dependendo do tamanho e complexidade do arquivo de entrada, além do que exigirá o máximo da máquina, especialmente da cpu, notadamente em computadores mais antigos e com menor poder de processamento, que por conseguinte certamente irá aquecer.

Assim sendo, se o caso, fique atento à possibilidade de superaquecimento, é sempre bom ter instalado algum forma de monitoramento de temperatura para que se tenha uma visão mais concreta da execução da tarefa.

Nesse sentido pode ajudar:

sudo apt install psensor

Esse acima se pode acrescentar na barra superior um applet, além de possuir uma interface gráfica.

ou ainda:

sudo apt install lm-sensors

Esse último possibilita um acompanhamento por linha de comando.
www.arredondar.org.br
Vencedor Desafio de Impacto Social Google 2016!
Você também pode participar e fazer a diferença.