動画ファイルや音声ファイルを再生するにはDelphiに標準で付属するTMediaPlayerを使ったりTWindowsMediaPlayerを取り込んで使ったりと色々ありますが、DirectShowを使うという手もあります。
TMediaPlayerやTWindowsMediaPlayerのようにコンポーネントをフォームに貼り付けてプロパティをセットして動作を決めてゆくというようなお手軽さはありませんが、ビデオ映像のキャプチャが(慣れれば)簡単にできるなどそれを補って余りある魅力があります。
コンポーネントを貼り付けてのお手軽さを求めるならDSPackというものを利用する手もあります。
このページではDSPackのコンポーネントは使わずに生のDicrectShowをいじくりまわしてやっています。
今回は下準備ととりあえず再生するだけのサンプルです。
DirectShowのインターフェースの一覧。
左の欄にある膨大な数のインターフェースの一覧を見ただけでも心が折れてしまいそうになりますが、大丈夫。
すべて理解する必要はありません。
ただ、ざっと目を通しておけばやりたいことの目星が付くやも知れません。
DirectShowでの再生やキャプチャなどをサンプルと共に説明してくれています。
まずはDirectShowのヘッダーをDelphi用に翻訳したユニットを使えるようにします。
この作業はDelphi 6などの古いバージョンでDirectShowのヘッダー(DirectShow9.pasあるいはDirectShow9.dcu)が付属しないものに必要なものです。
あらかじめDirectShowのヘッダーが付属しているバージョンのDelphiには必須ではありません。
DirectShowのヘッダーをDelphi用に翻訳したものはDSPackに入っています。
DSPack以外にも探せば色々とあるようですが、DSPackはDirectShowをコンポーネント化していて、更にそのソースコードがついているのでお勧めです。
2010年9月現在2.3.4が最新版のようです。
ダウンロードして解凍したら、DirectShow9.pasのあるフォルダ(src\Directx9)とDSPackのソースコードのあるフォルダ(src\DSPack)をDelphiのライブラリのパスに追加します。
DSPackのソースコードのあるフォルダはDSPackのコンポーネントを使わない場合でもBaseClass.pasとDSUtil.pasを使うことがあるのでパスに追加しておきます。
Delphiのメニューで「プロジェクト」→「オプション」で出てくるダイアログの「ディレクトリ/条件」タブの「検索パス」の欄に追加します。
これで準備OKです。
ちなみに、DSPackの圧縮ファイルを解凍してできるファイルにはDirectX用のヘッダーユニットの他にもサンプルソースコードなどが色々あります。
それらのサンプルを動かすにはDSPackをインストールして使えるようにしておく必要があります。
インストールのやり方はreadme.htmlに(英文ですが)書いてあります。
Delphi 6の場合なら、
これでOKです。
DirectX9_D6.dpkとDSPack_D6.dpkはコンパイルするだけでインストールはしません。
DSPackDesign_D6.dpkをインストールするだけです。
メディアプレーヤーのサンプルだけでなくDVDプレーヤーのサンプルやフィルターのサンプルなどもあるのでインストールしておいて損はないと思います。
それでは早速DirectShowでの再生をやってみましょう。
とりあえず再生しっぱなしなサンプルです。
interface部のuses節にDirectShow9ユニットを追加します。
implementation部のuses節にActiveXユニットを追加します。
Form1のprivate宣言部にIGraphBuilder型の変数F_GraphBuilderを宣言します。
Form1にButtonコントロールとOpenDialogコントロールを貼り付けます。
Buttonコントロールをダブルクリックして表示されるButton1Clickイベントに上記のコードを加えます。
Form1のFormDestroyイベントにF_GraphBuilderを初期化するコードを加えます。
これだけです。
このプログラムを実行させ、ボタンをクリックしてファイル選択ダイアログで音楽ファイルや動画ファイルを選べば再生が始まります。
選択したファイルが動画なら別ウィンドウを開いて再生します。
参考サイトのサンプルのコードと比べるとずいぶんあっさりしていますが、これは手抜きができるところを思いっきり抜いているためです。
このようにDirectShowは手を抜いた部分を賢く補完してくれるので意外と取っ付きやすいです。
参考サイトのサンプルはコマンドラインのプログラムなので再生の後待機するようなコードが必要ですが、フォームを使う場合には必要ありません。
またDirectShowを使うにあたってCOMの初期化のためにCoInitializeを最初に呼びなさい、そしてそれに合わせて終了時にCoUninitializeも呼びなさいとありますが、これもDelphiでは必要ありません。
必要ないというか、すでにComObjユニットで呼ばれているのでわざわざ自分でやる必要がありません。
そしてComObjユニットはDirectShow9ユニットのuses節に含まれています。
結果、Delphiでは必要なし。
ということです。
更にCoUninitializeはCoInitializeの戻り値によって呼ばなければならなかったり逆に呼んではならなかったりするので、この場合余分なことはしない方が良いという判断で省略します。
気をつける点はD6のファイル選択ダイアログのFileNameプロパティはAnsiStringなのでWideStringにキャストしてからRenderFileに渡すという点です。
それをしないと、POLESTRはPWideCharと同じなのでPWideChar(OpenDialog1.FileName)とするのと同じことになり(Unicode化以前のDelphiでは)文字化けするのでファイルの読み込みに失敗します。
今回はファイルを選んで再生しっぱなしなサンプルでしたが、IMediaControlインターフェースを使えば再生、一時停止、停止などができます。
IMediaPositionインターフェースを使えば再生位置の移動なども簡単にできます。