sábado, 19 de outubro de 2013

Usando o FFMPEG (FFPLAY) como player de streams HLS

HLS, ou HTTP Live Streaming, formato criado para a Apple para exibição de vídeo ao vivo no iOS e que vem sendo aos poucos sendo adaptada por outras plataformas (infelizmente ainda mal implementado no Android) exige um bocado de malabarismo para quem queira trabalhar com ele. Até mesmo para assistir os streams no computador enquanto trabalha.

Se você usa Mac, não é complicado. O QuickTime X tem suporte nativo ao HLS, basta abrir a URL com M3U8 nele. Nos outros sistemas, especialmente Windows, a coisa complica. O FFMPEG pode ser uma boa solução.

O FFMPEG, em alguns builds, vem com outras duas ferramentas, o FFPROBE e FFPLAY. A primeira serve de ferramenta de diagnóstico para arquivos. A segunda serve justamente para assistir conteúdo utilizando o engine do FFMPEG. E como nas últimas versões (atualmente estamos na 1.2.1) os suporte a HLS como formato de entrada evoluiu muito ele pode ser um player bem útil.

Basta chamar na linha de comando ffmpeg http://a.url.do/seu.stream/playlist.m3u8 Simples e prático.

domingo, 13 de outubro de 2013

Instalando o mais recente FFMPEG no Ubuntu 12.10

(Adaptado de: "Install FFMPEG on Ubuntu From Source" e "Making use of /usr/local/lib")

Tenho um VPS com Ubuntu 12.10 e precisava usá-lo para fazer remotamente conversões de formatos através do FFMPEG. O problema é que as distribuições oficiais via apt-get install ffmpeg não instalam realmente a última versão e sim uma versão modificada do 0.6 apenas para manter compatibilidade com outros programas. Como usar então as últimas versões do aplicativo nesse sistema, ou ainda, como utilizar outras bibliotecas não incluídas por padrão? Compilando do código-fonte. Para os não tão iniciados no mundo Linux (eu incluso), aqui vai um registro do caminho das pedras:

Comece fazendo a limpeza

Retire todas as dependências previamente instaladas via apt-get para evitar conflitos:

sudo apt-get remove ffmpeg x264 libav-tools libvpx-dev libx264-dev yasm

PS: Caso precise da biblioteca libfaac lembre-se de adicionar o repositório multiverse. Leia mais detalhes aqui

Instale as dependências

sudo apt-get update

sudo apt-get -y install autoconf build-essential checkinstall git libass-dev libfaac-dev libgpac-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev librtmp-dev libtheora-dev libtool libvorbis-dev pkg-config texi2html zlib1g-dev

Instalando os pacotes

Yasm

cd

wget http://www.tortall.net/projects/yasm/releases/yasm-1.2.0.tar.gz

tar xzvf yasm-1.2.0.tar.gz

cd yasm-1.2.0

./configure

make

sudo checkinstall --pkgname=yasm --pkgversion="1.2.0" --backup=no --deldoc=yes --fstrans=no --default

make install

x264

cd

git clone --depth 1 git://git.videolan.org/x264

cd x264

./configure --enable-static

make

sudo checkinstall --pkgname=x264 --pkgversion="3:$(./version.sh | awk -F'[" ]' '/POINT/{print $4"+git"$5}')" --backup=no --deldoc=yes --fstrans=no --default

make install

fdk-aac

cd

git clone --depth 1 git://github.com/mstorsjo/fdk-aac.git

cd fdk-aac

autoreconf -fiv

./configure --disable-shared

make

sudo checkinstall --pkgname=fdk-aac --pkgversion="$(date +%Y%m%d%H%M)-git" --backup=no --deldoc=yes --fstrans=no --default

make install

libvpx

cd

git clone --depth 1 http://git.chromium.org/webm/libvpx.git

cd libvpx

./configure --disable-examples --disable-unit-tests

make

sudo checkinstall --pkgname=libvpx --pkgversion="1:$(date +%Y%m%d%H%M)-git" --backup=no --deldoc=yes --fstrans=no --default

