系統媒體傳輸控制項的手動控制項

從 Windows 10 版本 1607 開始,使用 MediaPlayer 類別播放媒體的 UWP 應用程式預設會自動與系統媒體傳輸控制項 (SMTC) 整合。 這是大部分案例中與 SMTC 互動的建議方式。 如需自訂 SMTC 與 MediaPlayer 的預設整合相關詳細資訊,請參閱與系統媒體傳輸控制項整合

在某些情況下,您可能需要實作 SMTC 的手動控制。 這些說明也包括使用 MediaTimelineController 來控制一個或多個媒體播放機的播放。 或者使用多個媒體播放機,而只想要為您的應用程式使用一個 SMTC 執行個體。 如果您使用 MediaElement 播放媒體,則必須手動控制 SMTC。

設定傳輸控制項

如果您使用 MediaPlayer 播放媒體,可以藉由存取 MediaPlayer.SystemMediaTransportControls 屬性來取得 SystemMediaTransportControls 類別的執行個體。 如果您要手動控制 SMTC,則應該將 CommandManager.IsEnabled 屬性設定為 false,以停用 MediaPlayer 所提供的自動整合。

注意

如果您藉由將 IsEnabled 設定為 false 來停用 MediaPlayerMediaPlaybackCommandManager ,它會中斷 MediaPlayer 以及 MediaPlayerElement 提供之 TransportControls 間的連結,因此內建的傳輸控制項將不再自動控制播放程式的播放。 因此,您必須實作自己的控制項來控制 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 事件。 傳遞至事件處理常式之 SystemMediaTransportControlsButtonPressedEventArgsButton 屬性,是 SystemMediaTransportControlsButton 列舉的成員,可指出已按下哪些已啟用按鈕。

若要從 ButtonPressed 事件處理常式更新 UI 執行緒上的物件,例如 MediaElement 物件,您必須透過 CoreDispatcher 封送呼叫。 這是因為系統不會從 UI 執行緒呼叫 ButtonPressed 事件處理常式,因此如果您嘗試直接修改 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 類別所公開的 MusicPropertiesImagePropertiesVideoProperties 物件的值,藉此手動更新系統媒體傳輸控制項所顯示的中繼資料。


// 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);
  • 您必須提供 StartTimeEndTimePosition 的值,系統控制項才能顯示播放項目的時間軸。

  • MinSeekTimeMaxSeekTime 可讓您指定使用者能夠在時間軸內搜尋的範圍。 這個的典型案例,是允許內容提供者在其媒體中包含廣告時間。

    您必須設定 MinSeekTimeMaxSeekTime,才能引發 PositionChangeRequest

  • 建議您讓系統控制項與媒體播放保持同步,方法是在播放期間大約每 5 秒更新一次這些屬性,每當播放狀態變更時 (例如暫停或搜尋到新位置) 再更新一次屬性。

回應播放器屬性變更

有一組系統傳輸控制項屬性與媒體播放程式本身的目前狀態相關,而不是正在播放之媒體項目的狀態。 這些屬性每一個都會對應到使用者調整相關聯控制項時所引發的事件。 這些屬性與事件包括:

屬性 Event
AutoRepeatMode AutoRepeatModeChangeRequested
PlaybackRate PlaybackRateChangeRequested
ShuffleEnabled ShuffleEnabledChangeRequested

  若要處理使用者與其中一個控制項的互動,請先註冊相關聯事件的處理常式。

_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;
    }
}
  • 為了順利引發這些播放器屬性事件,您必須設定屬性的初始值。 例如,在至少設定 PlaybackRate 屬性的值一次之後,才會引發 PlaybackRateChangeRequested

使用系統媒體傳輸控制項處理背景音訊

如果您未使用 MediaPlayer 提供的自動 SMTC 整合,則必須手動與 SMTC 整合,才能啟用背景音訊。 您的應用程式至少必須啟用播放和暫停按鈕,方法是將 IsPlayEnabledIsPauseEnabled 設定為 true。 您的應用程式也必須處理 ButtonPressed 事件。 如果您的應用程式不符合這些需求,當您的應用程式移至背景時,音訊播放將會停止。

針對背景音訊使用新單一程序模型的應用程式,應該藉由呼叫 GetForCurrentView 來取得 SystemMediaTransportControls 的執行個體。 使用舊版雙重程序模型處理背景音訊的應用程式,必須使用 BackgroundMediaPlayer.Current.SystemMediaTransportControls 從其背景程序存取 SMTC。

如需在背景播放音訊的詳細資訊,請參閱在背景播放媒體