更新日: 2010 年 12 月 17 日

Visual Basic の内容はこちらに掲載しています。10 行でズバリ!! [VB] Silverlight - メディアの再生

このコンテンツのポイント

  • 動画の再生
  • 再生中の制御

今回紹介するコード


using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Threading;

namespace SampleMediaPlayer
{
   public partial class MainPage : UserControl
   {
       DispatcherTimer timer = new DispatcherTimer();

       public MainPage()
       {
           InitializeComponent();
           timer.Interval = new TimeSpan(0, 0, 0, 0, 200);
           timer.Tick += new EventHandler(timer_Tick);

       }

       private void btnPlay_Click(object sender, RoutedEventArgs e)
       {
           media1.Play();
           timer.Start();

       }

       private void btnPause_Click(object sender, RoutedEventArgs e)
       {
           if (media1.CurrentState == MediaElementState.Paused)
               media1.Play();
           else
               media1.Pause();
       }

       private void btnStop_Click(object sender, RoutedEventArgs e)
       {
           media1.Stop();
           timer.Stop();

       }

       private void media1_MediaOpened(object sender, RoutedEventArgs e)
       {
           slider1.Maximum = media1.NaturalDuration.TimeSpan.Ticks;
       }

       void timer_Tick(object sender, EventArgs e)
       {
           slider1.Value = media1.Position.Ticks;
       }

       private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
       {
           if (slider1.Value != media1.Position.Ticks)
               media1.Position = TimeSpan.FromTicks((long)slider1.Value);
       }

       private void sliderVolume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
       {
           if (media1 != null)
               media1.Volume = sliderVolume.Value;
       }
   }
}

目次

  1. はじめに
  2. サンプル アプリケーションの作成準備
  3. プロジェクトに動画ファイルを追加する
  4. MediaElement によるメディア再生
  5. 再生の制御
  6. 音量を変更する
  7. おわりに

1. はじめに

Silverlight は、動画や音声といったメディアを扱うための MediaElement というコントロールを提供しています。

今回は、簡単なアプリケーションを作成して、こうしたメディアの再生について解説します。なお、再生用の動画や音声は別途用意する必要があります。Windows に付属しているサンプル ビデオなどをお使いください。

ページのトップへ


2. サンプル アプリケーションの作成準備

まず、Visual Studio を起動して、[ファイル] メニューの [新規作成] から [プロジェクト] をクリックし、[新しいプロジェクト] を開きます。次に、[インストールされたテンプレート] で [Silverlight] カテゴリーにある [Silverlight アプリケーション] を選びます。[名前] には任意のプロジェクト名を指定できますが、ここでは「SampleMediaPlayer」とします。

図 1. [新しいプロジェクト] ダイアログで Silverlight アプリケーションのプロジェクトを新規作成

[OK] をクリックすると、[新しい Silverlight アプリケーション] ダイアログが表示され、これから作成する Silverlight アプリケーションが埋め込まれた Web ページを持つ Web サイトを作成するかどうかと、Silverlight のバージョンが確認されます。ここでは、[Silverlight アプリケーションを新しい Web サイトでホストする] のチェックを外します。これで、この Silverlight アプリケーションを実行しようとするたびに、仮の Web サイトが自動作成されます。Silverlight のバージョンは、「Silverlight 4」のままにしておきます。

図 2. [新しい Silverlight アプリケーション] ダイアログ

[OK] ボタンをクリックすると、SampleMediaPlayer ソリューションと、Silverlight アプリケーションのための SampleMediaPlayer プロジェクトが作成されます。

図 3. プロジェクト作成直後の Visual Studio 2010

ページのトップへ


3. プロジェクトに動画ファイルを追加する

まず、ソリューション エクスプローラーでプロジェクト名 (SampleMediaPlayer) を右クリックし、[追加] - [既存の項目] メニューを呼び出します。ここで動画ファイルを選びます。Windows 自身のサンプル動画 (<ビデオ/パブリックのビデオ/サンプル ビデオ> フォルダーに入っているものなど) を追加してもよいでしょう。

今回は、外部ファイルとして動画を再生するため、動画ファイルを選んでプロパティ ウィンドウで「ビルド アクション」を「なし」に、「出力ディレクトリにコピー」を「新しい場合はコピーする」に設定します。なお、Silverlight をホストする Web アプリケーションを作成している場合は、メディア ファイルを Web アプリケーション プロジェクトの ClientBin (Silverlight アプリケーションを保持するフォルダー) にコピーしておく必要があります。

