ビデオ フォーマットの基本はわかりました。いくつかのコンテナ フォーマットがあり、次にコア ビデオ/オーディオ フォーマットがあります。ファイルが使用しているビデオ/オーディオ コーデックを判断する Web ベースのアプリケーションを作成したいと考えています。
ビデオコーデックをプログラムで判断するにはどうすればよいですか? システムコールを介して標準ライブラリを使用し、その出力を解析するのが最善でしょうか? (例: ffmpeg、トランスコードなど?)
ビデオ フォーマットの基本はわかりました。いくつかのコンテナ フォーマットがあり、次にコア ビデオ/オーディオ フォーマットがあります。ファイルが使用しているビデオ/オーディオ コーデックを判断する Web ベースのアプリケーションを作成したいと考えています。
ビデオコーデックをプログラムで判断するにはどうすればよいですか? システムコールを介して標準ライブラリを使用し、その出力を解析するのが最善でしょうか? (例: ffmpeg、トランスコードなど?)
mplayer -identify
トリックを行います。ファイルを呼び出すだけffmpeg
でも機能します。ffmpegに実際に何をするように指示しているかに関係なく、入力ファイルに関する一連の情報を最初に自動的に出力します。
もちろん、外部プログラムへの exec 呼び出しを使用せずにプログラムから実行したい場合は、avcodec ライブラリを含めて、独自の識別ルーチンを直接実行できます。
独自の検出を実装することもできますが、libav* がサポートするフォーマットの数が非常に多いことを考えると、既存のルーチンより劣ることは間違いありません。そして、それは車輪の再発明のかなりばかげたケースになるでしょう.
Linux の「file」コマンドでも同じことができますが、出力されるデータの量はビデオ形式によって異なります。たとえば、AVI では、解像度、FOURCC、fps などに関するあらゆる種類のデータが提供されますが、MKV ファイルでは、「Matroska データ」と表示されるだけで、内部構造や、使用されているビデオおよびオーディオ形式については何もわかりません。
これを実現するために、perl スクリプトで FFMPEG を使用しました。
$info = `ffmpeg -i $path$file 2>&1 /dev/null`;
@fields = split(/\n/, $info);
そして、抽出する必要がある @fields 内のアイテムを見つけるだけです。
さらに先に進む必要があります。コンテナ形式と、それがコーデックを指定する方法を知る必要があります。
したがって、コンテナーの形式を識別するプログラムから始めます (拡張子だけでなく、ヘッダーに移動して実際のコンテナーを決定します)。
次に、プログラムがサポートするコンテナを特定し、コーデックを含むコンテナに格納されたメタ データを解析するために必要な関数を組み込みます。
-アダム
ファイルの先頭付近を探すために、バイナリ識別マーカーの大きなデータベースが本当に必要です。幸いなことに、あなたの質問には「Linux」というタグが付けられており、そのようなデータベースはすでにそこに存在します。file(1) はあなたのために仕事をします。
ffprobe
出力形式をjsonに強制することをお勧めします。解析がはるかに簡単になります。最も簡単な例:
$meta = json_decode(join(' ', `ffprobe -v quiet -print_format json -show_format -show_streams /path/to/file 2>&1`));
ファイルが破損している場合はnull
、エラー報告の設定に応じて結果と警告が表示されることに注意してください。適切なエラー処理を含む完全な例:
$file = '/path/to/file';
$cmd = 'ffprobe -v quiet -print_format json -show_format -show_streams ' . escapeshellarg($file).' 2>&1';
exec($cmd, $output, $code);
if ($code != 0) {
throw new ErrorException("ffprobe returned non-zero code", $code, $output);
}
$joinedOutput = join(' ', $output);
$parsedOutput = json_decode($joinedOutput);
if (null === $parsedOutput) {
throw new ErrorException("Unable to parse ffprobe output", $code, $output);
}
//here we can use $parsedOutput as simple stdClass