domingo, 28 de outubro de 2007

Conversão de formatos de vídeos com PHP e FFMPeg (Parte 1)

Olá. Neste primeiro artigo desta série gostaria de demonstrar uma forma de se manipular formatos de vídeo (e áudio) utilizando-se uma classe em PHP, FFMPeg e qt-faststart.

O que é FFMPeg ?

Pra quem não conhece, o FFMpeg é a princípio uma ferramenta de comando de linha para converter vídeo. Com esta ferramenta, é possível além da converção, extrair apenas áudio ou vídeo de um arquivo, transmitir streaming por uma rede (internet ou rede local), mesclar arquivos de vídeo com arquivos de áudio, etc. A quantidade de codec´s que esta ferramenta utiliza também é um ponto forte, sendo praticamente possível a conversão de qualquer formato, para qualquer formato (mesmo os proprietário$). Recomendo uma passadinha no site oficial do projeto:http://ffmpeg.mplayerhq.hu/

O que é PHP ?

Acredito que se você está lendo artigo, já sabe o que é PHP ;-) Caso você não seja deste planeta e esteja curioso para saber, visite: http://br.php.net/

O que é qt-faststart ?

É um programa que provê a propriedade fast-start para arquivos MOV. Após baixar o source, rode make qt-faststart e, após isto copie o executável gerado (qt-faststart) para o diretório /usr/bin. Veja: http://svn.mplayerhq.hu/ffmpeg/trunk/tools/qt-faststart.c?view=markup

Instalação do FFMPeg

Você pode instalar o FFMPeg por apt ou yum, dependendo da versão do sistema que utiliza. Recomendo os seguintes pacotes: ffmpeg, ffserver ( um servidor HTTP para a ferramenta, o RTSP encontra-se em desenvolvimento enquanto escrevo estas linhas ), ffplay ( uma perfumaria para executar arquivos multimídia ), libavcodec ( uma biblioteca que contém todos os codificadores/decodificadores utilizados pelo FFMPeg ) e libavformat ( uma biblioteca contendo interpretadores e geradores para todos os formatos de vídeo e áudio comuns ).

Mães à obra...

Vamos iniciar construindo uma simples classe em PHP para realizar simples conversões, lembrando que isto é um papel bem básico para o poder do FFMPeg:
<?php

class FFMPeg
{
/**
* Classe para manipulação de arquivos de áudio e vídeo
* @version 1.0 (29/10/2007)
* @author Márcio Leandro da Silva (marcio.sfs@gmail.com)
*/

private $_arquivo_original;
private $_audio_codec;
private $_video_codec;
private $_cmd;

/**
* Construtor, define o arquivo original
*
* @param String $origem
*/
public function __construct ($origem)
{
if (is_file ($origem))
{
$this->_arquivo_original = $origem;
}
else
{
trigger_error(__CLASS__ . ': o arquivo original não é válido.', E_USER_ERROR);
}
}

/**
* Definindo as propriedades
*
* @param String $propriedade
* @param Integer $valor
*/
private function __set($propriedade, $valor)
{
# as propriedades que você deseja manipular
$propriedades = Array(
    'bitrate',
    'framerate',
    'audiobitrate'
   );

if (!in_array($propriedade, $propriedades))
{
trigger_error("impossivel setar propriedade " . __CLASS__ . "::$propriedade", E_USER_ERROR);
}
else
{
settype($valor, 'integer');
$this->$propriedade = $valor;
}
}

/**
* Define os codecs a ser utilizado na geração do novo vídeo
*
* @param String $video_codec
* @param String $audio_codec
*/
public function setCodecs ($video_codec, $audio_codec)
{
$array_audio_codecs = Array('mp3', 'aac');
$array_video_codecs = Array ('wmv', 'flv', 'h264', 'avi');

if (!in_array($video_codec, $array_video_codecs))
{
trigger_error('Impossível encontrar codec de vídeo: ' . $video_codec, E_USER_ERROR);
}

if (!in_array($audio_codec, $array_audio_codecs))
{
trigger_error('Impossível encontrar codec de áudio: ' . $audio_codec, E_USER_ERROR);
}

$this->_video_codec = trim ($video_codec);
$this->_audio_codec = trim ($audio_codec);
}

/**
* Realiza a converção
*
* @param String $arquivo_final
* @param String $formato
* @return Boolean
*/
public function converter ($arquivo_final, $debug=FALSE)
{
# arquivo original
$cmd = "ffmpeg -y -i {$this->_arquivo_original} -vcodec {$this->_video_codec} -acodec {$this->_audio_codec}";

if (isset($this->bitrate))
{
$cmd .= " -b {$this->bitrate}k";
}
if (isset($this->framerate))
{
$cmd .= " -r {$this->framerate}";
}
if (isset($this->audiobitrate))
{
$cmd .= " -ar {$this->audiobitrate}";
}

if ($this->_video_codec == 'h264')
{
$cmd .= " -qmin 10 -qmax 51";
}

$cmd .= " $arquivo_final 2>&1";

//echo $cmd;
if ($debug ==FALSE)
{
exec ($cmd);
}
else
{
echo "<pre>;";
passthru ($cmd);
echo "</pre>;";
}

if ($this->_video_codec == 'h264')
{
/*$arquivo_temporario = time();
$cmd = "qt-faststart $arquivo_final $arquivo_temporario 2>&1";
exec($cmd);
unlink($arquivo_final);
rename($arquivo_temporario, $arquivo_final);
*/
}
return file_exists($arquivo_final);
}
}

?>

Enfim, um exemplo de utilização da mesma:
<?php

include 'ffmpeg.class.php';

$video = new FFMPeg('video.avi');

$video->bitrate = 200;
$video->framerate = 24;
$video->audiobitrate = 44100;
$video->setCodecs('h264', 'mp3');

$video->converter('final.mov', TRUE);

?>

Por hoje é só. No próximo artigo desta série estarei implementando esta classe para que ela trabalhe com streaming de áudio e/ou vídeo, útil para se criar uma rádio virtual, um sistema de monitoramento por câmeras, e o que mais a imaginação mandar. That´s all, Folks ;-)
DevOne - Desenvolvimento WEB
Anabolizando- Tudo sobre esteróides anabolizantes

Nenhum comentário: