C#でDirectShowを使って動画を再生する

chakemiです。

本日は、DirectShowをC#で使ってみようと思います。

DirectShow.Netというとても便利なライブラリもありますが、今回は、「ランタイム呼び出し可能ラッパー」というものを使ってみようと思います。 ランタイム呼び出し可能ラッパーについてはこの辺をみてください。

開発環境

  • WindowsXP SP3
  • VisualC#2010Express

DirectShowはCOMベースでタイプライブラリが用意されていて、ランタイム呼び出し可能ラッパーを作成出来ます。

参照設定から「参照の追加」を開いて、「COM」タブの「Active Movie control type library」を選択します。

ソリューションエクスプローラーに「QuartzTypeLib」が追加されます。

VisualStudioを使わない人は、自分でQuartzTypeLib.dllを作成することも出来ます。 詳しくは、こちらをみてください。

今回は、ボタンからOpenFileDialogで再生したい動画を選択し、アプリケーションウィンドウで動画を再生してみようと思います。

usingディレクティブを追加します。

1
using QuartzTypeLib;

適当に設置したボタンのクリックイベントに、再生の処理を書いてきます。 はじめにフィルタグラフマネージャーを生成します。

1
FilgraphManager filgraphManager = new FilgraphManager();

次に再生用グラフを作成生成します。

1
filgraphManager.RenderFile(openFileDialog.FileName);

フィルタグラフマネージャーからインターフェースを取得します。

1
2
3
IBasicVideo bv = (IBasicVideo)filgraphManager;
IVideoWindow vw = (IVideoWindow)filgraphManager;
IMediaEventEx mevent = (IMediaEventEx)filgraphManager;

動画サイズを取得し、VideoWindowをアプリケーションウィンドウにアタッチします。

1
2
3
4
5
int vx, vy;
bv.GetVideoSize(out vx, out vy);

vw.Owner = (int)this.Handle;
vw.WindowStyle = 0x40000000 | 0x4000000;

VideoWindowを動画のサイズに設定し、アプリケーションウィンドウのサイズを変更します。

1
2
3
4
vw.SetWindowPosition(0, 0, vx, vy);
this.Width = vx + 2;
this.Height = vy + 55;
button1.Location = new Point(button1.Location.X, vy + 2);

イベント通知を受け取れるように所有者ウィンドウを設定します。

1
mevent.SetNotifyWindow((int)this.Handle, 0x8000, 0);

グラフマネージャーを実行し、再生します。

1
filgraphManager.Run();

以下、全体です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using QuartzTypeLib;

namespace ActiveMovieControl
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.InitialDirectory = @"c:\";
            openFileDialog.Filter = "メディアファイル(*.avi;*.mpg;*.wmv)|*.avi;*.mpg;*.wmv|すべてのファイル|*.*";

            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                //グラフマネージャー生成
                FilgraphManager filgraphManager = new FilgraphManager();
                //再生用グラフの作成
                filgraphManager.RenderFile(openFileDialog.FileName);
                //インターフェースの取得
                IBasicVideo bv = (IBasicVideo)filgraphManager;
                IVideoWindow vw = (IVideoWindow)filgraphManager;
                IMediaEventEx mevent = (IMediaEventEx)filgraphManager;

                //動画サイズの取得
                int vx, vy;
                bv.GetVideoSize(out vx, out vy);

                //VideoWindowをアプリケーションウィンドウにアタッチ
                vw.Owner = (int)this.Handle;
                vw.WindowStyle = 0x40000000 | 0x4000000;

                //VideoWindowを動画のサイズに設定し、アプリケーションウィンドウのサイズを変更
                vw.SetWindowPosition(0, 0, vx, vy);
                this.Width = vx + 2;
                this.Height = vy + 55;
                button1.Location = new Point(button1.Location.X, vy + 2);

                //イベント通知を受け取れるように所有者ウィンドウを設定
                mevent.SetNotifyWindow((int)this.Handle, 0x8000, 0);

                filgraphManager.Run();

            }
        }
    }
}

こんな感じで再生出来ました。

Comments