domingo, 6 de novembro de 2011

Shell script para gerar arquivos xvid com áudio mp3

Olá pessoal. Neste post vou colocar um script que eu mesmo fiz para fazer encode de arquivos de vídeo no formato avi com o codec de vídeo xvid e áudio mp3.

Faço essa conversão porque tenho dois probleminhas: 1 - meu dvd é velhinho e roda arquivos com legendas, mas não arquivos muito grandes - nesse caso tenho que reduzir o bitrate. 2 - meu xbox 360 não carrega legendas externas (srt) de vídeos e só roda xvid.

O software que eu uso para encode é o mencoder, o SO é GNU/Linux distro Slackware 13.37. O mplayer foi compilado por mim. Versão:

MPlayer SVN-r34308-4.5.2 (C) 2000-2011 MPlayer Team


Meu mplayer foi compilado com as bibliotecas adicionais xvid e libmp3lame, mas para encode do xvid eu estou usando lavc. Para audio estou usando mp3lame.

Antes de postar o script, vale lembrar que é minha primeira aventura de script shell para automatizar alguma tarefa minha, então o código pode não ser o melhor possível. Dicas são muito bem vindas!

Abaixo o script:


#!/bin/bash

function usage {
echo "uso: video-encode -v video -l legenda -ab audio-bitrate -vb video-bitrate [-vol volume] [-sim] -o arqiuvo-output"
}

function error_exit {
echo "$1" 1>&2
exit 1
}

while [ "$1" != "" ]; do
case $1 in
-v )
shift
video=$1
;;
-l )
shift
legenda=$1
;;
-vb )
shift
vb=$1
;;
-ab )
shift
ab=$1
;;
-o )
shift
output=$1
;;
-vol )
shift
vol=":vol=$1"
;;
-sim )
sim=true
;;
* )
usage
error_exit "Parâmetro não reconhecido: $1"
;;
esac
shift
done


# Verificando se o arquivo de vídeo é válido
test -n "$video" -a -f "$video" || error_exit "Arquivo inválido: $video"

# Verificando se o arquivo de legenda (se informado) é válido
test -z "$legenda" -o -f "$legenda" || error_exit "Legenda inválida: $legenda"

# Verificando se o arquivo de legenda (se informado) está no format utf-8
test -f "$legenda" -a $(file -bi "$legenda" | sed 's/\(.*\)charset=//') == "utf-8" || error_exit "A legenda não está no formato utf-8: $legenda"

# Tenta criar o arquivo de saída
touch "$output" > /dev/null 2>&1 || error_exit "Erro ao criar o arquivo de saída: $output"

echo
echo "******************************************************"
echo "Ambiente"
echo "video: $video"
echo "legenda: $legenda"
echo "vbitrate: $vb"
echo "abitrate: $ab"
echo "******************************************************"
echo

function echo_exec {
echo $1
echo $2

if [ -z $sim ]; then
eval $2 || error_exit "Operação cancelada"
fi
}

cmd="mencoder \"$video\" -sub \"$legenda\" -ovc lavc -lavcopts vcodec=mpeg4:vpass=1 -oac mp3lame -ffourcc XVID -o /dev/null"
echo_exec "Encoding 2-pass - parte 1" "$cmd"

cmd="mencoder \"$video\" -sub \"$legenda\" -ovc lavc -lavcopts vcodec=mpeg4:vpass=2:vbitrate=$vb -oac mp3lame -lameopts abr:br=$ab$vol -ffourcc XVID -o \"$output\" -utf8"
echo_exec "Encoding 2-pass - parte 2" "$cmd"


Explicando em termos gerais, o script aceita os seguintes parâmetros de linha de comando:
-v arquivo de vídeo origem
-l arquivo de legendas
-vb bitrate do vídeo
-ab bitrate do áudio
-o arquivo de output
-vol volume do áudio - opcional (para aplicar ganho - pode distorcer)
-sim modo simulação (na verdade só exibe os comandos na tela, sem executar nada)

Estou usando o método 2pass do mencoder porque achei que tive videos de melhor performance assim.

Alguns pontos a melhorar:

O mencoder está sempre usando -utf8, por isso precisa do arquivo de legendas em formato utf-8. Vou tentar criar uma função para converter automaticamente o arquivo para utf-8 caso não seja - atualmente o programa retorna um erro e não prossegue.

Antes de rodar o programa é preciso saber de antemão o bitrate de áudio e vídeo que serão usados. Vou tentar identificar no arquivo de origem e dar suporte ao usuário entrar com as informações através de prompt.

Tornar a seleção da legenda opcional. Embora era minha intenção, ainda não está funcionando.

Acabei de executar o script e na minha máquina está funcionando (bem, na nossa máquina sempre funciona, né...), então espero que ajude outras pessoas da mesma forma que me ajuda aqui.

Grande abraço a todos e até a próxima.

3 comentários:

  1. Parabéns! Esse post esta excelente, Felipe!
    Obrigado por dividir isso!
    Estou precisando gerar um MPEG-4 que rode como DivX ou Xvid ...
    Vc acha que com esse seu exemplo eu consigo?
    De qqr forma, mto obrigado!

    ResponderExcluir
  2. Esse meu script faz exatamente isso. Ele vai gerar um arquivo avi com vídeo mpeg4 xvid e áudio mp3.

    Vou tentar hospedar ele em algum lugar para ter acesso mais fácil, e fazer com que a legenda seja opcional.

    Muito obrigado pela por acessar o estação zn e fico feliz que o conteúdo tenha agradado.

    ResponderExcluir

 
BlogBlogs.Com.Br