Hackeando FFmpeg com Python - Parte Um
FFmpeg é uma excelente estrutura multimídia que ajuda você a lidar com seus arquivos de áudio e vídeo. O que quero dizer com isso? Bem, você pode facilmente converter de um formato para outro, extrair áudio de um vídeo, compactar um vídeo e até mesmo extrair imagens de um vídeo. Há muitas coisas legais que você pode fazer com esta ferramenta. Ele é escrito principalmente na linguagem de programação C e a melhor parte é que o FFmpeg é de código aberto.
Através deste tutorial você aprenderá como usar a linguagem de programação python para interagir com esta ferramenta de código aberto a fim de automatizar algumas tarefas simples.
Configurando python e ffmpeg em sua caixa Linux
A versão python usada neste artigo é Python 2.7.x, portanto, certifique-se de instalá-la em sua própria máquina Linux antes de prosseguir, pois uma versão diferente pode causar todos os tipos de erros ao executar o código no shell interativo python.
Compilar o código a partir do código-fonte é um pouco complicado, mas como é necessário cobrir esta instalação para quase qualquer tipo de distribuição Linux, não é possível passar por todos os gerenciadores de pacotes.
Abra o terminal e baixe o pacote python correto usando o utilitário wget, conforme mostrado aqui:
wget --no-check-certificate https://www.python.org/ftp/python/2.7.11/
Python-2.7.11.tgz
Nota: wget é um utilitário de linha de comando que pode ser usado para baixar coisas através do protocolo http.
Assim que o pacote python 2.7.x terminar de baixar, a próxima ferramenta de linha de comando necessária é tar:
tar -xzf Python-2.7.11.tgz
Altere o diretório de trabalho usando o seguinte comando:
cd Python-2.7.11
Para compilar e instalar o python em sua máquina execute os seguintes comandos, um por um. Esta é a última etapa para garantir que você tenha a versão correta do python instalada. Sem ele, você não poderá aproveitar as vantagens desta série de hackers FFmpeg:
./configure
make
sudo make install
Antes de compilar e instalar o FFmpeg é sempre uma boa ideia testar a nova versão do python que você acabou de instalar.
O comando a seguir pode ajudar a executar python2.7.x em sua máquina Linux para verificá-lo:
python2.7
Se o shell python aparecer, significa que esta parte da configuração foi feita corretamente.
A mesma coisa deve ser feita para ter o utilitário FFmpeg em sua caixa nix. O primeiro passo é baixar o código-fonte do site oficial usando o comando mostrado abaixo:
wget https://github.com/FFmpeg/FFmpeg/archive/master.zip
Como você pode ver no comando acima, a ferramenta wget é usada para baixar o código-fonte, que precisamos compilar.
O comando para descompactar o arquivo .zip é o seguinte:
unzip master.zip
Quando o diretório estiver pronto, execute o seguinte comando para ter certeza de que a configuração foi feita corretamente:
./configure
Se o comando acima for concluído sem erros, significa que você pode facilmente compilar e instalar o FFmpeg em sua máquina.
Use os seguintes comandos:
make
su -c 'make install'
Assim que a instalação do FFmpeg for concluída, recomendamos fortemente que você faça o mesmo teste que fizemos com o shell python para garantir que a ferramenta funcione corretamente.
O seguinte comando pode ser usado para executar o FFmpeg na linha de comando:
ffmpeg
Alguns exemplos práticos de FFMpeg
Antes de começar a hackear o FFmpeg usando uma linguagem de programação como Python, é recomendável que você se familiarize com alguns dos recursos que esta estrutura líder de código aberto de multimídia tem a oferecer.
Incluído na instalação da caixa FFmpeg está o utilitário ffprobe. Ele pode ser usado para obter informações sobre um arquivo de áudio ou vídeo, como streams, formato ou ambos, usando o seguinte código:
ffprobe -show_format -show_streams test.mp4
O comando acima investiga o vídeo ‘test.mp4’ em busca de tags de formato e fluxos. A saída exibida no console por este comando é muito extensa, conforme mostrado abaixo.
[STREAM]
index=1
codec_name=aac
codec_long_name=AAC (Advanced Audio Coding)
profile=LC
codec_type=audio
codec_time_base=1/44100
codec_tag_string=mp4a
codec_tag=0x6134706d
sample_fmt=fltp
sample_rate=44100
channels=2
channel_layout=stereo
bits_per_sample=0
id=N/A
r_frame_rate=0/0
avg_frame_rate=0/0
time_base=1/44100
start_pts=0
start_time=0.000000
duration_ts=9262080
duration=210.024490
bit_rate=95999
max_bit_rate=103664
bits_per_raw_sample=N/A
nb_frames=9045
nb_read_frames=N/A
nb_read_packets=N/A
DISPOSITION:default=1
DISPOSITION:dub=0
DISPOSITION:original=0
DISPOSITION:comment=0
DISPOSITION:lyrics=0
DISPOSITION:karaoke=0
DISPOSITION:forced=0
DISPOSITION:hearing_impaired=0
DISPOSITION:visual_impaired=0
DISPOSITION:clean_effects=0
DISPOSITION:attached_pic=0
DISPOSITION:timed_thumbnails=0
TAG:creation_time=2015-04-23T08:06:29.000000Z
TAG:language=eng
TAG:handler_name=IsoMedia File Produced by Google, 5-11-2011
[/STREAM]
[FORMAT]
filename=test.mp4
nb_streams=2
nb_programs=0
format_name=mov,mp4,m4a,3gp,3g2,mj2
format_long_name=QuickTime / MOV
start_time=0.000000
duration=210.023333
size=8691199
bit_rate=331056
probe_score=100
TAG:major_brand=mp42
TAG:minor_version=0
TAG:compatible_brands=isommp42
TAG:creation_time=2015-04-23T08:06:28.000000Z
[/FORMAT]
A saída produzida por este comando nos fornece muitas informações sobre os fluxos do arquivo. Cada fluxo tem seu próprio índice. O primeiro fluxo tem um índice 0, mas para os fins deste artigo, nem todos os fluxos investigados pelo ffprobe são exibidos aqui.
Suponha que alguém queira extrair apenas o fluxo de áudio de um videoclipe. O comando perfeito pela minha experiência é aquele que copia o fluxo de áudio sem recodificá-lo:
ffmpeg -i video.mp4 -vn -acodec copy audio.aac
O comando acima é realmente útil quando se trata de extrair o fluxo de áudio. No entanto, há um grande problema com isso. A cópia do fluxo de áudio precisa da extensão correta, que no caso acima é .acc. É aqui que o ffprobe se torna realmente útil!
Encontrar a extensão correta para salvar o arquivo de áudio que está sendo copiado é tão fácil quanto dar uma olhada no valor codec_name dentro das informações do fluxo de áudio que vem da análise do arquivo com o seguinte utilitário de linha de comando ffprobe:
[STREAM]
index=1
codec_name=aac
........
........
.......
[/STREAM]
Para obter mais informações sobre como usar o utilitário de linha de comando ffmpeg, leia nosso artigo sobre comandos práticos que podem ser usados em situações reais.
Comece a usar python para interagir com ffmpeg
Python é uma linguagem de programação de computador de alto nível, perfeita para criar scripts que alguém gosta de automatizar. Não é necessário ser um especialista em python para seguir este tutorial ou utilizar outros códigos Python. Até mesmo um iniciante em codificação pode acompanhar, compreender e executar os códigos compartilhados neste artigo.
Abra um shell python usando o seguinte comando em seu terminal:
python2.7
Existem muitos módulos disponíveis na biblioteca padrão que o python oferece. Aquela que realmente atende às nossas necessidades é a biblioteca de subprocessos.
Para fazer uso de um módulo python, primeiro você deve importá-lo usando o seguinte comando:
import subprocess
Mas qual é a finalidade do módulo que acabamos de importar? De acordo com a documentação oficial do python, o módulo subprocess permite gerar um processo. Em outras palavras, você pode executar um programa via python. Além disso, você também pode conectar-se aos seus tubos de entrada/saída e até obter códigos de retorno.
O exemplo a seguir é realmente bom para lhe dar uma ideia melhor de como o módulo subprocesso pode ser usado para gerar um processo.
p = subprocess.Popen('ls', stderr=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=subprocess.PIPE)
O código python acima executa o comando ls que lista os arquivos dentro de um diretório. Tente você mesmo!
Em seguida, obtenha a saída do processo aberto acima comunicando-se com ele conforme mostrado abaixo.
output, _ = p.communicate()
Para imprimir a saída, esta instrução python print pode ser usada:
print(_)
A instrução acima irá exibir a saída retornada pela comunicação com o processo. Se tudo funcionou corretamente, você deverá obter uma lista dos arquivos e subdiretórios dentro do diretório de trabalho atual.
Python também pode ajudar a gerar um processo para o utilitário ffmpeg conforme mostrado no código a seguir:
cmds = ['/usr/local/bin/ffmpeg']
ffmpeg_p = subprocess.Popen(cmds, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
Comunique-se com o processo para obter a saída:
output, _ = ffmpeg_p.communicate()
Imprima a saída retornada por ffmpeg no console usando esta instrução python print:
print(_)
A instrução print acima imprimirá o seguinte:
ffmpeg version 3.2 Copyright (c) 2000-2016 the FFmpeg developers
configuration: --prefix=/usr/local/Cellar/ffmpeg/3.2 --enable-shared
--enable-pthreads --enable-gpl --enable-version3 --enable-hardcoded-tables
--enable-avresample --cc=clang --host-cflags= --host-ldflags=
--enable-libmp3lame --enable-libx264 --enable-libxvid --enable-opencl
--disable-lzma --enable-vda
libavutil 55. 34.100 / 55. 34.100
libavcodec 57. 64.100 / 57. 64.100
libavformat 57. 56.100 / 57. 56.100
libavdevice 57. 1.100 / 57. 1.100
libavfilter 6. 65.100 / 6. 65.100
libavresample 3. 1. 0 / 3. 1. 0
libswscale 4. 2.100 / 4. 2.100
libswresample 2. 3.100 / 2. 3.100
libpostproc 54. 1.100 / 54. 1.100
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]... {[outfile options]
outfile}...
Use -h to get full help or, even better, run 'man ffmpeg'
É a mesma coisa que executar o comando ffmpeg no console, mas desta vez usamos python para fazer o trabalho para nós.
Obter os streams e o formato do arquivo de vídeo com python é tão fácil quanto definir os comandos necessários para gerar o processo com o módulo subprocess.
No nosso caso os comandos são os seguintes:
cmds = ['/usr/local/bin/ffprobe', '-show_format', '-show_streams',
'test.mp4']
Como você pode ver, armazenamos os comandos em um objeto python que é conhecido como lista. A sintaxe para definir uma lista é a seguinte:
[]
Em seguida, abra um novo processo e passe o cmds como argumento, conforme mostrado abaixo:
ffprobe_p = subprocess.Popen(cmds, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Para obter os streams e o formato do arquivo de vídeo você precisa usar o método de comunicação como fizemos nos exemplos anteriores. Use este código:
output, _ = ffprobe_p.communicate()
Em seguida, use a instrução print para imprimir os fluxos e as informações de formato retornadas pela operação de investigação.
Conclusão
FFmpeg não é apenas uma ferramenta geek usada por geeks como nós! A indústria multimídia também faz uso disso. Há muito buzz em torno do YouTube usando-o para codificar seus vídeos. Memorizar toda a lista de comandos que esta ferramenta tem a oferecer não vale a pena, mas este é um caso perfeito para quando uma linguagem de script como o Python se torna realmente útil.
A diversão está apenas começando, vamos aproveitar!