make install

E finalmente, o FFMPEG em si

cd

git clone --depth 1 git://source.ffmpeg.org/ffmpeg

cd ffmpeg

./configure --enable-gpl --enable-libass --enable-libfaac --enable-libfdk-aac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librtmp --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-nonfree --enable-version3

make

sudo checkinstall --pkgname=ffmpeg --pkgversion="7:$(date +%Y%m%d%H%M)-git" --backup=no --deldoc=yes --fstrans=no --default

make install

hash -r

Pronto!

Ué, e esse erro "undefined reference to `x264(...)"?"

É um problema que pode acontecer por referências erradas à biblioteca do x264. Tente:

Edite o arquivo /etc/ld.so.conf e adicione a linha "/usr/local/lib"

Execute "sudo ldconfig"

Continue a instalação do FFMPEG novamente a partir do 'make'"

ERROR: libvpx decoder version must be >=0.9.1

cd ~/libvpx

make clean

git pull

./configure

make

sudo checkinstall --pkgname=libvpx --pkgversion="$(date +%Y%m%d%H%M)-git" --backup=no --default --deldoc=yes

http://stackoverflow.com/questions/14899290/error-libvpx-decoder-version-must-be-0-9-1

sábado, 12 de outubro de 2013

Publicando um stream Flash no Original Livestream.com

Uma capacidade muito interessante do FFMPEG é de poder enviar o resultado final da codificação em forma de streaming para outro computador ou servidor, inclusive no formato RTMP, usado por servidores como o Flash Media Server ou Wowza Server. Sobre essas capacidades falarei mais a fundo numa próxima oportunidade.

O que me levou a fazer esse post é uma dor de cabeça que eu tive durante um bom tempo. Uso um serviço de streaming chamado Livestream, e no seu serviço original (não confundir com o novo Livestream, uma plataforma tecnológica bem diferente) é possível enviar o stream através de programas como Wirecast e Flash Live Encoder, que usam o protocolo RTMP. Ou seja, em tese deveria funcionar. Mas no meu computador não conseguia realizar conexão.

O curioso é que com outros servidores, como o Wowza, eu conseguia. Demorei um certo tempo para descobrir a questão. E acho que agora matei a charada.

Há um certo tempo o FFMPEG permite a publicação de streams através do comando -f rtmp://servidor/app/caminho, mas graças a uma implantação de parte da biblioteca do librtmp, vinda do projeto rtmpdump. Note bem: parte.

