【WPF】 簡易動画プレーヤーを作成する
今回は動画のプレーヤーを作ってみます(簡易的なものですが)。調べてみるとWPFにはMediaElementというものがあって、これを使ってみると良さそうです。 まずはxamlが以下のようになります。
<Window x:Class="CSMediaPlayer.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:CSMediaPlayer" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="6*"/> <RowDefinition Height="1*"/> </Grid.RowDefinitions> <MediaElement Name="MediaElementMovie" Grid.Row="0" Stretch="Fill" LoadedBehavior="Manual" UnloadedBehavior="Manual"/> <Grid Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="4*"/> </Grid.ColumnDefinitions> <Button Name="ButtonPlay" Grid.Column="0" Content="▶" Click="ButtonPlay_Click"/> <Button Name="ButtonPause" Grid.Column="1" Content="||" Click="ButtonPause_Click"/> <Button Name="ButtonStop" Grid.Column="2" Content="■" Click="ButtonStop_Click"/> <Grid Grid.Column="3"> <Slider Name="SliderMoviePosition" VerticalAlignment="Center" Minimum="0" Maximum="100" ValueChanged="SliderMoviePosition_ValueChanged"/> </Grid> </Grid> </Grid> </Window>
上記のXAMLでこんな感じの見た目になります。あとはボタンやスライダーにイベントを割り振っていきます。
using System; using System.Windows; using System.Windows.Threading; namespace CSMediaPlayer { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { // 動画の相対パス private readonly string _videoPath = "video.avi"; // スライダーを動かすためのタイマー private DispatcherTimer _timer = new DispatcherTimer(); // タイマー起動間隔(1秒) private const int _timerInterval = 1; // 動画経過時間 private int _elapsedSec = 0; // スライダーをユーザーが動かしたかどうか判別するフラグ private bool _sliderValueChangedByProgram = false; public MainWindow() { InitializeComponent(); _timer.Interval = new TimeSpan(0, 0, _timerInterval); _timer.Tick += dispatcherTimer_Tick; } private void dispatcherTimer_Tick(object sender, EventArgs e) { // 動画経過時間に合わせてスライダーを動かす _elapsedSec += _timerInterval; double totalSec = MediaElementMovie.NaturalDuration.TimeSpan.TotalSeconds; SliderMoviePosition.Value = _elapsedSec / totalSec * SliderMoviePosition.Maximum; _sliderValueChangedByProgram = true; } private void ButtonPlay_Click(object sender, RoutedEventArgs e) { // 動画を再生 _timer.Start(); MediaElementMovie.Source = new Uri(_videoPath, UriKind.Relative); MediaElementMovie.Play(); } private void ButtonPause_Click(object sender, RoutedEventArgs e) { // 動画を一次停止 _timer.Stop(); MediaElementMovie.Pause(); } private void ButtonStop_Click(object sender, RoutedEventArgs e) { // 動画を停止 _timer.Stop(); _elapsedSec = 0; SliderMoviePosition.Value = 0; MediaElementMovie.Stop(); MediaElementMovie.Source = null; } private void SliderMoviePosition_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) { if (!_sliderValueChangedByProgram) { // スライダーを動かした位置に合わせて動画の再生箇所を更新する double totalSec = MediaElementMovie.NaturalDuration.TimeSpan.TotalSeconds; double sliderValue = SliderMoviePosition.Value; int targetSec = (int)(sliderValue * totalSec / SliderMoviePosition.Maximum); _elapsedSec = targetSec; TimeSpan ts = new TimeSpan(0, 0, 0, targetSec); MediaElementMovie.Position = ts; } _sliderValueChangedByProgram = false; } } }
参考にしたサイトはここです(方法 : MediaElement (再生、一時停止、停止、ボリューム、および速度) を制御する )。サイトでは様々なイベントを定義しているので、きちんと作るのであれば上記コードは改善しないといけなさそうです。。。