システム メディア トランスポート コントロールの手動制御

Windows 10 バージョン 1607 以降、MediaPlayer クラスを使ってメディアを再生する UWP アプリは、既定でシステム メディア トランスポート コントロール (SMTC) と自動的に統合されます。 これは、ほとんどのシナリオの SMTC と対話するための推奨される方法です。 SMTC の MediaPlayer との既定の統合のカスタマイズについて詳しくは、「システム メディア トランスポート コントロールとの統合」をご覧ください。

SMTC の手動コントロールの実装が必要になるシナリオがいくつかあります。 たとえば、MediaTimelineController を使って 1 つ以上のメディア プレーヤーの再生を制御する場合です。 複数のメディア プレーヤーを使用していて、アプリ用に SMTC の 1 つのインスタンスだけが必要な場合もそうです。 MediaElement を使ってメディアを再生する場合は、SMTC を手動で制御する必要があります。

トランスポート コントロールをセットアップする

MediaPlayer 使ってメディアを再生している場合は、MediaPlayer.SystemMediaTransportControls プロパティにアクセスして SystemMediaTransportControls のインスタンスを取得できます。 SMTC を手動で制御する場合は、CommandManager.IsEnabled プロパティを false に設定して、MediaPlayer によって提供される自動統合を無効にする必要があります。

注意

IsEnabled を false に設定して、MediaPlayerMediaPlaybackCommandManager を無効にすると、MediaPlayerElement で提供される MediaPlayerTransportControls の間のリンクが解除されます。このため組み込みトランスポート コントロールはプレーヤーの再生を自動的に制御しなくなります。 代わりに、独自のコントロールを実装して、MediaPlayer を制御する必要があります。

_mediaPlayer = new MediaPlayer();
_systemMediaTransportControls = _mediaPlayer.SystemMediaTransportControls;
_mediaPlayer.CommandManager.IsEnabled = false;

GetForCurrentView を呼び出して、SystemMediaTransportControls のインスタンスを取得することもできます。 MediaElement を使ってメディアを再生している場合は、この方法でオブジェクトを取得する必要があります。

_systemMediaTransportControls = SystemMediaTransportControls.GetForCurrentView();

SystemMediaTransportControls オブジェクトの対応する "is enabled" プロパティ (IsPlayEnabledIsPauseEnabledIsNextEnabledIsPreviousEnabled など) を設定することで、アプリで使うボタンを有効にします。 利用可能なすべてのコントロールの一覧については、SystemMediaTransportControls のリファレンス ドキュメントをご覧ください。

_systemMediaTransportControls.IsPlayEnabled = true;
_systemMediaTransportControls.IsPauseEnabled = true;

ユーザーがボタンを押したときに通知を受信するために、ButtonPressed イベントのハンドラーを登録します。

_systemMediaTransportControls.ButtonPressed += SystemControls_ButtonPressed;

システム メディア トランスポート コントロールの押されたボタンを処理する

ButtonPressed イベントは、有効なボタンの 1 つが押されたときにシステム トランスポート コントロールで発生します。 イベント ハンドラーに渡される SystemMediaTransportControlsButtonPressedEventArgsButton プロパティは、有効なボタンのうちどれが押されたかを示す SystemMediaTransportControlsButton 列挙体のメンバーです。

ButtonPressed イベント ハンドラーから UI スレッド上のオブジェクト (MediaElement オブジェクトなど) を更新するには、CoreDispatcher を介して呼び出しをマーシャリングする必要があります。 これは、ButtonPressed イベント ハンドラーが UI スレッドから呼び出されず、UI を直接変更しようとすると例外が発生するためです。

async void SystemControls_ButtonPressed(SystemMediaTransportControls sender,
    SystemMediaTransportControlsButtonPressedEventArgs args)
{
    switch (args.Button)
    {
        case SystemMediaTransportControlsButton.Play:
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                mediaElement.Play();
            });
            break;
        case SystemMediaTransportControlsButton.Pause:
            await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
            {
                mediaElement.Pause();
            });
            break;
        default:
            break;
    }
}

現在のメディアの状態でシステム メディア トランスポート コントロールを更新する

システムで現在の状態を反映してコントロールを更新できるように、メディアの状態が変更されたときには、それを SystemMediaTransportControls に通知する必要があります。 そのためには、メディアの状態が変更されたときに発生する MediaElementCurrentStateChanged イベント内から、PlaybackStatus プロパティを適切な MediaPlaybackStatus 値に設定します。

void MediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
{
    switch (mediaElement.CurrentState)
    {
        case MediaElementState.Playing:
            _systemMediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Playing;
            break;
        case MediaElementState.Paused:
            _systemMediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Paused;
            break;
        case MediaElementState.Stopped:
            _systemMediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Stopped;
            break;
        case MediaElementState.Closed:
            _systemMediaTransportControls.PlaybackStatus = MediaPlaybackStatus.Closed;
            break;
        default:
            break;
    }
}

メディアの情報と縮小表示でシステム メディア トランスポート コントロールを更新する

SystemMediaTransportControlsDisplayUpdater クラスを使って、現在再生されているメディア項目の曲のタイトルやアルバム アートなど、トランスポート コントロールに表示されるメディア情報を更新します。 SystemMediaTransportControls.DisplayUpdater プロパティを使って、このクラスのインスタンスを取得します。 一般的なシナリオの場合、メタデータを渡すための推奨される方法は、現在再生中のメディア ファイルを渡して CopyFromFileAsync を呼び出すことです。 表示アップデーターによって、ファイルからメタデータと縮小表示画像が自動的に抽出されます。

Update を呼び出すことで、システム メディア トランスポート コントロールの UI が新しいメタデータと縮小表示によって更新されます。

async void MediaElement_MediaOpened(object sender, RoutedEventArgs e)
{
    // Get the updater.
    SystemMediaTransportControlsDisplayUpdater updater = _systemMediaTransportControls.DisplayUpdater;

    await updater.CopyFromFileAsync(MediaPlaybackType.Music, currentMediaFile);

    // Update the system media transport controls
    updater.Update();
}

必要に応じて、DisplayUpdater クラスによって公開される MusicPropertiesImageProperties、または VideoProperties オブジェクトの値を設定することにより、システム メディア トランスポート コントロールに表示されるメタデータを手動で更新できます。


// Get the updater.
SystemMediaTransportControlsDisplayUpdater updater = _systemMediaTransportControls.DisplayUpdater;

// Music metadata.
updater.Type = MediaPlaybackType.Music;
updater.MusicProperties.Artist = "artist";
updater.MusicProperties.AlbumArtist = "album artist";
updater.MusicProperties.Title = "song title";

// Set the album art thumbnail.
// RandomAccessStreamReference is defined in Windows.Storage.Streams
updater.Thumbnail =
   RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Music/music1_AlbumArt.jpg"));

// Update the system media transport controls.
updater.Update();

注意

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

システム メディア トランスポート コントロールのタイムライン プロパティを更新する

システム トランスポート コントロールには、メディア項目の現在の再生位置、開始時刻、終了時刻など、現在再生中のメディア項目のタイムラインに関する情報が表示されます。 システム メディア トランスポート コントロールのタイムライン プロパティを更新するには、新しい SystemMediaTransportControlsTimelineProperties オブジェクトを作成します。 再生中のメディア項目の現在の状態を反映するように、オブジェクトのプロパティを設定します。 SystemMediaTransportControls.UpdateTimelineProperties を呼び出して、コントロールのタイムラインを更新します。

// Create our timeline properties object 
var timelineProperties = new SystemMediaTransportControlsTimelineProperties();

// Fill in the data, using the media elements properties 
timelineProperties.StartTime = TimeSpan.FromSeconds(0);
timelineProperties.MinSeekTime = TimeSpan.FromSeconds(0);
timelineProperties.Position = mediaElement.Position;
timelineProperties.MaxSeekTime = mediaElement.NaturalDuration.TimeSpan;
timelineProperties.EndTime = mediaElement.NaturalDuration.TimeSpan;

// Update the System Media transport Controls 
_systemMediaTransportControls.UpdateTimelineProperties(timelineProperties);
  • 再生中の項目のタイムラインをシステム コントロールに表示するには、StartTimeEndTime、および Position の値を指定する必要があります。

  • MinSeekTimeMaxSeekTime を使うと、ユーザーがシークできるタイムライン内の範囲を指定できます。 一般的なシナリオとしては、コンテンツ プロバイダーがメディアに広告を含める場合などがあります。

    PositionChangeRequest を発生させるには、MinSeekTimeMaxSeekTime を設定する必要があります。

  • システム コントロールは、メディアの再生と同期させておくことをお勧めします。そのためには、再生中にこれらのプロパティを約 5 秒ごとに更新し、一時停止や新しい位置へのシークなど、再生に変更が加えられたときには、再度更新します。

プレーヤーのプロパティの変更に応答する

再生中のメディア項目の状態ではなく、メディア プレーヤー自体の現在の状態に関連した、一連のシステム トランスポート コントロール プロパティがあります。 これらの各プロパティは、ユーザーが関連するコントロールを調整したときに発生するイベントと対応しています。 これらのプロパティとイベントを次に示します。

プロパティ イベント
AutoRepeatMode AutoRepeatModeChangeRequested
PlaybackRate PlaybackRateChangeRequested
ShuffleEnabled ShuffleEnabledChangeRequested

  これらのコントロールの 1 つに対するユーザーの操作を処理するには、最初に、関連付けられているイベントのハンドラーを登録します。

_systemMediaTransportControls.PlaybackRateChangeRequested += SystemControls_PlaybackRateChangeRequested;

まず、イベントのハンドラーで、要求された値が有効な予想される範囲内にあることを確認します。 範囲内の場合は、MediaElement の対応するプロパティを設定してから、SystemMediaTransportControls オブジェクトの対応するプロパティを設定します。

void SystemControls_PlaybackRateChangeRequested(SystemMediaTransportControls sender, PlaybackRateChangeRequestedEventArgs args)
{
    // Check the requested value to make sure it is within a valid and expected range
    if (args.RequestedPlaybackRate >= 0 && args.RequestedPlaybackRate <= 2)
    {
        // Set the requested value on the MediaElement
        mediaElement.PlaybackRate = args.RequestedPlaybackRate;

        // Update the system media controls to reflect the new value
        _systemMediaTransportControls.PlaybackRate = mediaElement.PlaybackRate;
    }
}
  • これらのプレーヤー プロパティ イベントの 1 つが発生するためには、プロパティの初期値を設定する必要があります。 たとえば、PlaybackRateChangeRequested は、PlaybackRate プロパティの値を少なくとも 1 回設定するまでは発生しません。

バックグラウンド オーディオに対してシステム メディア トランスポート コントロールを使う

MediaPlayer によって提供される自動 SMTC 統合を使用していない場合は、SMTC と手動で統合してバック グラウンド オーディオを有効にする必要があります。 少なくとも、アプリで IsPlayEnabledIsPauseEnabled を true に設定して、再生ボタンと一時停止ボタンを有効にする必要があります。 アプリは、ButtonPressed イベントも処理する必要があります。 アプリがこれらの要件を満たしていない場合、アプリがバックグラウンドに移動したときにオーディオ再生は停止します。

バックグラウンド オーディオ用に新しい 1 プロセスのモデルを使うアプリは、GetForCurrentView を呼び出して SystemMediaTransportControls のインスタンスを取得する必要があります。 バックグラウンド オーディオ用に従来の 2 プロセスのモデルを使うアプリは、BackgroundMediaPlayer.Current.SystemMediaTransportControls を使ってバックグラウンド プロセスから SMTC にアクセスする必要があります

バックグラウンドでのオーディオ再生について詳しくは、「バックグラウンドでのメディアの再生」をご覧ください。