Posted at

PHPでffmpegを使った動画の変換を裏側で行う

More than 5 years have passed since last update.


ffmpegを使った動画の変換を裏側で行う

ユーザーが動画をアップした時に変換している間なにも出来ないんじゃ困るので、アップしたら後は勝手にバックグラウンドで粛々と変換されるようにします。


やり方

ffmpegの変換はターミナルなんかを起動してffmpegコマンドを実行して行うので、PHPからシェルを実行できるexec()とかshell_exec()という関数を使います。

shell_exec("ffmpeg -i sample.flv -vcodec libx264 -vpre default sample.mp4");

shell_execのカッコの中に通常のffmpegコマンドをそのまま書けば出来ます。

これを使ったエンコード処理をするphpファイル(例えばconvert.php)を作り、

アップロードされた際にそのphpファイルへ遷移させ、その後完了画面へ遷移させます。


convert.php

//convert.php

shell_exec("ffmpeg -i sample.flv -vcodec libx264 -vpre default sample.mp4");
header('Location: complete.php');

このままだと、ffmpegコマンドが終わらない限り、完了画面(complete.php)へ遷移できないので、

ffmpegコマンドの最後に「&」をつけます。

shell_exec("ffmpeg -i sample.flv -vcodec libx264 -vpre default sample.mp4 &");

header('Location: complete.php');

これで、ffmpegコマンドが完了(エンコード処理完了)しなくてもすぐ完了画面へ遷移し、バックグラウンドではそのままエンコード処理が勝手に続きます。


access.php

shell_exec('/usr/bin/php /var/www/html/convert.php &');

header('Location: complete.php');


convert.php

shell_exec("ffmpeg -i sample.flv -vcodec libx264 -vpre default sample.mp4");

header('Location: notice.php?convert=success');


notice.php

$flg = $_GET['convert']; //終了フラグを受け取る。

//・・・DBに書き込む処理


complete.php

echo  'エンコードが完了しました';


「/usr/bin/php」というのは、サーバーにあるPHPの実行ファイルのあるパスで、コマンドラインからPHPを実行する場合には、こういう書き方をします。(サーバーによってphpのパスが違う場合がある)

phpのパスが分からなければコマンドラインで# which phpと打てばパスが分かる。

後半の「/var/www/html/convert.php」はconvert.phpのパス。


動画を別サーバーに置く場合

サイトのあるサーバーと動画ファイルを保管しておくサーバーとを別にする場合、

convert.phpは動画ファイルのあるサーバーに置いておかないといけないので、

サイトのあるサーバーでaccess.phpを実行し、コマンドラインからconvert.phpへ遷移しようとしても出来ない。

その場合には、access.php内でコマンドラインから「wget」を使う。

wgetはファイルをダウンロードしてくるコマンドで、これを使う事でサイトのあるサーバーへconvert.phpをダウンロードしてこれる。

そして、そのconvert.phpを実行するという流れ。


access.php

shell_exec('wget http://hogehoge.com/convert.php &');

header('Location: complete.php');

もし、convert.phpへ複数のGETパラメータを渡したいならURLをクォーテーションで囲ってあげないと、2つ目以降のパラメータがわたらないので注意。

shell_exec("wget 'http://hogehoge.com/convert.php?id=1&name=sample' &");