第28回CODESEEK勉強会
第28回CODESEEK勉強会
WPFで簡単ビデオ再生
自己紹介
イントロダクション
MediaElement
MediaPlayer
独立モードとクロックモード
ビデオキャプチャ
Q&A
今日帰るときには・・・
WPF のビデオの概要
MediaElement の使い方、特徴を理解
MediaPlayer の使い方、特徴を理解
簡単なビデオプレーヤーが作れる
第28回CODESEEK勉強会
なんで、そんなことしているの?
2000 ごろは、Java/Unix 系でした
Microsoft は嫌いだったので、2000-2002 ぐらいまで、Java/Unix 系で
Web Server を立てて、HPを作っていた。
日曜管理者なので、カーネルのメインテナンスに疲れ果てた。
少し金を払ってもいいから、楽にサーバーを運用したかったので、
Windows 系に乗り換えた。
Windows 系の開発をしたことがなかったので
Visual Studio 2002 C# Beta が出たので、触ってみた。
すげー!!
コミュニティ
いろいろな素晴らしい人と出会える。
面白い!理屈はいらないでしょ。
MVPを受賞したきっかけは?
2002年に Visual Studio 2002 Beta が出た
Beta はタダだったので、使ってみた。
.NET/C# のすごさに触発された。
わからないことがいろいろあるが、C#/.NET 関連の日本語 HP がほとん
どなかった。
せっかく調べたのに、忘れてしまうともったいなので、少しづつまとめて、
宇宙仮面の C# プログラミングというページを作成していた。
すこしづつ C# ユーザーが増え、掲示板にも書きこまれるようになった。
.NET/C# Group を開始
どなたかが、MVPに推薦してくれたらしい。
最初、マルチ商法みたいで怖かったから、テキトーにあしらっていた。
Microsoft KK から直接説明があったので、お受けすることに。
2003/10 MVP for Visual Developer C# 受賞
第28回CODESEEK勉強会
MediaElement と MediaPlayer
WPF でビデオ・音声メディアを再生するには、
MediaElement、またはMediaPlayerを使います。
それぞれ特徴があるので、しっかり押さえておき
たい。
MediaElement は、WPFに統合されているので、アルファブレン
ディングや3D の表面にレンダリングも可能
MediaPlayer には直接的なビジュアル表現がないので、レイアウト
上は直接使えません。しかし、Windows Media Player ランタイ
ムを起動する必要がないため、高速に起動できます。また、ビジュ
アル表現がないので、音声の再生にも適しています。
第28回CODESEEK勉強会
MediaElementにより、単純にビデオを再生
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/prese
ntation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication3.Window1"
x:Name="Window"
Title="Window1"
Width="320" Height="240"
xmlns:d="http://schemas.microsoft.com/expression/blend/200
8" xmlns:mc="http://schemas.openxmlformats.org/markupcompatibility/2006" mc:Ignorable="d">
<Grid>
<MediaElement Source="Test.wmv"
LoadedBehavior="Play"/>
</Grid>
</Window>
Expression Blend によるWPF プロジェクトの自動生成
Expression Blend を使用してメディアを再生する
WPF プロジェクトを簡単に作ることができます。
1. WMVなどのメディアをプロジェクトに追加する。
2. WMVファイルをダブルクリックするか、フォー
ム上に Drag & Drop する。
Expression Blend によるWPF プロジェクトの自動生成
<Window ・・・>
<Window.Resources>
<Storyboard x:Key="Test_wmv">
<MediaTimeline Source="Test.wmv" BeginTime="00:00:00"
Storyboard.TargetName="Test_wmv"
d:DesignTimeNaturalDuration="233.129"/>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Test_wmv}"/>
</EventTrigger>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<MediaElement Margin="62,46,255,78" x:Name="Test_wmv"
Stretch="Fill"/>
</Grid>
</Window>
Silverlight2 によるWPF プロジェクトの自動生成
ストリーボードなしのシンプルな XAML が生成されます。
Silverlight2 では、まだ MediaTimeline がサポートされていません。
<UserControl
xmlns="http://schemas.microsoft.com/client/2007"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightApplication6.Page"
Width="320" Height="240">
<Grid x:Name="LayoutRoot" Background="White" >
<MediaElement x:Name="Test_wmv" Source="Test.wmv"
Stretch="Fill"/>
</Grid>
</UserControl>
WPF コントロールの内部にビデオを埋め込む
MediaElement コントロールは
System.Windows.UIElement クラスから継承さ
れているので、他の UIElement コントロールを
配置できるところであればどこでも配置できます。
<Button Click="Button_Click">
<MediaElement
x:Name="Test_wmv“
LoadedBehavior="Manual”
Source="Test.wmv"
Stretch="Fill“ />
</Button>
----------// C# 再生用コード
this.Test_wmv.Play();
プログレスバーの表示
MediaElement の MediaOpened でプログレス
バーの最大値を設定
Storyboard の CurrentTimeInvalidated でプロ
グレスバーの値を設定する
<MediaElement Name="myMedia"
MediaOpened="myMedia_MediaOpened"/>
…
<Storyboard Storyboard.TargetName="myMedia"
CurrentTimeInvalidated="Storyboard_CurrentTimeInvalidated">
<MediaTimeline Source="Test.wmv" x:Name="mTimeline"
BeginTime="00:00:00" Duration="00:10:05" />
</Storyboard>
プログレスバーの表示
C# 実装部分
private void Storyboard_CurrentTimeInvalidated(…)
this.progressBar1.Value =
myMedia.Position.TotalMilliseconds;
}
{
private void myMedia_MediaOpened(...){
this.progressBar1.Maximum =
myMedia.NaturalDuration.TimeSpan.TotalMilliseconds;
}
再生、停止、一時停止、再生位置の変更、ボリュームの変
更、再生スピードの調整
注意:
メディアを対話的に停止、一時停止、および再生できるようにするには、
MediaElement の LoadedBehavior プロパティを Manual に設
定する必要があります。
再生:
myMediaElement.Play();
停止:
myMediaElement.Stop();
一時停止:
myMediaElement.Pause();
再生位置の変更:
TimeSpan ts = new TimeSpan(0, 0, 0, 0, SliderValue);
myMediaElement.Position = ts;
ボリュームの変更:
myMediaElement.Volume =
(double)volumeSlider.Value;
再生スピードの調整: myMediaElement.SpeedRatio =
(double)speedRatioSlider.Value;
再生時の遅延対策
MediaElement を使用した場合、Windows Media
Player ランタイムを起動する必要があるため、メ
ディアを最初に再生するときに、遅延が生じる場合
があります。
このため、メディア ファイルとユーザー イベント
やアニメーションと正確に同期を取って再生するこ
とができません。
対策
1. メディア ファイルを事前に読み込み、使用準備が整うまで一時停
止状態にしておく。
2. <Storyboard SlipBehavior="Slip">
を指定します。すると、メディアの再生が開始するまで、アニメー
ションが停止してくれます。
ビデオを 3D の表面にマップする
ModelVisual3D の中で、VisualBrush の MediaElement ソースにメ
ディアファイルを指定します。
<GeometryModel3D.Material>
<DiffuseMaterial>
<DiffuseMaterial.Brush>
<VisualBrush>
<VisualBrush.Visual>
<MediaElement Source="Test.wmv" />
</VisualBrush.Visual>
</VisualBrush>
</DiffuseMaterial.Brush>
</DiffuseMaterial>
</GeometryModel3D.Material>
第28回CODESEEK勉強会
MediaPlayer の用途
メディアを再生するもう一つの方法として、
MediaPlayer があります。
MediaElement は、基本的に MediaPlayer クラ
スのラッパーなので、MediaElement で実現でき
ることは MediaPlayer で実現できます。
MediaPlayer は
- 音楽を再生する
- より複雑な処理
に使用します。
主なプロパティ
MediaPlayerのプロパティや、イベントを設定することに
より、たとえば次のような操作が可能です。
メディア ファイルの位置を取得または設定 Position プロ
パティに TimeSpan オブジェクトを設定します。
例
バッファリングの進行状況 BufferingProgress プロパティ
再生の進行状況
DownloadProgress プロパティ
オーディオ コントロール
Balance プロパティ、
Volume プロパティを設定
メディアの開始を知る
MediaOpened イベント
メディアの終了を知る
MediaEnded イベント
ビデオを 3D の表面にマップする
WAV オーディオだけの再生であれば、
System.Media.SoundPlayer クラスが利用できます。
いろいろな種類の音楽を再生するには、MediaPlayer クラ
スを使用するのが良いでしょう。
MediaPlayer mp = new MediaPlayer();
Try
{
mp.Open(new Uri(@"..\..\Test.wma", UriKind.Relative));
mp.Play();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
MediaPlayer, DrawingBrush を使って、ビデオをコント
ロールに描画する
<Rectangle Stroke="Black" MouseDown="OnClick1" …>
<Rectangle.RenderTransform>
<TransformGroup>
…
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<VideoDrawing x:Name="MyVideoDrawing“… />
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
MediaPlayer, DrawingBrush を使って、ビデオをコント
ロールに描画する
C# 実装部分
void OnClick1(object sender, RoutedEventArgs e)
{
MediaPlayer MyPlayer = new MediaPlayer();
MyPlayer.Open(new Uri(@“..\..\Test.wmv”,
UriKind.Relative));
MyVideoDrawing.Player = MyPlayer;
MyPlayer.Play();
}
2つのビジュアルに同時プレイ
C# 実装部分
void OnLoaded(object sender, RoutedEventArgs e)
{
MediaPlayer MyPlayer = new MediaPlayer();
MyPlayer.Open(new Uri(@"..\..\Test.wmv",
UriKind.Relative));
MyVideoDrawing.Player = MyPlayer;
MyVideoDrawing1.Player = MyPlayer;
MyPlayer.Play();
}
第28回CODESEEK勉強会
独立モードとクロックモード
MediaElement、および MediaPlayer は、独立モードとク
ロック モードの2つのモードがあります。
通常の再生だけであれば、独立モードで OK です。
独立モード
<MediaElement Source="Test.wmv" Width="320"
Height="240" LoadedBehavior="Play"/>
クロックモード
Expression Blend で、メディアを追加した場合、クロック
モードで WPF が生成されます。
Clock が null の場合
MediaElement はイメージに似ており、直接 Source URI を
指定できます。
標準のメディアを再生および制御する場合、Storyboard や
MediaTimeline を扱う必要はありません。
通常の再生だけであれば、独立モードで OK です。
Clock が null の場合、メディア オブジェクトは独立モード
です。
特徴
- メディアの Uri を直接指定することができます。
- メディアの再生を直接制御できます。
- メディアの Position プロパティと SpeedRatio プロパ
ティを変更できます。
独立モードの例
<MediaElement Source="Test.wmv" Width="320"
Height="240" LoadedBehavior="Play"/>
Clock が Null ではない場合
MediaElement は、MediaTimeline によって、メディアの再
生が実行されます。
特徴
- メディアの Uri は、MediaTimeline を通じて間接的に設
定されます。
- メディアの再生をクロックで制御できます。メディア オ
ブジェクトのコントロール メソッドは使用できません。
Expression Blend で、メディアを追加した場合、クロッ
クモードで WPF が生成されます。
ClockController プロパティを使用すれば、対話形式でク
ロックを開始、 一時停止、再開、シーク、区間の最後ま
での前進、停止ができます。
クロックモード
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Test_wmv.Clock.Controller.Pause();
// クロックのPause
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
this.Test_wmv.Clock.Controller.Seek(new TimeSpan(0, 0, 30),
TimeSeekOrigin.BeginTime);
// クロックをシーク
this.Test_wmv.Clock.Controller.Resume();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
MediaTimeline mTimeline =
new MediaTimeline(new Uri(@"..\..\Test.wmv", UriKind.Relative));
MediaClock mClock = mTimeline.CreateClock();
this.Test_wmv.Clock = mClock;
this.Test_wmv.Clock.Controller.Begin();
}
第28回CODESEEK勉強会
<Rectangle Stroke="Black" MouseLeftButtonDown="Rectangle_MouseDown"
RenderTransformOrigin="0.5,0.5" Margin="102,11,14,0"
Height="89.305" VerticalAlignment="Top">
<Rectangle.RenderTransform>
<TransformGroup>
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Fill>
<DrawingBrush>
<DrawingBrush.Drawing>
<VideoDrawing x:Name="MyVideoDrawing…/>
</DrawingBrush.Drawing>
</DrawingBrush>
</Rectangle.Fill>
</Rectangle>
<Image Height="30" HorizontalAlignment="Left“ Name="image1"
Stretch="Fill" VerticalAlignment="Top" Width="72" />
C# 実装部分
MediaPlayer MyPlayer = new MediaPlayer();
private void Rectangle_MouseDown(…) {
MyPlayer.Open(new Uri(@"..\..\Test.wmv", UriKind.Relative));
MyVideoDrawing.Player = MyPlayer;
MyPlayer.Play();
}
private void button1_Click(…) {
RenderTargetBitmap rtb = new RenderTargetBitmap((int)image1.Width, (int)image1.Height, 1 / 200,
1 / 200, PixelFormats.Pbgra32);
DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();
dc.DrawVideo(MyPlayer, new Rect(0, 0, (int)image1.Width, (int)image1.Height));
dc.Close();
rtb.Render(dv);
this.image1.Source = BitmapFrame.Create(rtb);
using (FileStream stream = new FileStream("capture.png", FileMode.Create))
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
encoder.Save(stream);
}
}
}
{
宇宙仮面の C#
http://uchukamen.com
WPF を使ってコントロールと 3D の表面にビデオを追加する
http://msdn.microsoft.com/ja-jp/magazine/cc163455.aspx
MSDN MediaElement クラス
http://msdn.microsoft.com/ja-jp/library/system.windows.controls.mediaelement.aspx
ダウンロード

自己紹介 イントロダクション MediaElement MediaPlayer 独立モードと