図 4. メディア ファイルのプロパティを設定

Note: Silverlight で扱えるメディア ファイルの形式 (動画、音声) については、「サポートされるメディア形式、プロトコル、ログ フィールド」を参照してください。

ページのトップへ


4. MediaElement によるメディア再生

メディアを扱うために MediaElement というコントロールが用意されているので、これを MainPage.xaml に配置します。後で追加するコントロールの領域も確保しておくため、Grid を使って次のように記述します。

<UserControl x:Class="SampleMediaPlayer.MainPage"
   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"
   mc:Ignorable="d"
   d:DesignHeight="300" d:DesignWidth="400">

   <Grid x:Name="LayoutRoot" Background="White">
       <Grid.RowDefinitions>
           <RowDefinition Height="Auto" />
           <RowDefinition Height="Auto" />
           <RowDefinition Height="Auto" />
           <RowDefinition Height="*" />
       </Grid.RowDefinitions>
       <MediaElement Grid.Row="0" x:Name="media1" Height="240" Source="Bear.wmv" />

   </Grid>
</UserControl>

ここで、Source はメディア ファイルを指定するプロパティです (ここでは Bear.wmv という動画ファイルを指定しています)。このまま、アプリケーションを実行すると、図 5 のように動画が自動的に再生されます。

図 5. MediaElement を使って動画を再生

再生できるものは、動画だけではなく音声 (WMA、MP3) も含まれます。動画ファイルの代わりに音声ファイルを割り当てれば、音声が再生されます。ここで、MediaElement はユーザー インターフェイスとして配置するコントロールであり、どこかに配置しなければ使えないことに注意してください。プログラムで、MediaElement オブジェクトを生成して、Source プロパティに (表示されることのない) 音声ファイルを指定しても、MainPage の Children に追加せずに再生することはできません。

ページのトップへ


5. 再生の制御

MediaElement は、デフォルトでは割り当てられたメディアを自動再生しますが、自動再生を抑止したり、プログラムで再生や停止を制御したりできます。まず、このためのボタンを追加します。

<UserControl x:Class="SampleMediaPlayer.MainPage"
  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"
  mc:Ignorable="d" FontSize="16"
  d:DesignHeight="300" d:DesignWidth="400">

  <Grid x:Name="LayoutRoot" Background="White">
      <Grid.RowDefinitions>
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="Auto" />
          <RowDefinition Height="*" />
      </Grid.RowDefinitions>
      <MediaElement Grid.Row="0" x:Name="media1" Height="240" AutoPlay="False" Source="Bear.wmv" />
      <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
          <Button x:Name="btnPlay" Content="再生" Click="btnPlay_Click" />
          <Button x:Name="btnPause" Content="一時停止" Click="btnPause_Click" />
          <Button x:Name="btnStop" Content="停止" Click="btnStop_Click" />
      </StackPanel>

  </Grid>
</UserControl>

自動再生を抑止するためには MediaElement の AutoPlay プロパティを False にします。

それぞれのボタンの Click イベント ハンドラーは次のように記述します。

       private void btnPlay_Click(object sender, RoutedEventArgs e)
       {
           media1.Play();
       }
 
       private void btnPause_Click(object sender, RoutedEventArgs e)
       {
           if (media1.CurrentState == MediaElementState.Paused)
               media1.Play();
           else
               media1.Pause();
       }

       private void btnStop_Click(object sender, RoutedEventArgs e)
       {
           media1.Stop();
       }

ここでは、すでに再生が一時停止しているときに一時停止 (Pause) ボタンを押すと、再生が始まるようにしています。このように、MediaElement の CurrentState プロパティを使えば、現在のメディアの状態を確認できます。

プログラムを実行している様子を図 6 に示します。

図 6. 再生を制御するボタンを追加

さらに、再生位置を表示するスライダーを追加します。

           <RowDefinition Height="*" />
       </Grid.RowDefinitions>
       <MediaElement Grid.Row="0" x:Name="media1" Height="240" AutoPlay="False" Source="Bear.wmv"
                     MediaOpened="media1_MediaOpened"/>
       <Slider Grid.Row="1" x:Name="slider1" ValueChanged="slider1_ValueChanged" />

       <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
           <Button x:Name="btnPlay" Content="再生" Click="btnPlay_Click" />
           <Button x:Name="btnPause" Content="一時停止" Click="btnPause_Click" />
           <Button x:Name="btnStop" Content="停止" Click="btnStop_Click" />
       </StackPanel>

