ffmpeg-php で FLV からサムネイルを生成する
今年初セーターな nakamura です。こんにちは。
そうそうあるケースではないですが、とある案件で FLV ファイルからサムネイル画像を生成する機能が必要になったのでその時の作業メモです。ffmpeg-php というエクステンションを使うと比較的容易にできますよ。
今回は CentOS-5.5 での作業例です。
インストール
動作には ffmpeg, ffmpeg-devel といったパッケージが必要ですが、デフォルトのリポジトリには存在しないので rpmforge リポジトリを追加します。※ダウンロードする rpm のファイル名は適宜最新のものにしてください。
wget http://packages.sw.be/rpmforge-release/rpmforge-release-0.5.1-1.el5.rf.i386.rpm
rpm -ivh rpmforge-release-0.5.1-1.el5.rf.i386.rpm
リポジトリの追加が終わったらパッケージをインストールします。php-devel も入っていなければ入れてください。
yum --enablerepo=rpmforge install ffmpeg ffmpeg-devel php-devel
こちら のページから ffmpeg-php のソースコードをダウンロード、展開します。現時点で最新の 0.6.0 を使います。
wget http://sourceforge.net/projects/ffmpeg-php/files/ffmpeg-php/0.6.0/ffmpeg-php-0.6.0.tbz2/download -O /usr/local/src/ffmpeg-php-0.6.0.tbz2
tar xjvf /usr/local/src/ffmpeg-php-0.6.0.tbz2
展開したソースをコンパイル、インストール。
cd /usr/local/src/ffmpeg-php-0.6.0
phpize
./configure -enable-shared -prefix=/usr
make
make install
/usr/lib/php/modules/ffmpeg.so が生成されていれば成功です。
/etc/php.d/ffmpeg.ini に以下のように記述して Apache を再起動すれば ffmpeg-php が利用可能な状態になります。
; Enable ffmpeg extension module
extension=ffmpeg.so
プログラム例
それでは実際のプログラム例です。今回はアップロードされた FLV ファイルの開始から 3 秒目をキャプチャして幅 96px 高さ 72px に収まる大きさにサムネイル化した画像をダウンロードさせる処理です。
ffmpeg-php で使えるメソッドについては こちら を参照してください。
<?php
// 生成するサムネイルの幅と高さの最大値
define("LIMIT_WIDTH", 96);
define("LIMIT_HEIGHT", 72);
// 動画の読み込み
$movie = new ffmpeg_movie($_FILES["flv"]["tmp_name"], false);
if (!$movie) {
// 適宜エラー処理してください
echo "アップロードされたファイルが読み取れません。";
exit;
}
// フレームレート取得
$frame_rate = $movie->getFrameRate();
// 3 秒目のフレームを計算
$target_frame = $frame_rate * 3;
// 該当する箇所のフレームオブジェクト取得
$frame = $movie->getFrame($target_frame);
// GD イメージオブジェクト生成
$image = $frame->toGDImage();
// 画像の幅と高さを取得
$width = ImageSX($image);
$height = ImageSY($image);
// 縮小比率を計算
$width_rate = LIMIT_WIDTH / $width;
$height_rate = LIMIT_HEIGHT / $height;
if ($height_rate < $width_rate) {
$rate = $height_rate;
} else {
$rate = $width_rate;
}
$new_width = $width * $rate;
$new_height = $height * $rate;
// リサイズした画像オブジェクトを生成
$new_image = ImageCreateTrueColor($new_width, $new_height);
ImageCopyResized($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
// ファイル名生成
$filename = "thumb_" . date("YmdHis") . ".jpg";
// HTTP ヘッダ出力
header("Content-type: image/jpeg");
header("Content-Disposition: attachment; filename=\"{$filename}\"");
// ファイル出力
ImageJPEG($new_image, null, 100);
// インスタンス解放
imagedestroy($image);
imagedestroy($new_image);
?>
終わりに
ブログにのせる用にちぢめたコードなのであれですが、、、処理の流れとしては大体こんな感じでいけるはずです。使う機会がもしあればぜひ参考にしてみてください。