Capturando miniatura de vídeos com PHP

Hoje vamos falar de um assunto bastante divertido e que é de muita utilidade para todos nós. Vamos aprender como capturar a miniatura (thumbnail) de um vídeo em PHP e posteriormente salva-las no HD. Todo serviço que trabalha com algum tipo de mídia precisa de algumas ferramentas para fazer esta manipulação. O PHP não oferece suporte utilizando funções nativas para manipular arquivos de audio ou vídeo. Por isso, vocês precisam de 3 coisas muito importantes que são descritas logo a frente para seguirmos com este artigo.

Requisitos

  • ffmpeg-0.4.9_pre1 ou superior.
  • ffmpeg-php 0.5.3 ou superior.
  • gd-2.0 ou superior. (a versão que vem compilada com o PHP funciona também)

obs: Neste artigo não é meu objetivo ensinar a fazer a instalação destes recursos pois com uma rápida googada você resolve o problema.

O que é o ffmpeg?

O ffmpeg é um conjunto de bibliotecas de uso livre e open-source que oferece um suporte completo para você converter e interagir com praticamente qualquer tipo de mídia.

O que é o ffmpeg-php?

O ffmpeg-php é uma extensão php desenvolvida para que nós, programadores PHP, possamos interagir com o ffmpeg sem utilizarmos a “perigosa” função system() (e derivadas) do PHP. Mas vale lembrar que ela cobre “em partes” as funções do ffmpeg. Você não consegue com ffmpeg-php converter vídeos por exemplo, mas com o ffmpeg você consegue.

Recebendo as informações do vídeo com PHP

Antes de começar a brincar com o vídeo, nós precisamos aprender como pegar as informações do vídeo. O ffmpeg-php permite que você acesse estas informações do video:

//Return the duration of a movie or audio file in seconds.
$movie->getDuration() 
//Return the number of frames in a movie or audio file.
$movie->getFrameCount() 
//Return the frame rate of a movie in fps.
$movie->getFrameRate() 
//Return the path and name of the movie file or audio file.
$movie->getFilename() 
//Return the comment field from the movie or audio file.
$movie->getComment() 
//Return the title field from the movie or audio file.
$movie->getTitle() 
//alias $movie->getArtist()	Return the author field from the movie or the artist ID3 field from an mp3 file.
$movie->getAuthor() 
//Return the copyright field from the movie or audio file.
$movie->getCopyright() 
//Return the artist ID3 field from an mp3 file.
$movie->getArtist() 
//Return the genre ID3 field from an mp3 file.
$movie->getGenre() 
//Return the track ID3 field from an mp3 file.
$movie->getTrackNumber() 
//Return the year ID3 field from an mp3 file.
$movie->getYear() 
 //Return the height of the movie in pixels.
$movie->getFrameHeight()
//Return the width of the movie in pixels.
$movie->getFrameWidth()	
//Return the pixel format of the movie.
$movie->getPixelFormat() 
//Return the bit rate of the movie or audio file in bits per second.
$movie->getBitRate() 
//Return the bit rate of the video in bits per second.
$movie->getVideoBitRate()
//Return the audio bit rate of the media file in bits per second.
$movie->getAudioBitRate() 
//Return the audio sample rate of the media file in bits per second.
$movie->getAudioSampleRate() 
//Return the current frame index.
$movie->getFrameNumber() 
//Return the name of the video codec used to encode this movie as a string.
$movie->getVideoCodec()	
//Return the name of the audio codec used to encode this movie as a string.
$movie->getAudioCodec() 
//Return the number of audio channels in this movie as an integer.
$movie->getAudioChannels() 
//Return boolean value indicating whether the movie has an audio stream.
$movie->hasAudio() 
//Return boolean value indicating whether the movie has a video stream.
$movie->hasVideo() 
//Returns a frame from the movie as an ffmpeg_frame object. 
//Returns false if the frame was not found.
//framenumber - Frame from the movie to return. 
//If no framenumber is specified, returns the next frame of the movie.
$movie->getFrame([Integer framenumber])	
//Returns the next key frame from the movie as an ffmpeg_frame object. 
//Returns false if the frame was not found.
$movie->getNextKeyFrame()

