プロデルでWPFのMediaElementを使ったメディアプレーヤを無理やり作る

## プロデルで無理やりWPF

今日は、プロデルでWPF(Windows Presentation Foundation)を無理やり使ってアプリを作ってみます。先日紹介した[プロデルで.NETのクラスを利用する方法](https://qiita.com/jpl_produire/items/50c979d38541b6d9a84d)を用いて、WPFでサポートされるメディア機能を使ったメディアプレーヤを作ってみます。

プロデルではWindows Media Player(従来版)を利用して音楽や動画を再生できます。その他にもいくつかの方法でメディアを再生できますが、これという方法がありません。WPFにはMediaElementクラスという機能が用意されていますので、この記事はこれを使えないか試行錯誤した結果を書いたものです。


## WPFのWindowを表示する
では早速、Qiitaで紹介した「ネット型」を用いて、WPFのSystem.Windows.Windowクラスを作成します。アセンブリ名は、PresentationFrameworkを主に使います。

Visual Studioでは、XAMLを追加することでウィンドウが表示されますが、プロデルではXAMLのデザインに対応していないので、コントロールを配置する部分もプログラムで指示する必要があります。このあたりもC#とは勝手が異なります。

```
※コンソール
"System.Windows.Application,PresentationFramework"のネット型を作ってappとする
"System.Windows.Window,PresentationFramework"のネット型を作ってwindowとする
windowのTitleは、「WPFのウィンドウ」
windowのWidth=500
windowのHeight=500
window:Show()
app:Run(window)
```

「作る」文でSystem.Windows.Windowクラスのインスタンスを作って、作ったオブジェクトについてプロパティを設定していきます。最後にShow()メソッドを呼び出します。

また、System.Windows.Application.Run()メソッドは、エントリーポイントとして最初に表示するウィンドウを指定して、メッセージループするために使います。プロデルでは「待機する」手順に相当する機能です。つまり、ウィンドウが表示されている間、アプリが終了しないようにする役割を担います。

このあたりは、一度C#でほぼ同じプログラムを書いて、動きを確認しつつプロデルに置き換えました。

なお、プロデルデザイナで実行するときに別プロセスとして実行されるように「※コンソール」を冒頭に指定しています。これは、ひとつのプロセスで複数の System.Windows.Applicationインスタンスを作成することはできないというWPFの制約があるためです。

また、プロデルではWindows FormsをもとにしたGUI部品を提供しているため、WPFのライブラリと共用できない箇所があります。一部の機能は、プロデル上でもある程度は動くものの一部動かない機能があります。もしこの記事を応用するときにはご留意ください。

## MediaElementクラスでメディアプレーヤを作る

WPFのWindowを表示できましたので、今度はMediaElementクラスでメディアを再生させてみます。WindowにMediaElementを貼り付けて、Sourceにファイル名を指定してPlay()メソッドを呼び出します。
再生位置を指定できるようにSliderクラスで「ポジションスライダ」を作ります。

Microsoftの.NETのドキュメントを参考にしながらひとつひとつ部品を貼り付けるプログラムを書いていきます。

MediaElementのSourceプロパティに.flacや.mp4のパスを指定するときは、文字列ではなくUriクラスで指定しなければならないのが注意点です。

動作環境:[プロデル1.9.1164](https://rdr.utopiat.net/files/1.9/index.php?type=exe)

```メディアプレーヤ.rdr
※コンソール
"System.Windows.Application,PresentationFramework"のネット型を作ってappとする
"System.Windows.Window,PresentationFramework"のネット型を作ってメイン画面とする
"System.Windows.Controls.Canvas,PresentationFramework"のネット型を作ってcanvasとする
メイン画面のTitleは、「プロデルでWPFを使ったメディアプレーヤー」
メイン画面のWidth=500
メイン画面のHeight=500
メイン画面のContentは、canvas
メイン画面のClosed時の手順は、メイン画面を閉じた

"System.Windows.Controls.Button,PresentationFramework"のネット型を作って再生ボタンとする
再生ボタンのContent=「再生」
再生ボタンのWidth=150
再生ボタンのHeight=50
再生ボタンのClick時の手順は、再生ボタンをクリックした
canvasのChildren:Add(再生ボタン)

//https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.controls.button?view=netframework-4.8
"System.Windows.Controls.Button,PresentationFramework"のネット型を作って停止ボタンとする
停止ボタンのContent=「一時停止」
停止ボタンのWidth=150
停止ボタンのHeight=50
canvas:SetLeft(停止ボタン, 200)
停止ボタンのClick時の手順は、停止ボタンをクリックした
canvasのChildren:Add(停止ボタン)

//https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.controls.slider?view=netframework-4.8
"System.Windows.Controls.Slider,PresentationFramework"のネット型を作ってポジションスライダとする
ポジションスライダのWidth=350
ポジションスライダのHeight=100
canvas:SetLeft(ポジションスライダ, 0)
canvas:SetTop(ポジションスライダ, 50)
ポジションスライダのValueChanged時の手順は、スライドした
canvasのChildren:Add(ポジションスライダ)

//https://learn.microsoft.com/ja-jp/dotnet/api/system.windows.controls.mediaelement?view=netframework-4.8
メディア要素という"System.Windows.Controls.MediaElement,PresentationFramework"のネット型を作る
メディア要素のLoadedBehavior=「Manual」
メディア要素のWidth=400
メディア要素のHeight=400
メディア要素のMediaOpened時の手順は、読み込んだ
canvas:SetLeft(メディア要素, 0)
canvas:SetTop(メディア要素, 100)
canvasのChildren:Add(メディア要素)

URLという"System.Uri,System"のネット型(「Music.flac」)を作る
//URLという"System.Uri,System"のネット型(「Video.mp4」)を作る

メイン画面:Show()
app:Run(メイン画面)

読み込んだ手順
	合計秒数は、メディア要素のNaturalDurationのTimeSpanの合計秒数
	ポジションスライダのMaximumは、合計秒数
終わり
再生ボタンをクリックした手順
	メディア要素のSource=URL
	メディア要素:Play()
終わり
停止ボタンをクリックした手順
	メディア要素:Pause()
終わり
スライドした手順
	値という日時期間形式(「0:00」)を作る
	値へ(この時のNewValue)秒足す
	メディア要素のPositionは、値
終わり

メイン画面を閉じた手順
	メディア要素:Stop()
	終了する
終わり
```

※MediaElementクラスだけを作れば、普段のプロデルのGUIでメディアを再生できるのではないか?っと思い試してみましたがどうやらWPFのWindow上に配置しないと再生できないようです

## 実行画面

大雑把になりましたが、何とかメディアプレーヤに必要なパーツがある画面ができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101225/ad974078-3c41-f0c6-a342-227ed6b24991.png)

プロデルのGUIとは異なりWPFで表現できる部品類はより最近のアプリっぽい画面が作れ奥が深いのですが、今日はここまでにしたいと思います。

## まとめ
今回の記事は、日本語プログラミングの欠片もなく、本来はもっとプロデルらしいプログラムを書きたいところでしたが、プロデルでこんなこともできる。豊富な.NETのライブラリからどうしてもプロデルで使いたい機能がある、という時などに参考になるかと思います。

メディアプレーヤを作ってみましたが、結論としてはMediaElementクラスを使うよりも既存のWindows Media Playerプラグインを使う方法がプロデルでは扱いやすいと思いました。

次回はプロデルらしいプログラムを作ります。