Xamarin Community Toolkit MediaElement
MediaElement
は、ビデオとオーディオを再生するためのビューです。 基になるプラットフォームでサポートされているメディアは、次のソースから再生できます。
- URI (HTTP または HTTPS) を使用する Web。
- URI スキームを使用して、プラットフォーム アプリケーションに
ms-appx:///
埋め込まれたリソース。 - URI スキームを使用して、アプリのローカルおよび一時データ フォルダーから取得された
ms-appdata:///
ファイル。 - デバイスのライブラリ。
MediaElement
は、トランスポート コントロールと呼ばれるプラットフォーム再生コントロールを使用できます。 ただし、既定では無効になっており、独自のトランスポート コントロールに置き換えることができます。 次のスクリーンショットは、プラットフォーム トランスポート コントロールを使用したビデオの再生を示 MediaElement
しています。
Note
MediaElement
は、iOS、Android、ユニバーサル Windows プラットフォーム (UWP)、macOS、Windows Presentation Foundation、Tizen で使用できます。
MediaElement
は次の特性を定義します。
Aspect
型Aspect
の は、メディアを表示領域に合わせてスケーリングする方法を決定します。 このプロパティの既定値はAspectFit
です。AutoPlay
型bool
の は、 プロパティが設定されたときにメディアの再生をSource
自動的に開始するかどうかを示します。 このプロパティの既定値はtrue
です。BufferingProgress
型double
の 。 は、現在のバッファリングの進行状況を示します。 このプロパティの既定値は 0.0 です。CanSeek
型bool
の は、 プロパティの値を設定することでメディアのPosition
位置を変更できるかどうかを示します。 これは、読み取り専用プロパティです。CurrentState
型MediaElementState
の は、コントロールの現在の状態を示します。 これは読み取り専用プロパティで、既定値は ですMediaElementState.Closed
。Duration
型TimeSpan?
の 。 は、現在開いているメディアの期間を示します。 これは、既定値が である読み取り専用プロパティですnull
。IsLooping
型bool
の は、現在読み込まれているメディア ソースが、最後に到達した後に最初から再生を再開する必要があるかどうかを示します。 このプロパティの既定値はfalse
です。KeepScreenOn
型bool
の 。 は、メディアの再生中にデバイス画面をオンにするかどうかを決定します。 このプロパティの既定値はfalse
です。Position
型TimeSpan
の は、メディアの再生時間の現在の進行状況を表します。 このプロパティはバインディングをTwoWay
使用し、既定値は ですTimeSpan.Zero
。ShowsPlaybackControls
の型bool
は、プラットフォームの再生コントロールを表示するかどうかを決定します。 このプロパティの既定値はfalse
です。 iOS では、コントロールは画面を操作した後に短時間だけ表示されることに注意してください。 コントロールを常に表示する方法はありません。 WPF では、システム コントロールはサポートされていないため、このプロパティは無効です。Speed
の種類double
は、メディアの再生速度を決定します。 このプロパティの既定値は 1 です。Source
型MediaSource
の は、コントロールに読み込まれたメディアのソースを示します。VideoHeight
型int
の は、コントロールの高さを示します。 これは、読み取り専用プロパティです。VideoWidth
型int
の は、コントロールの幅を示します。 これは、読み取り専用プロパティです。Volume
型double
の は、メディアのボリュームを決定します。メディアのボリュームは、0 から 1 の間の線形スケールで表されます。 このプロパティはバインディングをTwoWay
使用し、既定値は 1 です。
プロパティを除 CanSeek
くこれらのプロパティは、オブジェクトによって BindableProperty
サポートされます。つまり、データ バインディングのターゲットにすることができ、スタイルを設定できます。
クラスでは、次 MediaElement
の 4 つのイベントも定義されます。
MediaOpened
は、メディア ストリームが検証されて開かれたときに発生します。MediaEnded
は、メディアのMediaElement
再生が完了したときに発生します。MediaFailed
は、メディア ソースに関連するエラーが発生したときに発生します。SeekCompleted
は、要求されたシーク操作のシーク ポイントが再生の準備ができたときに発生します。
さらに、 には、MediaElement
、Pause
、 Stop
メソッドが含Play
まれます。
Android でサポートされているメディア形式の詳細については、「developer.android.com で サポートされているメディア形式 」を参照してください。 ユニバーサル Windows プラットフォーム (UWP) でサポートされているメディア形式の詳細については、「サポートされているコーデック」を参照してください。
リモート メディアを再生する
は MediaElement
、HTTP および HTTPS URI スキームを使用してリモート メディア ファイルを再生できます。 これを行うには、 プロパティを Source
メディア ファイルの URI に設定します。
<MediaElement Source="https://sec.ch9.ms/ch9/5d93/a1eab4bf-3288-4faf-81c4-294402a85d93/XamarinShow_mid.mp4"
ShowsPlaybackControls="True" />
既定では、 プロパティで定義されているメディアは、メディアを Source
開いた直後に再生されます。 メディアの自動再生を抑制するには、 プロパティを AutoPlay
に false
設定します。
メディア再生コントロールは既定で無効になっており、 プロパティを ShowsPlaybackControls
に true
設定することで有効になります。 MediaElement
では、プラットフォーム再生コントロールが使用可能な場合に使用されます。
ローカル メディアを再生する
ローカル メディアは、次のソースから再生できます。
- URI スキームを使用して、プラットフォーム アプリケーションに
ms-appx:///
埋め込まれたリソース。 - URI スキームを使用して、アプリのローカルおよび一時データ フォルダーから取得された
ms-appdata:///
ファイル。 - デバイスのライブラリ。
これらの URI スキームの詳細については、「 URI スキーム」を参照してください。
アプリ パッケージに埋め込まれたメディアを再生する
は MediaElement
、URI スキームを使用して、アプリ パッケージに埋め込まれているメディア ファイルを ms-appx:///
再生できます。 メディア ファイルは、プラットフォーム プロジェクトに配置することで、アプリ パッケージに埋め込まれます。
プラットフォーム プロジェクトにメディア ファイルを格納する方法は、プラットフォームごとに異なります。
- iOS では、メディア ファイルは Resources フォルダーまたは Resources フォルダーのサブフォルダーに格納する必要があります。 メディア ファイルには、 の
BundleResource
がBuild Action
必要です。 - Android では、メディア ファイルは raw という名前の Resources のサブフォルダーに格納する必要があります。 raw フォルダーにサブフォルダーを含めることはできません。 メディア ファイルには、 の
AndroidResource
がBuild Action
必要です。 - UWP では、メディア ファイルはプロジェクト内の任意のフォルダーに格納できます。 メディア ファイルには、 の
Content
がBuildAction
必要です。
これらの条件を満たすメディア ファイルは、URI スキームを ms-appx:///
使用して再生できます。
<MediaElement Source="ms-appx:///XamarinForms101UsingEmbeddedImages.mp4"
ShowsPlaybackControls="True" />
データ バインディングを使用する場合は、値コンバーターを使用して次の URI スキームを適用できます。
public class VideoSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
if (string.IsNullOrWhiteSpace(value.ToString()))
return null;
if (Device.RuntimePlatform == Device.UWP)
return new Uri($"ms-appx:///Assets/{value}");
else
return new Uri($"ms-appx:///{value}");
}
// ...
}
その後、 VideoSourceConverter
のインスタンスを使用して、 ms-appx:///
埋め込みメディア ファイルに URI スキームを適用できます。
<MediaElement Source="{Binding MediaSource, Converter={StaticResource VideoSourceConverter}}"
ShowsPlaybackControls="True" />
ms-appx URI スキームの詳細については、「 ms-appx と ms-appx-web」を参照してください。
アプリのローカル フォルダーと一時フォルダーからメディアを再生する
は MediaElement
、URI スキームを使用して、アプリのローカルまたは一時データ フォルダーにコピーされたメディア ファイルを ms-appdata:///
再生できます。
次の例は、アプリの Source
ローカル データ フォルダーに格納されているメディア ファイルに設定された プロパティを示しています。
<MediaElement Source="ms-appdata:///local/XamarinVideo.mp4"
ShowsPlaybackControls="True" />
次の例は、アプリの Source
一時データ フォルダーに格納されているメディア ファイルの プロパティを示しています。
<MediaElement Source="ms-appdata:///temp/XamarinVideo.mp4"
ShowsPlaybackControls="True" />
重要
UWP は、アプリのローカルまたは一時データ フォルダーに格納されているメディア ファイルを再生するだけでなく、アプリのローミング フォルダーにあるメディア ファイルを再生することもできます。 これは、メディア ファイルの前に を付 ms-appdata:///roaming/
けることで実現できます。
データ バインディングを使用する場合は、値コンバーターを使用して次の URI スキームを適用できます。
public class VideoSourceConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
if (string.IsNullOrWhiteSpace(value.ToString()))
return null;
return new Uri($"ms-appdata:///{value}");
}
// ...
}
その後、 VideoSourceConverter
のインスタンスを使用して、アプリの ms-appdata:///
ローカルまたは一時データ フォルダー内のメディア ファイルに URI スキームを適用できます。
<MediaElement Source="{Binding MediaSource, Converter={StaticResource VideoSourceConverter}}"
ShowsPlaybackControls="True" />
ms-appdata URI スキームの詳細については、「 ms-appdata」を参照してください。
メディア ファイルをアプリのローカルまたは一時データ フォルダーにコピーする
アプリのローカルまたは一時データ フォルダーに格納されているメディア ファイルを再生するには、そのメディア ファイルをアプリによってそこにコピーする必要があります。 これを行うには、たとえば、アプリ パッケージからメディア ファイルをコピーします。
// This method copies the video from the app package to the app data
// directory for your app. To copy the video to the temp directory
// for your app, comment out the first line of code, and uncomment
// the second line of code.
public static async Task CopyVideoIfNotExists(string filename)
{
string folder = FileSystem.AppDataDirectory;
//string folder = Path.GetTempPath();
string videoFile = Path.Combine(folder, "XamarinVideo.mp4");
if (!File.Exists(videoFile))
{
using (Stream inputStream = await FileSystem.OpenAppPackageFileAsync(filename))
{
using (FileStream outputStream = File.Create(videoFile))
{
await inputStream.CopyToAsync(outputStream);
}
}
}
}
Note
上記のコード例では、 FileSystem
Xamarin.Essentials に含まれる クラスを使用しています。 詳細については、「 Xamarin.Essentials: ファイル システム ヘルパー」を参照してください。
デバイス ライブラリからメディアを再生する
ほとんどの最新のモバイル デバイスとデスクトップ コンピューターでは、デバイスのカメラとマイクを使用してビデオとオーディオを記録できます。 作成されたメディアは、デバイス上のファイルとして格納されます。 これらのファイルはライブラリから取得し、 によって MediaElement
再生できます。
各プラットフォームには、ユーザーがデバイスのライブラリからメディアを選択できる機能が含まれています。 Xamarin.Forms では、プラットフォーム プロジェクトはこの機能を呼び出すことができます。また、 クラスによって DependencyService
呼び出すことができます。
サンプル アプリケーションで使用されるビデオピッキング依存関係サービスは、「 図ライブラリから写真を選択する」で定義されているのと非常によく似ていますが、ピッカーはオブジェクトではなくファイル名を Stream
返します。 共有コード プロジェクトでは、 という名前 IVideoPicker
の 1 つのメソッドを定義する という名前 GetVideoFileAsync
のインターフェイスを定義します。 その後、各プラットフォームはクラスにこのインターフェイスを VideoPicker
実装します。
次のコード例は、デバイス ライブラリからメディア ファイルを取得する方法を示しています。
string filename = await DependencyService.Get<IVideoPicker>().GetVideoFileAsync();
if (!string.IsNullOrWhiteSpace(filename))
{
mediaElement.Source = new FileMediaSource
{
File = filename
};
}
ビデオ 選択依存関係サービスは、 メソッドを DependencyService.Get
呼び出して、プラットフォーム プロジェクトのインターフェイスの実装を IVideoPicker
取得することによって呼び出されます。 GetVideoFileAsync
その後、そのインスタンスで メソッドが呼び出され、返されたファイル名を使用してオブジェクトが作成FileMediaSource
され、 の プロパティにSource
設定されますMediaElement
。
ビデオの縦横比を変更する
プロパティは Aspect
、表示領域に合わせてビデオ メディアをスケーリングする方法を決定します。 既定では、このプロパティは列挙メンバーに AspectFit
設定されますが、列挙メンバーのいずれかに Aspect
設定できます。
AspectFit
は、縦横比を維持しながら、必要に応じてビデオが表示領域に収まるようにレターボックス化されることを示します。AspectFill
は、縦横比を維持しながら、ビデオが表示領域を埋めるようにクリップされることを示します。Fill
は、ビデオが表示領域を埋めるように引き伸ばされることを示します。
Position プロパティへのバインド
バインド可能なプロパティのプロパティ変更通知は、 Position
再生中に 200 ミリ秒間隔で発生します。 したがって、 プロパティは、メディアの進行状況を Slider
示すために、コントロール (または同様) にデータバインドできます。 CommunityToolkit には、 を合計秒数を表す浮動小数点値に変換TimeSpan
する も用意TimeSpanToDoubleConverter
されています。 このようにして、スライダー Maximum
をメディアの の に Duration
設定し Value
、 を に Position
設定して、正確な進行状況を提供できます。
<?xml version="1.0" encoding="UTF-8"?>
<pages:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:pages="clr-namespace:Xamarin.CommunityToolkit.Sample.Pages"
x:Class="Xamarin.CommunityToolkit.Sample.Pages.Views.MediaElementPage">
<pages:BasePage.Resources>
<xct:TimeSpanToDoubleConverter x:Key="TimeSpanConverter"/>
</pages:BasePage.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<xct:MediaElement
x:Name="mediaElement"
Source="https://sec.ch9.ms/ch9/5d93/a1eab4bf-3288-4faf-81c4-294402a85d93/XamarinShow_mid.mp4"
ShowsPlaybackControls="True"
HorizontalOptions="Fill"
SeekCompleted="OnSeekCompleted" />
<Slider Grid.Row="1" BindingContext="{x:Reference mediaElement}" Value="{Binding Position, Converter={StaticResource TimeSpanConverter}}" Maximum="{Binding Duration, Converter={StaticResource TimeSpanConverter}}">
<Slider.Triggers>
<DataTrigger TargetType="Slider"
Binding="{Binding CurrentState}"
Value="{x:Static MediaElementState.Buffering}">
<Setter Property="IsEnabled" Value="False" />
</DataTrigger>
</Slider.Triggers>
</Slider>
<Button Grid.Row="2" Text="Reset Source (Set Null)" Clicked="OnResetClicked" />
</Grid>
</pages:BasePage>
この例では、 Maximum
の Slider
プロパティは の プロパティMediaElement
にDuration
データバインドされValue
、 の Slider
プロパティは の プロパティMediaElement
にPosition
データバインドされています。 したがって、ドラッグすると Slider
、メディア再生位置が変化します。
さらに、 オブジェクトは DataTrigger
、メディアのバッファリング時に を Slider
無効にするために使用されます。 データ トリガーの詳細については、「 Xamarin.Forms トリガー」を参照してください。
Note
Android では、 と の設定にSlider
関係なく、1000 個の個別のMaximum
Minimum
ステップしかありません。 メディアの長さが 1000 秒を超える場合、2 つの異なる Position
値が の同じ Value
Slider
に対応します。 このため、上記のコードでは、新しい位置と既存の位置が全体の期間の 100 分の 1 を超えています。
MediaSource の種類について
は MediaElement
、そのプロパティを Source
リモートメディアファイルまたはローカルメディアファイルに設定することでメディアを再生できます。 プロパティは Source
型 MediaSource
であり、このクラスは 2 つの静的メソッドを定義します。
FromFile
は、引数からインスタンスをstring
返MediaSource
します。FromUri
は、引数からインスタンスをUri
返MediaSource
します。
さらに、 MediaSource
クラスには、 および Uri
引数からstring
インスタンスを返すMediaSource
暗黙的な演算子もあります。
Note
XAML で プロパティをSource
設定すると、 または Uri
からインスタンスを返MediaSource
す型コンバーターがstring
呼び出されます。
MediaSource
クラスには、次の 2 つの派生クラスもあります。
UriMediaSource
URI からリモート メディア ファイルを指定するために使用されます。 このクラスには、 にUri
設定できるプロパティがありますUri
。FileMediaSource
からローカル メディア ファイルstring
を指定するために使用されます。 このクラスには、 にFile
設定できるプロパティがありますstring
。 さらに、このクラスには、 を オブジェクトに変換する暗黙的な演算子と、 オブジェクトを に変換string
FileMediaSource
する暗黙的なFileMediaSource
演算子がありますstring
。
Note
XAML でオブジェクトをFileMediaSource
作成すると、 からstring
インスタンスを返FileMediaSource
す型コンバーターが呼び出されます。
MediaElement の状態を確認する
クラスは MediaElement
、 型の という名前 CurrentState
の読み取り専用バインド可能なプロパティを定義します MediaElementState
。 このプロパティは、メディアの再生中か一時停止中か、メディアを再生する準備がまだできていないかどうかなど、コントロールの現在の状態を示します。
MediaElementState
列挙体を使って、次のメンバーを定義できます。
Closed
は、 にMediaElement
メディアが含まれないことを示します。Opening
は、 が指定したソースを検証し、読み込もうとしていることをMediaElement
示します。Buffering
は、 が再生のためにメディアを読み込むことをMediaElement
示します。 この状態では、そのPosition
プロパティは進行しません。 がビデオをMediaElement
再生していた場合、最後に表示されたフレームが引き続き表示されます。Playing
は、 がメディア ソースを再生していることをMediaElement
示します。Paused
は、 がそのプロパティをMediaElement
進Position
めないことを示します。 がビデオをMediaElement
再生していた場合は、現在のフレームが引き続き表示されます。Stopped
は、 にMediaElement
メディアが含まれているが、再生または一時停止されていないことを示します。 プロパティPosition
は 0 で、進むことはありません。 読み込まれたメディアがビデオの場合はMediaElement
、最初のフレームが表示されます。
一般に、トランスポート コントロールを使用するときに プロパティをCurrentState
MediaElement
調べる必要はありません。 ただし、このプロパティは、独自のトランスポート コントロールを実装するときに重要になります。
カスタム トランスポート コントロールを実装する
メディア プレーヤーのトランスポート コントロールには、[ 再生]、[ 一時停止]、[ 停止] の各機能を実行するボタンが含まれます。 これらのボタンは一般的に、テキストではなく使い慣れたアイコンで識別されます。また、再生と一時停止機能は一般的に、1 つのボタンに結合されています。
既定では、 MediaElement
再生コントロールは無効になっています。 これにより、 をプログラムで制御 MediaElement
したり、独自のトランスポート コントロールを指定したりすることができます。 これをサポートするには、MediaElement
および メソッドが含まれますPlay
Pause
。Stop
次の XAML の例は、 および カスタム トランスポート コントロールを MediaElement
含むページを示しています。
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MediaElementDemos.CustomTransportPage"
Title="Custom transport">
<Grid>
...
<MediaElement x:Name="mediaElement"
AutoPlay="False"
... />
<StackLayout BindingContext="{x:Reference mediaElement}"
...>
<Button Text="▶️ Play"
HorizontalOptions="CenterAndExpand"
Clicked="OnPlayPauseButtonClicked">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding CurrentState}"
Value="{x:Static MediaElementState.Playing}">
<Setter Property="Text"
Value="⏸ Pause" />
</DataTrigger>
<DataTrigger TargetType="Button"
Binding="{Binding CurrentState}"
Value="{x:Static MediaElementState.Buffering}">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Button.Triggers>
</Button>
<Button Text="⏹ Stop"
HorizontalOptions="CenterAndExpand"
Clicked="OnStopButtonClicked">
<Button.Triggers>
<DataTrigger TargetType="Button"
Binding="{Binding CurrentState}"
Value="{x:Static MediaElementState.Stopped}">
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
</Button.Triggers>
</Button>
</StackLayout>
</Grid>
</ContentPage>
この例では、カスタム トランスポート コントロールは オブジェクトとして Button
定義されています。 ただし、1 つ目が Play と Pause を表し、2 つ目Button
が Stop を表すオブジェクトは 2 Button
Button
つだけです。 DataTrigger
オブジェクトは、ボタンを有効または無効にし、最初のボタンを [再生 ] と [ 一時停止] の間で切り替えるために使用されます。 データ トリガーの詳細については、「 Xamarin.Forms トリガー」を参照してください。
分離コード ファイルには、イベントのハンドラーがあります Clicked
。
void OnPlayPauseButtonClicked(object sender, EventArgs args)
{
if (mediaElement.CurrentState == MediaElementState.Stopped ||
mediaElement.CurrentState == MediaElementState.Paused)
{
mediaElement.Play();
}
else if (mediaElement.CurrentState == MediaElementState.Playing)
{
mediaElement.Pause();
}
}
void OnStopButtonClicked(object sender, EventArgs args)
{
mediaElement.Stop();
}
[再生] ボタンを押すと、有効になったら再生を開始できます。
[一時停止] ボタンを押すと、再生が一時停止します。
[停止] ボタンを押すと再生が停止し、メディア ファイルの位置が先頭に戻ります。
カスタム ボリューム コントロールを実装する
各プラットフォームによって実装されるメディア再生コントロールには、ボリューム バーが含まれます。 このバーはスライダーに似ていて、メディアの音量を示しています。 さらに、ボリューム バーを操作してボリュームを増減することもできます。
次の例に示すように、 を使用して Slider
カスタム ボリューム バーを実装できます。
<StackLayout>
<MediaElement AutoPlay="False"
Source="{StaticResource AdvancedAsync}" />
<Slider Maximum="1.0"
Minimum="0.0"
Value="{Binding Volume}"
Rotation="270"
WidthRequest="100" />
</StackLayout>
この例では、データはそのSlider
プロパティを の MediaElement
プロパティにVolume
バインドしますValue
。 これは、 プロパティがバインディングを Volume
使用するためです TwoWay
。 したがって、 プロパティを Value
変更すると、プロパティが Volume
変更されます。
Note
Volume
プロパティには検証コールバックがあり、その値が 0.0 以上 1.0 以下であることを確認します。
の使用Slider
の詳細については、「Xamarin.Forms スライダー」を参照してください。