システム メディア トランスポート コントロールとの統合

この記事では、システム メディア トランスポート コントロール (SMTC) を操作する方法について説明します。 SMTC は、すべての Windows 10 デバイスに共通する一連のコントロールで、再生に MediaPlayer を使うすべての実行中のアプリのメディア再生をユーザーが制御するための一貫した方法を提供します。

システム メディア トランスポート コントロールを使用すると、メディア アプリケーション開発者は、組み込みのシステム UI と統合して、アーティスト、アルバム タイトル、チャプター タイトルなどのメディア メタデータを表示できます。 また、システム トランスポート コントロールを使用すると、ユーザーは、再生を一時停止したり、再生リストで前後にスキップしたりするなど、組み込みのシステム UI を使用してメディア アプリの再生を制御できます。

System Media Transtport コントロール

SMTC との統合を示す完全なサンプルについては、github のシステム メディア トランスポート コントロールのサンプルをご覧ください。

SMTC との自動統合

Windows 10 バージョン 1607 以降、メディアの再生に MediaPlayer クラスを使う UWP アプリは、既定で SMTC と自動的に統合されます。 MediaPlayer の新しいインスタンスをインスタンス化し、MediaSourceMediaPlaybackItem、または MediaPlaybackList をプレーヤーの Source プロパティに割り当てるだけで、SMTC にアプリ名が表示され、SMTC コントロールを使って再生リストから再生、一時停止、再生リスト内の移動を行うことができます。

アプリは一度に複数の MediaPlayer オブジェクトを作成し、使うことができます。 アプリ内のアクティブな MediaPlayer インスタンスごとに、SMTC に個別のタブが作成されるため、ユーザーはアクティブなメディア プレーヤーとその他の実行中のアプリのメディア プレーヤーを切り替えることができます。 SMTC で現在選択されているメディア プレーヤーが、コントロールが影響を与えるメディア プレーヤーとなります。

アプリで MediaPlayer を使う方法 (XAML ページで MediaPlayerElement にバインドするなど) について詳しくは、「MediaPlayer を使ったオーディオとビデオの再生」をご覧ください。

MediaSourceMediaPlaybackItemMediaPlaybackList の操作について詳しくは、「メディア項目、プレイリスト、トラック」をご覧ください。

SMTC で表示するメタデータを追加する

ビデオや曲のタイトルなど、SMTC でメディア項目に表示するメタデータを追加または変更する場合、メディア項目を表す MediaPlaybackItem の表示プロパティを更新する必要があります。 まず、GetDisplayProperties を呼び出して、MediaItemDisplayProperties オブジェクトへの参照を取得します。 次に、Type プロパティを持つ項目に、メディアの種類 (音楽またはビデオ) を設定します。 その後、指定したメディアの種類によって、MusicProperties または VideoProperties のフィールドを設定できます。 最後に、ApplyDisplayProperties を呼び出して、メディア項目のメタデータを更新します。

MediaItemDisplayProperties props = mediaPlaybackItem.GetDisplayProperties();
props.Type = Windows.Media.MediaPlaybackType.Video;
props.VideoProperties.Title = "Video title";
props.VideoProperties.Subtitle = "Video subtitle";
props.VideoProperties.Genres.Add("Documentary");
mediaPlaybackItem.ApplyDisplayProperties(props);
props = mediaPlaybackItem.GetDisplayProperties();
props.Type = Windows.Media.MediaPlaybackType.Music;
props.MusicProperties.Title = "Song title";
props.MusicProperties.Artist = "Song artist";
props.MusicProperties.Genres.Add("Polka");
mediaPlaybackItem.ApplyDisplayProperties(props);

注意

システム メディア トランスポート コントロールによって表示される他のメディア メタデータがアプリによって提供されない場合も、アプリには Type プロパティの値を設定する必要があります。 この値は、再生中にスクリーン セーバーがアクティブ化されないようにするなど、システムでメディア コンテンツを正しく処理するのに役立ちます。

CommandManager を使って既定の SMTC コマンドを変更またはオーバーライドする

アプリでは、MediaPlaybackCommandManager クラスを使って SMTC コントロールの動作を変更または完全にオーバーライドできます。 CommandManager プロパティにアクセスすると、MediaPlayer クラスのインスタンスごとにコマンド マネージャー インスタンスを取得できます。

既定では MediaPlaybackList の次の項目にスキップする Next コマンドなどのすべてのコマンドに、コマンド マネージャーは NextReceived のような受信イベントと、NextBehavior のようにコマンドの動作を管理するオブジェクトを公開します。

次の例では、NextReceived イベントのハンドラーと、NextBehaviorIsEnabledChanged イベントのハンドラーを登録します。

_mediaPlayer.CommandManager.NextReceived += CommandManager_NextReceived;
_mediaPlayer.CommandManager.NextBehavior.IsEnabledChanged += NextBehavior_IsEnabledChanged;

次の例は、ユーザーが再生リスト内の 5 個の項目をクリックスルーした後、アプリが Next コマンドを無効にするシナリオを示しています。おそらくは、コンテンツを引き続き再生する前に、何らかのユーザー操作が必要になります。 NextReceived イベントが発生するたびに、カウンターがインクリメントされます。 カウンターが目標の数値に達すると、Next コマンドの EnablingRuleNever に設定され、コマンドが無効になります。

int _nextPressCount = 0;
private void CommandManager_NextReceived(MediaPlaybackCommandManager sender, MediaPlaybackCommandManagerNextReceivedEventArgs args)
{
    _nextPressCount++;
    if (_nextPressCount > 5)
    {
        sender.NextBehavior.EnablingRule = MediaCommandEnablingRule.Never;
        // Perform app tasks while the Next button is disabled
    }
}

コマンドを Always に設定することもできます。これは、Next コマンドの例では、再生リスト内にこれ以上項目がない場合でも、コマンドが常に有効になっていることを示します。 または、コマンドを Auto に設定することもできます。この設定では、現在再生中のコンテンツに基づいてコマンドを有効にする必要があるかどうかがシステムによって判断されます。

上記のシナリオでは、ある時点でアプリが Next コマンドを再度有効にする必要があるため、EnablingRuleAuto に設定することでそれを行います。

_mediaPlayer.CommandManager.NextBehavior.EnablingRule = MediaCommandEnablingRule.Auto;
_nextPressCount = 0;

アプリには、アプリがフォアグラウンドで動作しているときに再生を制御するための独自の UI が備わっている可能性があるため、IsEnabledChanged イベントを使って独自の UI を SMTC と一致するように更新し、ハンドラーに渡された MediaPlaybackCommandManagerCommandBehaviorIsEnabled にアクセスすることによってコマンドを有効または無効にすることができます。

private void NextBehavior_IsEnabledChanged(MediaPlaybackCommandManagerCommandBehavior sender, object args)
{
    MyNextButton.IsEnabled = sender.IsEnabled;
}

場合によっては、SMTC コマンドの動作を完全にオーバーライドすることもできます。 次の例は、アプリが Next コマンドと Previous コマンドを使って、現在の再生リスト内のトラック間をスキップするのではなく、インターネット ラジオ局どうしを切り替えるシナリオを示しています。 前の例と同様に、ハンドラーはコマンドの受信時に登録されます。ここでは、PreviousReceived イベントの受信時となります。

_mediaPlayer.CommandManager.PreviousReceived += CommandManager_PreviousReceived;

PreviousReceived ハンドラーでは、そのハンドラーに渡された MediaPlaybackCommandManagerPreviousReceivedEventArgsGetDeferral を呼び出すことにより、まず Deferral が取得されます。 これにより、システムは Deferral が完了するのを待機してからコマンドを実行するよう通知されます。 これは、ハンドラーで非同期呼び出しを行う場合に非常に重要です。 この時点で、この例では前のラジオ局を表す MediaPlaybackItem を返すカスタム メソッドを呼び出します。

次に、Handled プロパティで、イベントが別のハンドラーによってまだ処理されていないかどうかが確認されます。 処理済みの場合、Handled プロパティが true に設定されます。 これにより、SMTC と、その他の受信登録されたハンドラーは、イベントが既に処理済みなのでこのコマンドを実行する必要がないことを把握できます。 その後、コードはメディア プレーヤーの新しいソースを設定し、プレーヤーを開始します。

最後に、保留オブジェクトで Complete が呼び出されて、システムはコマンドの処理が完了したことを把握できます。

private async void CommandManager_PreviousReceived(MediaPlaybackCommandManager sender, MediaPlaybackCommandManagerPreviousReceivedEventArgs args)
{
    var deferral = args.GetDeferral();
    MediaPlaybackItem mediaPlaybackItem = await GetPreviousStation();

    if(args.Handled != true)
    {
        args.Handled = true;
        sender.MediaPlayer.Source = mediaPlaybackItem;
        sender.MediaPlayer.Play();
    }
    deferral.Complete();
}

SMTC の手動制御

この記事で既に説明したように、SMTC はアプリによって作成される MediaPlayer のすべてのインスタンスに関する情報を自動的に検出して表示します。 MediaPlayer のインスタンスを複数使うが、SMTC ではアプリのエントリを 1 つだけ提供する場合、自動統合を使うのではなく、SMTC を手動で制御する必要があります。 また、MediaTimelineController を使って 1 つ以上のメディア プレーヤーを制御する場合、手動 SMTC 統合を使う必要があります。 アプリが MediaPlayer 以外の API (AudioGraph クラスなど) を使ってメディアを再生する場合も、ユーザーが SMTC を使ってアプリを制御できるように、手動 SMTC 統合を実装する必要があります。 SMTC を手動で制御する方法について詳しくは、「システム メディア トランスポート コントロールの手動制御」をご覧ください。