と(前回の話)いうことで、このサンプルコードを利用して自作のダイアログテンプレートをベースにテストします。
フォームのドンガラは直ぐにできて、
後はサンプルのコードを参考に「(メディア)ファイルを読込」「再生」「一時停止」「中断」「終了」の各メソッドを埋めればよいのです。(悪戦苦闘の部分は//解説:を参照してください。)
【MediaPlayer(Form).cs】
///////////////////////////////////////////////////////////////
// MediaPlayer, MediaDrawingサンプル
// https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/multimedia-overview?view=netframeworkdesktop-4.8
// https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/how-to-play-media-using-a-videodrawing?view=netframeworkdesktop-4.8
// https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.media.videodrawing?view=windowsdesktop-7.0
// https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.media.mediaplayer?view=windowsdesktop-7.0
// https://learn.microsoft.com/ja-jp/dotnet/desktop/wpf/graphics-multimedia/drawing-objects-overview?view=netframeworkdesktop-4.8
// https://www.dotnetheaven.com/article/how-to-create-a-media-player-in-csharp#google_vignette
// https://www.tetsuyanbo.net/tetsuyanblog/54455
///////////////////////////////////////////////////////////////
//解説:URLはテストを進めながら参照(学習)していったサイトです。
using System;
//using System.Windows; //Rectを使う為にこれを入れるとFormsの定義と抵触する
//using System.Windows.Controls;
using System.Windows.Forms; //Rectを使う為にこれを入れるとWindowsの定義と抵触する
//解説:ここら辺で「ん?なんかおかしいぞ?」という感じはしたんですよね。
using System.Drawing;
using System.Reflection; //Assemblyを使う為
using System.Windows.Media; //解説:MediaPlayerクラスを宣言すると直ぐに「参照先がない」
using System.Windows.Media.Imaging; //というエラーになるので、Microsoft Learnで調べて追加しました。
namespace MPViewer
{
///////////////////////////
//エントリーポイントクラス
///////////////////////////
class MainApp
{
[STAThread]
public static void Main()
{
Application.Run(new MPForm());
}
}
///////////////////////////
//MediaPlayerサンプルクラス
///////////////////////////
public partial class MPForm : Form
{
//コントロール
Button Btn1, Btn2, Btn3, Btn4, extBtn;
MediaPlayer mp = null; //解説:これはメソッドから参照できるように、です。
VideoDrawing vd = null; //解説:同じです。
//ファイル名
string fName;
public MPForm()
{
Assembly myOwn = Assembly.GetEntryAssembly();
this.Icon = Icon.ExtractAssociatedIcon(myOwn.Location); //プログラムアイコンをフォームにつける
this.Load += new EventHandler(MPForm_Load);
this.Text = "MediaPlayerとMediaDrawing サンプル";
this.ClientSize = new Size(640, 480);
this.MinimumSize = new Size(480, 360);
this.BackColor = SystemColors.Window;
}
private void MPForm_Load(object sender, EventArgs e)
{
//ボタン1
Btn1 = new Button();
Btn1.Location = new Point(ClientSize.Width - Btn1.Width - 10, 10);
Btn1.Text = "Open";
Btn1.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
Btn1.Click += Button1_Click;
this.Controls.Add(Btn1);
//ボタン2ボタン
Btn2 = new Button();
Btn2.Location = new Point(ClientSize.Width - Btn2.Width - 10, Btn1.Height + 20);
Btn2.Text = "Play";
Btn2.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
Btn2.Click += Button2_Click;
this.Controls.Add(Btn2);
//ボタン3ボタン
Btn3 = new Button();
Btn3.Location = new Point(ClientSize.Width - Btn3.Width - 10, Btn1.Height + Btn2.Height + 30);
Btn3.Text = "Pause";
Btn3.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
Btn3.Click += Button3_Click;
this.Controls.Add(Btn3);
//ボタン4ボタン
Btn4 = new Button();
Btn4.Location = new Point(ClientSize.Width - Btn4.Width - 10, Btn1.Height + Btn2.Height + Btn3.Height + 40);
Btn4.Text = "Stop";
Btn4.Anchor = (AnchorStyles.Top | AnchorStyles.Right);
Btn4.Click += Button4_Click;
this.Controls.Add(Btn4);
//終了ボタン
extBtn = new Button();
extBtn.Location = new Point(ClientSize.Width - extBtn.Width - 10, ClientSize.Height - extBtn.Height - 10);
extBtn.Text = "終了";
extBtn.Anchor = (AnchorStyles.Bottom | AnchorStyles.Right);
extBtn.Click += extBtn_Click;
this.Controls.Add(extBtn);
//MediaPlayer //解説:System.Windows.Media等を追加しているのでエラーになりません。
mp = new MediaPlayer();
}
private void Button1_Click(object sender, EventArgs e)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.AddExtension = true;
ofd.DefaultExt = "*.*";
ofd.Filter = "Media(*.*)|*.*";
ofd.ShowDialog();
fName = ofd.FileName;
ofd.Dispose();
//解説:これは単にメディアファイルパス、名を選択するだけです。
}
private void Button2_Click(object sender, EventArgs e)
{
/*
//Create a MediaTimeline.
MediaTimeline mTimeline = new MediaTimeline(new Uri(@"sampleMedia\xbox.wmv", UriKind.Relative));
//Set the timeline to repeat.
mTimeline.RepeatBehavior = RepeatBehavior.Forever;
Create a clock from the MediaTimeline.
MediaClock mClock = mTimeline.CreateClock();
MediaPlayer repeatingMP = new MediaPlayer();
repeatingMP.Clock = mClock;
VideoDrawing repeatingVD = new VideoDrawing();
repeatingVD.Rect = new Rect(150, 0, 100, 100);
repeatingVD.Player = repeatingMP;
//解説:これはTimeLineを利用したMicrosoft Learnのサンプルを参照できるように貼っています。
*/
//mp.Open(new System.Uri(fName, UriKind.Relative)); //相対。他に"Absolute"がある。//解説:これは備忘です。
mp.Open(new System.Uri(fName)); //Uri:URI(Uniform Resource Identifier) のオブジェクト表現を可能にし、URI の一部へ簡単にアクセスできるようにします。
vd = new VideoDrawing();
vd.Rect = new System.Windows.Rect(0, 0, 200, 200);
vd.Player = mp;
//解説:描画するにはVideoDrawインスタンスを引数で渡して生成したDrawBrushインスタンスが必要ということを、後で英文サイトで調べて知りました。以下がそのコードです。
// Assign the DrawingBrush.
// https://csharp.hotexamples.com/jp/examples/System.Windows.Media/VideoDrawing/-/php-videodrawing-class-examples.html
// DrawingBrush br = new DrawingBrush(vd);
// System.Windows.Controls.Panel p = new System.Windows.Controls.Panel();
// p.Bakcground = br;
//解説:これはWPFの書き方ではなく、WinFormでの書き方です。当時何も分かっていませんでした。
// this.Control.Add(p);
//解説:このコードではDrawBrushインスタンスをVideoDrawインスタンスを渡して生成し、「Panel」というコントロールを作ってその"BackGround"プロパティに設定しますが、Panelというコントロールは「見当たらないエラー」が出ますし、他のコントロールでは「BackGroundというプロパティがないエラー」が出ます。実に「おかしい」です。
mp.Play();
//解説:以上の緑色部分がMicrosoft Learnのサンプルコードです。最初から「どこへ、どのように描画するのか」が分からないコードだったので「おかしいな」とは思っていましたが、ここで段々と学習し、「何か僕が知らない大事な問題が隠れているぞ」ということが分かってきました。(「無知の智」)
}
private void Button3_Click(object sender, EventArgs e)
{
mp.Pause(); //トグルでmp.Play()と交互に使用する
}
private void Button4_Click(object sender, EventArgs e)
{
//ファイルを閉じる
mp.Close();
//初期化する
mp = null;
}
private void extBtn_Click(object sender, EventArgs e)
{
vd = null;
mp = null;
Close();
}
}
}
結局、後で「C#には、UI(UserInterface)の基盤(プラットフォーム、従ってライブラリー)にWinFormsとWPFの二つがあり、これらは(特別な必要性があり、特別な方法で共存させることは不可能ではないが。基本的に)共存できない」ことを知るのですが、この段階では「何故だろう、何故かしら?????」状態であったので、とうとうChat-GPI様のアドバイスを乞いました。
/* Chat-GPTの回答
C#のWindows FormsアプリケーションでMediaElementコントロールを使用することは、通常は難しいです。
MediaElementコントロールは主にWPF (Windows Presentation Foundation) プラットフォームで使用されるものであり、Windows Formsには直接組み込まれていません。
ただし、Windows Media Playerコントロールを使用してメディア再生を実現することは可能です。(解説:これは結局InterOperativeによります。)以下に、Windows FormsアプリケーションでWindows Media Playerコントロールを使用する例を示します。
まず、プロジェクトにWindows Media Playerコンポーネントを追加する必要があります。
プロジェクトを右クリックして、「デザイナーで開く」を選択します。(解説:結局Visual Studioベースです。)
ツールボックスで、「COMコンポーネント」から「Windows Media Player」を探します。ない場合は、「ツールボックスの選択」から追加します。(解説:これは結局InterOperativeによります。)
以下は、簡単な例です。フォームにWindowsMediaPlayerという名前のAxWindowsMediaPlayerコントロールを配置し、以下のコードを使用してメディアを再生します。
using System;
using System.Windows.Forms;
namespace MediaElementExample
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
// メディアのファイルパスを指定
axWindowsMediaPlayer1.URL = "C:\\Path\\To\\Your\\MediaFile.mp4";
}
private void btnPlay_Click(object sender, EventArgs e)
{
// 再生
axWindowsMediaPlayer1.Ctlcontrols.play();
}
private void btnPause_Click(object sender, EventArgs e)
{
// 一時停止
axWindowsMediaPlayer1.Ctlcontrols.pause();
}
private void btnStop_Click(object sender, EventArgs e)
{
// 停止
axWindowsMediaPlayer1.Ctlcontrols.stop();
}
}
}
Windows Media PlayerのCOMオブジェクトを操作するためのWMPLibライブラリ(解説:InterOperativeベースなので入手しようともしませんでした。)は、通常、Interop.WMPLib.dllとして知られるInteropアセンブリに含まれています。これは、Windows Media PlayerのCOMオブジェクトとC#コードとの間の相互運用性を提供します。
Interop.WMPLib.dllは通常、プロジェクトが参照するために生成され、プロジェクトのビルドディレクトリやbinフォルダに配置されます。ただし、直接的に手動で追加することは一般的でなく、通常はVisual Studioなどの開発環境が自動的に処理します。(解説:「Visual StudioやMSBuildが生成する」ので、Visual StudioがないとInterOperativeベースの開発は困難です。まぁ、それならC++でやった方が簡単だし。でも、それは本旨ではないので...)
以下は、WMPLibを使用するC#コードの例です:
csharp
Copy code
using WMPLib;
class Program
{
static void Main()
{
WindowsMediaPlayer wmp = new WindowsMediaPlayer();
// ここで Windows Media Player オブジェクトを使用するコードを追加
// アプリケーションを終了する前にオブジェクトを解放する
System.Runtime.InteropServices.Marshal.ReleaseComObject(wmp);
}
}
このコードでは、WMPLibから提供されるWindowsMediaPlayerオブジェクトが使用されています。プロジェクトが正しく構成されていれば、Interop.WMPLib.dllが必要なライブラリであり、これが自動的に解決されるはずです。
*/
結局Chat-GPTに聞いても、WinFormsベースではWin32APIベースのCOMをラップして使う方法しか提供してもらえず、またC#でWinFormsとWPFが共存困難であることから、
じゃ、C#でWPFベースのプログラムをかけばいーんでしょ?
という発想に切り替えました。(切り替えざるを得ませんでした。)
そして「私のWPFへの冒険(闘い?)」は続くのです。(注)
注:切りが良いので、【WPF】シリーズはここで本年分を締め、中断します。旧年中はご訪問、有難うございました。又、来年「【WPF】WPFを学習する」シリーズでお会いしましょう。
追記:アップしてから、「↑のコードでどうなったの?」という結論を書き忘れましたぁ!実は↑のコードは「正常にコンパイルされ、動くことは動き」ます。ただ、動画ファイルを読み込んで再生しても「音しか出ない」だけです。まぁ、画像処理部分が解説した通りなので、再生されるわけがないのですが...