中堅プログラマーの備忘録

忘れっぽくなってきたので備忘録として・・・

c#.netでWindowsMediaPlayerコントロールを使って動画プレイヤーを作成する。

単純な動画プレイヤーを作成してみました。
ローカルの特定フォルダ内のmp4ファイルのリストを作成し、それを延々と繰り返し再生をします。
必要な作業は【WindowsMediaPlayerコントロール】と【Timerコントロール】をFormに貼り付けるだけです。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WMPLib;

namespace tnvViewer
{
    public partial class Form1 : Form
    {
        static AxWMPLib.AxWindowsMediaPlayer mediaPlayer1;
        //
        private string[] playList;
        private int LIST_NUM;
        private int nowPlayNum = 0;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // 自身のサイズを変更
            this.Bounds = new Rectangle(0,0,1920,1080);

            // フォルダ内の再生可能な動画ファイル(mp4)の一覧を取得する。
            playList = System.IO.Directory.GetFiles(@"C:\work\sampleMedia", "*.mp4", System.IO.SearchOption.AllDirectories);            LIST_NUM = playList.Length;

            // 動画プレイヤーの設定
            mediaPlayer1 = axWindowsMediaPlayer1;
            mediaPlayer1.stretchToFit = true;			// 表示領域にフィットするようにサイズを変更する
            mediaPlayer1.uiMode = "none";               // UIを消す
            mediaPlayer1.Location = new Point(0, 0);
            mediaPlayer1.Dock = DockStyle.Fill;
            mediaPlayer1.settings.autoStart = false;	// 自動再生無効
            mediaPlayer1.Ctlenabled = false;            // ダブルクリックによるフルスクリーン出力を無効化
            mediaPlayer1.enableContextMenu = false;     // 右クリックによるコンテキストメニューの出力を無効化

            // 再生開始
            mediaPlayer1.URL = playList[nowPlayNum];
            playNumIncrement();
        }

        private void axWindowsMediaPlayer1_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)        {
            switch (e.newState)
            {
                case (int)WMPLib.WMPPlayState.wmppsStopped:
                    //停止時
                    break;

                case (int)WMPLib.WMPPlayState.wmppsPlaying:
                    //再生時
                    
                    break;

                case (int)WMPLib.WMPPlayState.wmppsMediaEnded:
                    //再生終了時
                    mediaPlayer1.URL = playList[nowPlayNum];
                    playNumIncrement();
                    break;

                case (int)WMPLib.WMPPlayState.wmppsTransitioning:
                    //再生準備中()
                    
                    break;

                case (int)WMPLib.WMPPlayState.wmppsReady:
                    //再生準備完了
                    timer1.Start();
                    break;

                default:
                    break;
            }
        }

        private void playNumIncrement()
        {
            nowPlayNum++;
            if(nowPlayNum>= LIST_NUM)
            {
                nowPlayNum = 0;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Stop();
            mediaPlayer1.Ctlcontrols.play();
        }
    }
}

WMPPlayStateについては下記のとおり。

state 説明
wmppsUndefined 0 未定義
wmppsStopped 1 停止
wmppsPaused 2 一時停止
wmppsPlaying 3 再生
wmppsScanForward 4 早送り
wmppsScanReverse 5 高速巻き戻し
wmppsBuffering 6 追加データを取得
wmppsWaiting 7 接続待機
wmppsMediaEnded 8 再生を完了
wmppsTransitioning 9 準備
wmppsReady 10 準備完了
wmppsReconnecting 11 再接続

【WindowsMediaPlayerコントロール】の動作フローとして
①URLを指定
②stateが【wmppsTransitioning】に移行
③stateが【wmppsReady】に移行したところで再生スタート
④stateが【wmppsMediaEnded】に移行
⑤次の動画のURLを指定で②からの繰り返し
といった感じです。

再生準備が完了したところでtimerをかましている理由ですが
そのままplayメソッドを実行すると
【HRESULTからの例外:0xC00D1054 】が発生しました。
理由としてはPlayStateChangeイベントハンドラー内で再生開始すると
PlayStateChangeイベントが発生しイベントループしてしまうからのようです。