Pesquisa de site

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!

Artigos relacionados: