Xamarin Community Toolkit MediaElement

サンプルをダウンロードします。 サンプルをダウンロードする

MediaElement は、ビデオとオーディオを再生するためのビューです。 基になるプラットフォームでサポートされているメディアは、次のソースから再生できます。

  • URI (HTTP または HTTPS) を使用する Web。
  • URI スキームを使用して、プラットフォーム アプリケーションに ms-appx:/// 埋め込まれたリソース。
  • URI スキームを使用して、アプリのローカルおよび一時データ フォルダーから取得された ms-appdata:/// ファイル。
  • デバイスのライブラリ。

MediaElement は、トランスポート コントロールと呼ばれるプラットフォーム再生コントロールを使用できます。 ただし、既定では無効になっており、独自のトランスポート コントロールに置き換えることができます。 次のスクリーンショットは、プラットフォーム トランスポート コントロールを使用したビデオの再生を示 MediaElement しています。

iOS と Android でビデオを再生している MediaElement のスクリーンショット。

Note

MediaElementは、iOS、Android、ユニバーサル Windows プラットフォーム (UWP)、macOS、Windows Presentation Foundation、Tizen で使用できます。

MediaElement は次の特性を定義します。

  • AspectAspectの は、メディアを表示領域に合わせてスケーリングする方法を決定します。 このプロパティの既定値は AspectFit です。
  • AutoPlayboolの は、 プロパティが設定されたときにメディアの再生を Source 自動的に開始するかどうかを示します。 このプロパティの既定値は true です。
  • BufferingProgressdoubleの 。 は、現在のバッファリングの進行状況を示します。 このプロパティの既定値は 0.0 です。
  • CanSeekboolの は、 プロパティの値を設定することでメディアの Position 位置を変更できるかどうかを示します。 これは、読み取り専用プロパティです。
  • CurrentStateMediaElementStateの は、コントロールの現在の状態を示します。 これは読み取り専用プロパティで、既定値は です MediaElementState.Closed
  • DurationTimeSpan?の 。 は、現在開いているメディアの期間を示します。 これは、既定値が である読み取り専用プロパティです null
  • IsLoopingboolの は、現在読み込まれているメディア ソースが、最後に到達した後に最初から再生を再開する必要があるかどうかを示します。 このプロパティの既定値は false です。
  • KeepScreenOnboolの 。 は、メディアの再生中にデバイス画面をオンにするかどうかを決定します。 このプロパティの既定値は false です。
  • PositionTimeSpanの は、メディアの再生時間の現在の進行状況を表します。 このプロパティはバインディングを TwoWay 使用し、既定値は です TimeSpan.Zero
  • ShowsPlaybackControlsの型 boolは、プラットフォームの再生コントロールを表示するかどうかを決定します。 このプロパティの既定値は false です。 iOS では、コントロールは画面を操作した後に短時間だけ表示されることに注意してください。 コントロールを常に表示する方法はありません。 WPF では、システム コントロールはサポートされていないため、このプロパティは無効です。
  • Speedの種類 doubleは、メディアの再生速度を決定します。 このプロパティの既定値は 1 です。
  • SourceMediaSourceの は、コントロールに読み込まれたメディアのソースを示します。
  • VideoHeightintの は、コントロールの高さを示します。 これは、読み取り専用プロパティです。
  • VideoWidthintの は、コントロールの幅を示します。 これは、読み取り専用プロパティです。
  • Volumedoubleの は、メディアのボリュームを決定します。メディアのボリュームは、0 から 1 の間の線形スケールで表されます。 このプロパティはバインディングを TwoWay 使用し、既定値は 1 です。

プロパティを除 CanSeek くこれらのプロパティは、オブジェクトによって BindableProperty サポートされます。つまり、データ バインディングのターゲットにすることができ、スタイルを設定できます。

クラスでは、次 MediaElement の 4 つのイベントも定義されます。

  • MediaOpened は、メディア ストリームが検証されて開かれたときに発生します。
  • MediaEnded は、メディアの MediaElement 再生が完了したときに発生します。
  • MediaFailed は、メディア ソースに関連するエラーが発生したときに発生します。
  • SeekCompleted は、要求されたシーク操作のシーク ポイントが再生の準備ができたときに発生します。

さらに、 には、MediaElementPauseStop メソッドが含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 開いた直後に再生されます。 メディアの自動再生を抑制するには、 プロパティを AutoPlayfalse設定します。

メディア再生コントロールは既定で無効になっており、 プロパティを ShowsPlaybackControlstrue設定することで有効になります。 MediaElement では、プラットフォーム再生コントロールが使用可能な場合に使用されます。

ローカル メディアを再生する

ローカル メディアは、次のソースから再生できます。

  • URI スキームを使用して、プラットフォーム アプリケーションに ms-appx:/// 埋め込まれたリソース。
  • URI スキームを使用して、アプリのローカルおよび一時データ フォルダーから取得された ms-appdata:/// ファイル。
  • デバイスのライブラリ。

これらの URI スキームの詳細については、「 URI スキーム」を参照してください。

アプリ パッケージに埋め込まれたメディアを再生する

MediaElement 、URI スキームを使用して、アプリ パッケージに埋め込まれているメディア ファイルを ms-appx:/// 再生できます。 メディア ファイルは、プラットフォーム プロジェクトに配置することで、アプリ パッケージに埋め込まれます。

プラットフォーム プロジェクトにメディア ファイルを格納する方法は、プラットフォームごとに異なります。

  • iOS では、メディア ファイルは Resources フォルダーまたは Resources フォルダーのサブフォルダーに格納する必要があります。 メディア ファイルには、 の BundleResourceBuild Action必要です。
  • Android では、メディア ファイルは raw という名前の Resources のサブフォルダーに格納する必要があります。 raw フォルダーにサブフォルダーを含めることはできません。 メディア ファイルには、 の AndroidResourceBuild Action必要です。
  • UWP では、メディア ファイルはプロジェクト内の任意のフォルダーに格納できます。 メディア ファイルには、 の ContentBuildAction必要です。

これらの条件を満たすメディア ファイルは、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>

この例では、 MaximumSlider プロパティは の プロパティMediaElementDurationデータバインドされValue、 の Slider プロパティは の プロパティMediaElementPositionデータバインドされています。 したがって、ドラッグすると Slider 、メディア再生位置が変化します。

iOS と Android の位置バーを含む MediaElement のスクリーンショット。

さらに、 オブジェクトは DataTrigger 、メディアのバッファリング時に を Slider 無効にするために使用されます。 データ トリガーの詳細については、「 Xamarin.Forms トリガー」を参照してください。

Note

Android では、 と の設定にSlider関係なく、1000 個の個別のMaximumMinimumステップしかありません。 メディアの長さが 1000 秒を超える場合、2 つの異なる Position 値が の同じ ValueSliderに対応します。 このため、上記のコードでは、新しい位置と既存の位置が全体の期間の 100 分の 1 を超えています。

MediaSource の種類について

MediaElement 、そのプロパティを Source リモートメディアファイルまたはローカルメディアファイルに設定することでメディアを再生できます。 プロパティは SourceMediaSourceであり、このクラスは 2 つの静的メソッドを定義します。

  • FromFileは、引数からインスタンスをstringMediaSourceします。
  • FromUriは、引数からインスタンスをUriMediaSourceします。

さらに、 MediaSource クラスには、 および Uri 引数からstringインスタンスを返すMediaSource暗黙的な演算子もあります。

Note

XAML で プロパティをSource設定すると、 または Uriからインスタンスを返MediaSourceす型コンバーターがstring呼び出されます。

MediaSourceクラスには、次の 2 つの派生クラスもあります。

  • UriMediaSourceURI からリモート メディア ファイルを指定するために使用されます。 このクラスには、 に Uri 設定できるプロパティがあります Uri
  • FileMediaSourceからローカル メディア ファイル stringを指定するために使用されます。 このクラスには、 に File 設定できるプロパティがあります string。 さらに、このクラスには、 を オブジェクトに変換する暗黙的な演算子と、 オブジェクトを に変換stringFileMediaSourceする暗黙的なFileMediaSource演算子がありますstring

Note

XAML でオブジェクトをFileMediaSource作成すると、 からstringインスタンスを返FileMediaSourceす型コンバーターが呼び出されます。

MediaElement の状態を確認する

クラスは MediaElement 、 型の という名前 CurrentStateの読み取り専用バインド可能なプロパティを定義します MediaElementState。 このプロパティは、メディアの再生中か一時停止中か、メディアを再生する準備がまだできていないかどうかなど、コントロールの現在の状態を示します。

MediaElementState 列挙体を使って、次のメンバーを定義できます。

  • Closed は、 に MediaElement メディアが含まれないことを示します。
  • Opening は、 が指定したソースを検証し、読み込もうとしていることを MediaElement 示します。
  • Buffering は、 が再生のためにメディアを読み込むことを MediaElement 示します。 この状態では、その Position プロパティは進行しません。 がビデオを MediaElement 再生していた場合、最後に表示されたフレームが引き続き表示されます。
  • Playing は、 がメディア ソースを再生していることを MediaElement 示します。
  • Paused は、 がそのプロパティを MediaElementPosition めないことを示します。 がビデオを MediaElement 再生していた場合は、現在のフレームが引き続き表示されます。
  • Stopped は、 に MediaElement メディアが含まれているが、再生または一時停止されていないことを示します。 プロパティ Position は 0 で、進むことはありません。 読み込まれたメディアがビデオの場合は MediaElement 、最初のフレームが表示されます。

一般に、トランスポート コントロールを使用するときに プロパティをCurrentStateMediaElement調べる必要はありません。 ただし、このプロパティは、独自のトランスポート コントロールを実装するときに重要になります。

カスタム トランスポート コントロールを実装する

メディア プレーヤーのトランスポート コントロールには、[ 再生]、[ 一時停止]、[ 停止] の各機能を実行するボタンが含まれます。 これらのボタンは一般的に、テキストではなく使い慣れたアイコンで識別されます。また、再生一時停止機能は一般的に、1 つのボタンに結合されています。

既定では、 MediaElement 再生コントロールは無効になっています。 これにより、 をプログラムで制御 MediaElement したり、独自のトランスポート コントロールを指定したりすることができます。 これをサポートするには、MediaElementおよび メソッドが含まれますPlayPauseStop

次の 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="&#x25B6;&#xFE0F; Play"
                    HorizontalOptions="CenterAndExpand"
                    Clicked="OnPlayPauseButtonClicked">
                <Button.Triggers>
                    <DataTrigger TargetType="Button"
                                 Binding="{Binding CurrentState}"
                                 Value="{x:Static MediaElementState.Playing}">
                        <Setter Property="Text"
                                Value="&#x23F8; Pause" />
                    </DataTrigger>
                    <DataTrigger TargetType="Button"
                                 Binding="{Binding CurrentState}"
                                 Value="{x:Static MediaElementState.Buffering}">
                        <Setter Property="IsEnabled"
                                Value="False" />
                    </DataTrigger>
                </Button.Triggers>
            </Button>
            <Button Text="&#x23F9; 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 つ目が PlayPause を表し、2 つ目ButtonStop を表すオブジェクトは 2 ButtonButton つだけです。 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();
}

[再生] ボタンを押すと、有効になったら再生を開始できます。

iOS と Android のカスタム トランスポート コントロールを含む MediaElement のスクリーンショット。

[一時停止] ボタンを押すと、再生が一時停止します。

iOS と Android で再生が一時停止されている MediaElement のスクリーンショット。

[停止] ボタンを押すと再生が停止し、メディア ファイルの位置が先頭に戻ります。

カスタム ボリューム コントロールを実装する

各プラットフォームによって実装されるメディア再生コントロールには、ボリューム バーが含まれます。 このバーはスライダーに似ていて、メディアの音量を示しています。 さらに、ボリューム バーを操作してボリュームを増減することもできます。

次の例に示すように、 を使用して 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 スライダー」を参照してください。