No nosso caso, os únicos métodos que vão nos interessar seram: getFrameRate, getDuration, getFrameCount, getFrameHeight , getFrameWidth e getFrame.

No início do seu script, coloque esta linha só por segurança:

if ( ! extension_loaded ( 'ffmpeg' ) ) exit ( 'ffmpeg não foi carregado!' );

Para receber as informações do vídeo dentro do seu arquivo PHP você precisa utilizar a classe ffmpeg_movie do ffmpeg-php e passar como parametro o caminho do vídeo que você quer manipular.

// instancia a classe ffmpeg_movie para pegarmos as informações que queremos o vídeo
$movie = new ffmpeg_movie($movie_file);
// pegamos a duranção do video em segundos
$duration = round ( $movie->getDuration() , 0 ); 
// recebemos o número de frames do vídeo
$totalFrames = $movie->getFrameCount();
// recebemos a altura do vídeo em pixels
$height = $movie->getFrameHeight ();
// recebemos a largura do vídeo em pixels
$width = $movie->getFrameWidth ();

Recebendo o frame do vídeo e salvando

Agora que já temos as informações do vídeo, podemos capturar a miniatura de um determinado frame do vídeo e salva-la em nosso HD. Vamos utilizar outra classe do ffmpeg-php chamada ffmpeg_frame e utilizarmos a função toGDImage para convertermos o frame para uma imagem GD.

Para escolhermos o frame podemos utilizar algumas técnicas:

Miniatura de um segundo especifico:

$thumbnailOf = $movie->getFrameRate() * 5;

Miniatura do meio do vídeo:

$thumbnailOf = round ( $movie->getFrameCount() / 2 );

Neste exemplo vou pegar fazer um calculo para receber um frame do meio do vídeo e salvar no HD.

// precisamos criar uma imagem GD para o ffmpeg-php trabalhar nela
$image = imagecreatetruecolor ( $width , $height ) ;
// criamos a instancia do frame com a classe ffmpeg_frame
$frame = new ffmpeg_frame ( $image );
// escolhemos o frame que queremos salvar como jpeg
$thumbnailOf = (int) round ($movie->getFrameCount() / 2.5);
// recebe o frame
$frame = $movie->getFrame ( $thumbnailOf );
// converte para uma imagem GD
$image = $frame->toGDImage ();
//salva no HD.
imagejpeg($image, $movie_file.'.jpg', 100);

Pronto! Agora não tem desculpa. Vocês já sabem capiturar o frame de um video e salvar uma miniatura dele.

Redimencionando o frame do video

Este capitulo é um bonus. Vocês também podem salvar um frame especifico do video como jpeg e redimenciona-lo antes e salvar no HD. A função resize() da classe ffmpeg_frame faz isso para gente:

$frame->resize(Integer width, Integer height [, Integer crop_top [, Integer crop_bottom [, Integer crop_left [, Integer crop_right ]]]])

Utilizando o mesmo código acima, acrescentando somente uma linha:

// colei esta linha somente como referencia
$frame = $movie->getFrame ( $thumbnailOf ); 
// redimenciona o frame para 200 de lagura por 100 de algura.
$frame->resize ( 200, 100 );

Podemos também, redimencionar esta imagem e fazer um crop nela:

// colei esta linha somente como referencia
$frame = $movie->getFrame ( $thumbnailOf );
// redimencionamos o frame para 200x100 e mas com o acrescimo de um crop de 30x30x30x30.
$frame->resize ( 200, 100, 30, 30, 30, 30 );

É isso aí!

Maiores informações, na documentação oficial do ffmpeg-php.

[]’s
Igor.

Posts Relacionados: