2012
10
30
10
30
C#: DirectShowでビデオファイルのフレームを抜き出して保存
追記
*********************************
DirectShowはわりと長いあいだ使われてきた技術だ。.NET Frameworkはそれより後に出てきたもので、DirectShowを使った開発にC#はイマイチしっくりこない。
ではC#に向いた技術は? 最近はExpression Encoder 4というのが出てきた。これは近年リリースされたもので、.NET Frameworkから容易にSDKが使えるようになっている。エンコーダーという名前だが、スクリーンキャプチャして動画をつくったり、動画からサムネイルを作るのが簡単にできるようになっている。ドキュメントのコードサンプル一覧を見れば、なにができそうかパッとわかる。
たとえば動画のサムネイルがほしいときはそれがBitmapクラスのインスタンスで得られるなんて気の利きよう。DLLに対してのtmbimpも不要だし。
<http://msdn.microsoft.com/en-us/library/cc761464(v=expression.40).aspx
スクリーンキャプチャで動画作るアプリ作ってみた
動画ファイルからサムネイル作るC#クラス作ってみた
*********************************
WPF: MediaElementからサムネイルを作る
ビデオファイルからサムネイルが作りたくて、以前MediaElementを使ってキャプチャした。タグに埋め込まれたイメージを使わないのは、サイズが小さすぎたりそもそも埋め込まれていなかったりするから。
MediaElementはWPFに使えるとても便利なパーツで、XAMLにそのまま記述できる。だけどもビデオファイル読み込み時に、グラフィック描画スペックの弱い環境だと、デスクトップの描画を数フレーム落とすことがある。これがネックだ。ライブラリにいくつもあるビデオファイルのサムネイルを作ろうとMediaElementからキャプチャする方法を取る。すると、そのキャプチャのためのビデオファイルをロードするたびにフレーム落ちが生じる。サムネイル作成のための代替手段が欲しい。
代替手段として、DirectShowを使った。これならばビデオファイルロード時のフレーム落ちが発生しなかった。しかもMediaElementと違って、デスクトップへの描画なしにキャプチャが可能だった。
こういうことをしている例は探せばやっぱりあるのだけど、記事が古くなっていて同じ手順では通用しなくなっていたり、codeprojectなどにあるラッパーを使っているために、手順が煩雑化していた。
では手順を。参照の追加でCOMから、『Dexter 1.0 Type Library』を追加。もう一つtlbimpを使って、C:\Windows\System32\qedit.dllを.NETから使えるDLLを作って参照に追加。あとは下のコードを適所に適用。
余談
メディアプレーヤを作ろうと思って初めて読んだページで、DirectShowの新しい代替手段としてWPFのMediaElementが紹介されていた。だからDirectShowの正統後継であろうMediaFoundationを使ってこなかった。MediaFoundationはDRMコンテンツにも対応した新技術らしい。公式にあるC++のサンプルや、C#で使えるようにした.NETのラッパーで試してみたが、avi再生やDRM保護のwmvをそのまま再生しようとしてエラーが出たので、まだDirectShowの代替として使うほどのアドバンテージは感じられなかった。
*********************************
DirectShowはわりと長いあいだ使われてきた技術だ。.NET Frameworkはそれより後に出てきたもので、DirectShowを使った開発にC#はイマイチしっくりこない。
ではC#に向いた技術は? 最近はExpression Encoder 4というのが出てきた。これは近年リリースされたもので、.NET Frameworkから容易にSDKが使えるようになっている。エンコーダーという名前だが、スクリーンキャプチャして動画をつくったり、動画からサムネイルを作るのが簡単にできるようになっている。ドキュメントのコードサンプル一覧を見れば、なにができそうかパッとわかる。
たとえば動画のサムネイルがほしいときはそれがBitmapクラスのインスタンスで得られるなんて気の利きよう。DLLに対してのtmbimpも不要だし。
<http://msdn.microsoft.com/en-us/library/cc761464(v=expression.40).aspx
スクリーンキャプチャで動画作るアプリ作ってみた
動画ファイルからサムネイル作るC#クラス作ってみた
*********************************
WPF: MediaElementからサムネイルを作る
ビデオファイルからサムネイルが作りたくて、以前MediaElementを使ってキャプチャした。タグに埋め込まれたイメージを使わないのは、サイズが小さすぎたりそもそも埋め込まれていなかったりするから。
MediaElementはWPFに使えるとても便利なパーツで、XAMLにそのまま記述できる。だけどもビデオファイル読み込み時に、グラフィック描画スペックの弱い環境だと、デスクトップの描画を数フレーム落とすことがある。これがネックだ。ライブラリにいくつもあるビデオファイルのサムネイルを作ろうとMediaElementからキャプチャする方法を取る。すると、そのキャプチャのためのビデオファイルをロードするたびにフレーム落ちが生じる。サムネイル作成のための代替手段が欲しい。
代替手段として、DirectShowを使った。これならばビデオファイルロード時のフレーム落ちが発生しなかった。しかもMediaElementと違って、デスクトップへの描画なしにキャプチャが可能だった。
こういうことをしている例は探せばやっぱりあるのだけど、記事が古くなっていて同じ手順では通用しなくなっていたり、codeprojectなどにあるラッパーを使っているために、手順が煩雑化していた。
では手順を。参照の追加でCOMから、『Dexter 1.0 Type Library』を追加。もう一つtlbimpを使って、C:\Windows\System32\qedit.dllを.NETから使えるDLLを作って参照に追加。あとは下のコードを適所に適用。
using QuartzTypeLib;
using DexterLib;
//動画サイズの取得
FilgraphManager filgraphManager = new FilgraphManager();
filgraphManager.RenderFile(fileName);
IBasicVideo bv = (IBasicVideo)filgraphManager;
int vx, vy;
bv.GetVideoSize(out vx, out vy);
var scale = 100F / (float)vx; //100Fのところに出力画像の長辺の長さを入れる
var w = (int)(scale * vx);
var h = (int)(scale * vy);
//フレーム保存の準備
var md = (IMediaDet)new MediaDet();
md.Filename = fileName;
md.CurrentStream = 0;
string name = @"hoge.bmp";
md.WriteBitmapBits(5.0d, w, h, name);
余談
メディアプレーヤを作ろうと思って初めて読んだページで、DirectShowの新しい代替手段としてWPFのMediaElementが紹介されていた。だからDirectShowの正統後継であろうMediaFoundationを使ってこなかった。MediaFoundationはDRMコンテンツにも対応した新技術らしい。公式にあるC++のサンプルや、C#で使えるようにした.NETのラッパーで試してみたが、avi再生やDRM保護のwmvをそのまま再生しようとしてエラーが出たので、まだDirectShowの代替として使うほどのアドバンテージは感じられなかった。
スポンサーサイト