Ao tentar usar a URL do Livestream, que utiliza vários parâmetros para autenticação (rtmp://publish.livestream.com/mogulus/[canal]/username=[usuario]/password=[senha]/isAutoLive=true) o parser padrão dessa parte da biblioteca se confundia e acessava o caminho errado. E não é possível passar os parâmetros corretamente.

Tá, e como resolvo isso?

Ao compilar o FFMPEG para esse trabalho, exija as legítimas Havaianas certifique-se que o comando ./configure tenha também o parâmetro --enable-librtmp***, além dos demais parâmetros que você deseje para o FFMPEG. Assim você garante que o FFMPEG será compilado usando a biblioteca original inteira, não apenas a resumida dentro do programa. Aí é só utilizar "rtmp://publish.livestream.com/mogulus/[canal]/username=[usuario]/password=[senha]/isAutoLive=true/live app=mogulus/[canal]/username=[usuario]/password=[senha]/isAutoLive=true live=1" como endereço do servidor.

UPDATE: Caso sua transmissão também seja direcionada para dispositivos móveis (e isso obriga também que o vídeo seja em h264 e o áudio em AAC, nada de MP3) é importante que você defina também "playpath" no comando, indicando o intevalo de keyframes e o bitrate total da transmissão (audio+video). Neste exemplo: "rtmp://publish.livestream.com/mogulus/[canal]/username=[usuario]/password=[senha]/isAutoLive=true/live app=mogulus/[canal]/username=[usuario]/password=[senha]/isAutoLive=true playpath=livestream?videoKeyframeFrequency=5&totalDatarate=400 live=1"

*** Caso você use Mac com o Homebrew, o comando para instalar com o librtmp é brew install ffmpeg --with-rtmpdump

segunda-feira, 7 de maio de 2012

Duplicando o áudio de um vídeo

Na dica sobre nomalização de áudio de vídeos já embutimos recursos para duplicar o áudio de arquivos onde a trilha estéreo tem um dos lados mudos, só que agora retornamos ao assunto para tratar exclusivamente este problema e sem a utilização de programas externos.

ffmpeg -f lavfi -i "amovie=arquivo_original.flv,pan=stereo: c0=c1: c1=c1" -i arquivo_original.flv -map 0:0 -map 1:0 -vcodec copy -acodec libfaac arquivo_final.mp4

Para entender melhor a sintaxe:

A primeira parte do comando causa bastante estranheza, mas tem uma explicação. -f lavfi -i "amovie=arquivo_original.flv,pan=stereo: c0=c1: c1=c1" indica para o FFMPEG que o arquivo de entrada na verdade é um filtro do libav e logo em seguida passa as opções para o mesmo. Neste caso é a biblioteca que abre o arquivo e não o FFMPEG em si, por isso a sintaxe um pouco estranha. pan=stereo: c0=c1: c1=c1 indica como será o balanceamento do áudio, onde c0 é o canal esquerdo e c1 é o canal direito. Como queremos que o canal direito seja usado nos dois lados do áudio indicamos c0=c1 e c1=c1.

O resto é familiar. -i arquivo_original.flv abre o segundo arquivo que servirá como fonte de vídeo, -map 0:0 -map 1:0 aponta qual stream será o de vídeo e o de áudio, -vcodec copy -acodec libfaac os codecs utilizados e por fim o nome do arquivo final.

sábado, 5 de maio de 2012

De FLV para MP4 sem recompressão

Aprendemos no último post a diferença entre codec e wrapper. Agora vamos tirar proveito disso:

É uma situação bastante corriqueira querer salvar um vídeo do YouTube ou outro site de compartilhamento de vídeos para ver em outro dispositivo. Muitas vezes os aplicativos de download de vídeos não fazem a conversão de formatos ou o fazem piorando ainda mais a qualidade do arquivo que na maioria das vezes já não é bom.

O FFMPEG resolve esse problema. Se o arquivo FLV foi codificado em H264/AAC (você pode ver esta informação pelo VLC em "Informações da Mídia > Detalhes do codec") basta executar:

ffmpeg -i arquivo.flv -vcodec copy -acodec copy arquivo_final.mp4

Pronto, você já tem um arquivo MP4, compatível com uma grande variedade de dispositivos (iOS por exemplo) sem precisar recodificar o arquivo e sem perda nenhuma de qualidade nesse processo.

terça-feira, 24 de abril de 2012

Noções básicas: Codec e wrapper

Para dominar bem o uso do FFMPEG é preciso antes deixar claro alguns pontos que a maioria das pessoas fazem confusão. Um dos principais é a diferença entre wrapper e codec. É muito comum uma pessoa falar "preciso de um vídeo em formato AVI" e depois ficar confuso pelo vídeo não funcionar no player ou dispositivo utilizado. Vamos a explicação:

Um vídeo e um áudio carregam quantidades enormes de informação digital. Para fazerem parte do nosso dia a dia precisam ser comprimidos. Os processos e técnicas utilizadas para atingir esse objetivo determinam o codec usado. Codec = codificação. Aí entram o h264, DivX, MP3, Windows Media...

Já AVI, tal como FLV, MKV e muitos outros que geralmente emprestam o nome ao conhecimento popular são "wrappers", ou seja, o que a própria tradução diz: Empacotadores. Eles unem vários streams (fluxos) de áudio e vídeo, em diferentes codecs, em um arquivo baixável, um streaming, uma transmissão de TV digital ou TV a cabo, entre outros.

Fazendo uma analogia com o mundo analógico (rá!) o wrapper seria a diagramação do livro, a quantidade de palavras por página, a existência ou não de notas no rodapé das páginas, etc... e o codec a língua em que o livro está escrito.

Portanto, voltando ao exemplo inicial, dizer que um arquivo é AVI não indica muita coisa além da forma que ele é organizado entre stream de áudio e vídeo. É preciso saber os codecs que serão usados dependendo quais são suportados pelo dispositivo-alvo. DivX? h264? Indeo? DV? Tudo depende do objetivo buscado.

Conceito esclarecido? Então até o próximo post, onde baseado nesses conceitos vamos ver como é passar um vídeo Flash FLV baixado do YouTube ser tranformado em MP4 sem perda de qualidade numa recompressão.

domingo, 15 de abril de 2012

Normalizando o áudio do vídeo sem recomprimir a imagem

Nem todo mundo tem muito cuidado técnico ao postar vídeos na internet, nem mesmo as grande emissoras. Faz algum tempo baixei alguns vídeos de um site com dois problemas: Áudio muito baixo e em apenas um lado dos canais estéreo. Mas como corrigir isso sem fazer com que a imagem seja recomprimida quadriculando ainda mais? Esse problema pode ser solucionado através do ffmpeg e um outro programa adicional, o SoX (disponível em http://sox.sourceforge.net/ ou através do Homebrew para usuários do Mac OS X)

O procedimento explicado:

Uso o ffmpeg para extrair do vídeo (um MP4) apenas o áudio em formato WAV, já mixando ele em mono. Depois com o SoX calculo e aplico a normalização no nível de volume e em seguida uso o ffmpeg pra unir a faixa de vídeo original com o arquivo gerado pelo SoX, ao mesmo tempo comprindo para AAC, que o formato MP4 exige.

O código:

Em formato de script do Bash o procedimento fica da seguinte forma:

#!/bin/sh
x=$1
file=${x%.*}
ffmpeg -i "$x" -vn -ac 1 "$file.wav"
sox "$file.wav" "$file-2.wav" vol `sox "$file.wav" -n stat -v 2>&1`
ffmpeg -i "$x" -i "$file-2.wav" -map 0:0 -map 1:0 -vcodec copy -acodec libfaac -ab 128k "$file-2.mp4"
rm "$file-2.wav" "$file.wav"

Feito isso basta apenas chamar pelo Terminal o seu script .sh seguido pelo caminho do arquivo a ser corrigido (não esqueça de atribuir permissões de execução a ele, ou seja, "chmod +x script.sh"). O arquivo corrigido será salvo na mesma pasta do original com o mesmo nome do original acrescentando um "2" no final.

Trocando em miúdos o código:

Agora vamos entender o para que serve cada parte do código:


ffmpeg -i "$x" -vn -ac 1 "$file.wav"
 -i - Indica o arquivo de entrada

-vn - Exclui a faixa de vídeo

-ac 1 - Indica que o arquivo de saída será mono (1 = mono / 2 = estéreo)

sox "$file.wav" "$file-2.wav" vol `sox "$file.wav" -n stat -v 2>&1`
Neste caso usamos um recurso do Bash de executar um comando dentro de outro. Entre os apóstrofes é executado o SoX com o comando -n stat que realiza uma análise do arquivo, inclusive o nível de volume a se ajustado. 2>&1 seleciona e retorna este resultado. Assim, o comando vol ajusta o arquivo de entrada $file.wav e salva como $file-2.wav

ffmpeg -i "$x" -i "$file-2.wav" -map 0:0 -map 1:0 -vcodec copy -acodec libfaac -ab 128k "$file-2.mp4"
Finalmente combinaremos todos os elementos para o arquivo final. Dois comandos -i são realizados, um lendo o vídeo original e outro para o áudio corrigido. Os comandos -map atribuem para estes arquivos de entrada qual será o vídeo e qual será o áudio. -vcodec copy indica que a faixa de vídeo será escrita idêntica a original, sem recompressão e -acodec libfaaac -ab 128k indica que o som WAV será comprimido no formato AAC e em 128kbps. E por último o nome do arquivo de saída. Pronto!