Webページがありますが、(特に)ユーザーがアップロードしたビデオから特定のフレームを抽出する必要があります。ユーザーはプレーヤーの.mp4の特定の部分をシークし、ボタンをクリックすると、ajax呼び出しが.mp4とビデオからの正確な時間を取得するphpスクリプトに送信され、それを使用して抽出します「サムネイル」フレーム。
私の現在のソリューションは、php exec
コマンドを使用しています。
exec("ffmpeg -i $videoPath -ss $timeOffset -vframes 1 $jpgOutputPath");
...これは糖蜜と同じくらい遅いことを除いて、非常にうまく機能します。私の推測では、ffmpegは仕事には少し多すぎるので、基礎となるライブラリーなどを利用することでより良い結果が得られる可能性があります...しかし、その方法はわかりません。
理想的には、本当の「インストールプロセス」を必要とするものをインストールする必要はありません...つまり、実行可能ファイルをWebアプリでフォルダーにドロップすることは問題ありませんが、実際にインストーラーを実行する必要はありません。また、ソリューションはMac、Linux、およびWindowsで実行できる必要があります(Linuxが最優先事項です)。
このプロセスを高速化するにはどうすればよいですか?
ありがとう。
もちろん、いくつかのC/C++をコーディングして-lav *にリンクし、基本的にフレームを抽出するためにffmpegの簡易バージョンを作成し、PHP拡張機能として実行することもできます(同じユーザーとして実行しません) 、もちろん同じプロセスで)。ただし、フォークとセットアップのオーバーヘッドを回避するだけであるため、結果が高速になることはほとんどありませんが、実際の問題はデコードであり、これは依然として同じです。
代わりに、最初にffmpegを高速シークモード(または高速/正確なハイブリッドモード)で使用することを検討する必要があります。 彼らのウィキの状態 高速シークについて:
-ssパラメーターは、-iの前に指定する必要があります。
ffmpeg -ss 00:03:00 -i Underworld.Awakening.avi -frames:v 1 out1.jpg
この例では、ムービーの開始から3分前後のどこかに1つのイメージフレーム(out1.jpg)を生成します。入力はキーフレームを使用して解析されますが、これは非常に高速です。欠点は、特定の時間(00:03:00)にあるとは限らないキーフレームでもシークを終了するため、シークが期待どおりに正確にならないことです。
高速シークはそれほど正確ではありませんが、ffmpegはシーク中にムービーの大部分を実際にデコードする必要がないため、非常に高速です。一方、高速/正確なハイブリッドモードは妥協点です。使用可能なすべてのオプションについては、 wikiページ をお読みください。
編集14/06/10:
FFmpeg 2.1の時点で、ffmpegを使用してトランスコードする場合(つまり、ストリームコピーではない場合)、-ssは、入力オプションとして使用する場合でも正確になりました。 -noaccurate_seekオプションを使用すると、以前の動作を復元できます。 (ソース)
したがって、2.1 +では、再エンコードに関して正確な結果を得るために「ハイブリッド」シークはもう必要ありません(.jpeg
への保存は再エンコードです)。低速シーク(-ss ... -i ...
)ではなく、通常の高速シーク(-i ... -ss ...
)を行うだけで十分です。