それぞれのボタンの Click イベント ハンドラーは次のように記述します。

using System.Windows.Shapes;
using System.Windows.Threading;

namespace SampleMediaPlayer
{
   public partial class MainPage : UserControl
   {
       DispatcherTimer timer = new DispatcherTimer();

       public MainPage()
       {
           InitializeComponent();
           timer.Interval = new TimeSpan(0, 0, 0, 0, 200);
           timer.Tick += new EventHandler(timer_Tick);

       }

       private void btnPlay_Click(object sender, RoutedEventArgs e)
       {
           media1.Play();
           timer.Start();
       }

       private void btnPause_Click(object sender, RoutedEventArgs e)
       {
           if (media1.CurrentState == MediaElementState.Paused)
               media1.Play();
           else
               media1.Pause();
       }

       private void btnStop_Click(object sender, RoutedEventArgs e)
       {
           media1.Stop();
           timer.Stop();
       }
 

       private void media1_MediaOpened(object sender, RoutedEventArgs e)
       {
           slider1.Maximum = media1.NaturalDuration.TimeSpan.Ticks;
       }

       void timer_Tick(object sender, EventArgs e)
       {
           slider1.Value = media1.Position.Ticks;
       }

       private void slider1_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
       {
           if (slider1.Value != media1.Position.Ticks)
               media1.Position = TimeSpan.FromTicks((long)slider1.Value);
       }

   }

MediaElement には、再生の進行に合わせて発生するイベントはないため、タイマー (DispatcherTimer) を使っています。まず、メディアをオープンした時点で、スライダーにメディアの長さを Tick 単位で割り当てておき、200 ミリ秒 (0.2 秒) ごとに発生するよう設定したタイマーの Tick イベントで、スライダーに現在の位置 (Tick 単位) を割り当てています。

スライダーを移動したときに発生する ValueChanged イベントでは、逆にスライダーの位置から再生位置を変更しています。上記のタイマーによる Tick イベントでスライダーの Value プロパティを変更したときにも ValueChanged イベントが発生することに注意してください。この直後はスライダーの Value プロパティとメディアの再生位置が一致しているはずなので、再生位置を設定しなおさないようにします (そうでないとメディアの再生がぎこちなくなってしまいます)。

プログラムを実行している様子を図 7 に示します。

図 7. 再生位置を表示・制御するスライダーを追加

Note: MediaElement の Position プロパティと Slider の Value プロパティを連動させるためにデータ バインディングを使わないようにしてください。非常に短い間隔で連動しようとするため、メディア再生のパフォーマンスが悪化します。

ページのトップへ


6. 音量を変更する

再生時の音量 (ボリューム) を調整してみましょう。音量調整用のスライダーを追加します。

       <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Center">
           <Button x:Name="btnPlay" Content="再生" Click="btnPlay_Click" />
           <Button x:Name="btnPause" Content="一時停止" Click="btnPause_Click" />
           <Button x:Name="btnStop" Content="停止" Click="btnStop_Click" />
           <Slider x:Name="sliderVolume" Width="100" Maximum="1.0" Value="1.0"
                   ValueChanged="sliderVolume_ValueChanged" />

       </StackPanel>

音量調整は、MediaElement の Volume プロパティに値を設定するだけです。最小値は 0、最大値は 1 なので、スライダーの最大値 (Maximum) と初期値 (Value) には 1.0 を設定します。

スライダーを移動させたときの ValueChanged イベント ハンドラーは次のように記述します。

       private void sliderVolume_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
       {
           if (media1 != null)
               media1.Volume = sliderVolume.Value;
       }

これで、再生時の音量調整ができます。

ページのトップへ


7. おわりに

Silverlight のメディア再生能力は、リリース当初からの大きな特長です。現在、Windows Media Video (WMV) および Audio (WMA) をはじめ、VC-1、H.264、MP3 といった主要な形式に対応しており、多くの動画サイトでも使われています。ぜひ、試してみてください。

関連リンク


Code Recipe Silverlight デベロッパー センター

ページのトップへ