共用方式為


舊版背景媒體播放

本文介紹了用於向 UWP 應用程式新增背景音訊支援的舊版雙重程序模型。 從 Windows 10 版本 1607 開始,背景音訊的單一程序模型會比較容易實作。 有關前背景音訊建議的更多資訊,請參閱在背景播放媒體。 本文旨在針對已使用舊版雙重程序模型開發的應用程式提供支援。

注意

從 Windows 版本 1703 開始,BackgroundMediaPlayer 已被取代,並且可能在未來版本的 Windows 中無法使用。

背景音訊架構

執行背景播放的應用程式包含兩個程序。 第一個程序是主應用程式,其中包含應用程式 UI 和用戶端邏輯,在前景執行。 第二個程序是背景播放工作,它像所有 UWP 應用程式背景工作一樣實作 IBackgroundTask。 背景工作包含音訊播放邏輯和背景服務。 背景工作會透過系統媒體傳輸控制項與系統通訊。

下圖是系統設計方式的概觀。

Windows 10 背景音訊架構

MediaPlayer

Windows.Media.Playback 命名空間包含用於在背景播放音訊的 API。 每個應用程式都有一個 MediaPlayer 執行個體,透過它進行播放。 您的背景音訊應用程式會呼叫 MediaPlayer 類別上的方法並設定屬性,以設定目前曲目、開始播放、暫停、快轉、倒轉等。 媒體播放器物件執行個體一律透過 BackgroundMediaPlayer.Current 屬性存取。

MediaPlayer 代理程式和虛設常式

當從應用程式的背景程序存取 BackgroundMediaPlayer.Current 時,MediaPlayer 執行個體將在背景工作裝載中啟用,並且可以直接操作。

當從前景應用程式存取 BackgroundMediaPlayer.Current 時,傳回的 MediaPlayer 執行個體實際上是一個與背景程序中的虛設常式進行通訊的代理程式。 此虛設常式會與實際 MediaPlayer 執行個體通訊,此執行個體也會裝載於背景程序中。

前景和背景程序都可以存取 MediaPlayer 執行個體的大部分屬性,但 MediaPlayer.SourceMediaPlayer.SystemMediaTransportControls 除外,它們只能從背景程序存取。 前景應用程式和背景程序均可接收特定於媒體的事件 (例如 MediaOpenedMediaEndedMediaFailed) 的通知。

播放清單

背景音訊應用程式的常見案例是連續播放多個項目。 透過使用 MediaPlaybackList 物件,可以在背景程序中輕鬆完成此作業,可以透過將其指派給 MediaPlayer.Source 屬性來將其設定為 MediaPlayer 上的來源。

無法從在背景程序中設定的前景程序存取 MediaPlaybackList

系統媒體傳輸控制項

使用者可以透過藍牙裝置、SmartGlass 和系統媒體傳輸控制項等方式控制音訊播放,而無需直接使用應用程式的 UI。 您的背景工作使用 SystemMediaTransportControls 類別來訂閱這些使用者啟動的系統事件。

若要從背景程序中取得 SystemMediaTransportControls 執行個體,請使用 MediaPlayer.SystemMediaTransportControls 屬性。 前景應用程式透過呼叫 SystemMediaTransportControls.GetForCurrentView 取得該類別的執行個體,但傳回的執行個體是僅前景執行個體,與背景工作無關。

在工作之間傳送訊息

有時候您會想要在背景音訊應用程式的兩個程序之間進行通訊。 例如,您可能想要讓背景工作在新的曲目開始播放時通知前景工作,然後將新的歌曲標題傳送到前景工作以顯示在畫面上。

簡單的通訊機制會在前景和背景程序中引發事件。 SendMessageToForegroundSendMessageToBackground 方法各自叫用對應程序中的事件。 可以透過訂閱 MessageReceivedFromBackgroundMessageReceivedFromForeground 事件來接收訊息。

資料可以做為引數傳遞給傳送訊息方法,然後傳遞至訊息接收事件處理常式。 使用 ValueSet 類別傳遞資料。 此類是一個字典,其中包含字串做為索引鍵,其他值類型做為值。 您可以傳遞簡單的值類型,例如整數、字串和布林值。

背景工作生命週期

背景工作的生命週期與應用程式的目前播放狀態密切相關。 例如,當使用者暫停音訊播放時,系統可能會根據情況終止或取消您的應用程式。 一段時間沒有音訊播放後,系統可能會自動關閉背景工作。

當您的應用程式第一次從前景應用程式中執行的程式碼存取 BackgroundMediaPlayer.Current 時,或當您為 MessageReceivedFromBackground 事件註冊處理常式時 (以先發生者為準),將呼叫 IBackgroundTask.Run 方法。 建議您在第一次呼叫 BackgroundMediaPlayer.Current 之前註冊訊息接收處理常式,以便前景應用程式不會錯過任何從背景程序傳送的訊息。

為了讓背景工作保持使用中狀態,您的應用程式必須在 Run 方法中請求 BackgroundTaskDeferral,並在工作執行個體收到 CanceledCompleted 事件時呼叫 BackgroundTaskDeferral.Complete。 不要在 Run 方法中循環或等待,因為這會消耗資源,並可能導致應用程式的背景工作被系統終止。

Run 方法完成且不要求延遲時,您的背景工作將取得 Completed 事件。 在某些情況下,當您的應用程式收到 Canceled 事件時,後面也可能會收到 Completed 事件。 您的工作在執行 Run 時可能會收到 Canceled 事件,因此請務必管理這種潛在的同時發生情況。

可以取消背景工作的情況包括:

  • 具有音訊播放功能的新應用程式在強制執行排他性子原則的系統上啟動。 請參閱下面的背景音訊工作生命週期的系統原則部分。

  • 背景工作已啟動但音樂尚未播放,然後暫停前景應用程式。

  • 其他媒體中斷,例如來電或 VoIP 通話。

無需通知即可終止背景工作的情況包括:

  • VoIP 通話傳入,系統上沒有足夠的可用記憶體來保持背景工作處於運作狀態。

  • 違反資源原則。

  • 工作取消或完成不會正常結束。

背景音訊工作生命週期的系統原則

下列原則可協助判斷系統如何管理背景音訊工作的生命週期。

排他性

如果啟用,此子原則會限制在任何指定時間最多 1 的背景音訊工作數目。 它在行動裝置和其他非桌面 SKU 上啟用。

非使用狀態逾時

由於資源限制,系統可能會在一段閒置期間之後終止您的背景工作。

如果符合下列兩個條件,背景工作就會被視為「非使用中」:

  • 前景應用程式不可見 (已暫停或終止)。

  • 背景媒體播放器不是處於播放狀態。

如果符合這兩個條件,背景媒體系統原則將會啟動計時器。 如果計時器到期時兩個條件都沒有變更,背景媒體系統原則將會終止背景工作。

共用生命週期

如果啟用,此子原則會強制背景工作依賴於前景工作的生命週期。 如果使用者或系統關閉前景工作,背景工作也會關閉。

不過,請注意,這並不表示前景依賴於背景。 如果背景工作已關閉,這不會強制前景工作關閉。

下列資料表列出哪些原則會在哪些裝置類型上強制執行。

子原則 Desktop (電腦) 行動 其他
排他性 停用 啟用 啟用
非使用狀態逾時 停用 啟用 停用
共用生命週期 啟用 已停用 已停用