在背景播放媒體

本文說明如何設定應用程式,讓媒體在應用程式從前景移至背景時繼續播放。 這表示即使使用者已將應用程式最小化、返回主畫面,或以其他方式瀏覽離開您的應用程式,您的應用程式仍可繼續播放音訊。

背景音訊播放的案例包括:

  • 長時間執行的播放清單:使用者短暫地調出一個前景應用程式來選取並啟動播放清單,之後使用者希望播放清單繼續在背景播放。

  • 使用工作切換器:使用者短暫啟動前景應用程式以開始播放音訊,然後使用工作切換器切換到另一個開啟的應用程式。 使用者預期音訊會繼續在背景播放。

本文中所述的背景音訊實作可讓您的應用程式在所有 Windows 裝置上普遍執行,包括行動裝置、桌面和 Xbox。

注意

本文中的程式碼是從 UWP 背景音訊範例改編的。

單一程序模型的說明

Windows 10 版本 1607 引進了新的單一程序模型,可大幅簡化啟用背景音訊的程序。 先前,除了前景應用程式之外,您的應用程式還需要管理背景程序,然後手動傳達兩個程序之間的狀態變更。 在新的模型中,您只要將背景音訊功能新增至應用程式資訊清單,您的應用程式就會在移至背景時自動繼續播放音訊。 兩個新的應用程式生命週期事件 EnteredBackgroundLeavingBackground,讓您的應用程式知道它何時進入和離開背景。 當您的應用程式進入背景或從背景轉換時,系統強制執行的記憶體限制可能會變更,因此您可以使用這些事件來檢查目前的記憶體使用量並釋放資源以保持在限制以下。

透過消除複雜的跨程序通訊和狀態管理,新模型可讓您更快地實作背景音訊,同時顯著減少程式碼。 不過,目前版本中仍支援雙重程序模型,以提供回溯相容性。 如需詳細資訊,請參閱舊版背景音訊模型

背景音訊的需求

當您的應用程式位於背景時,您的應用程式必須符合下列音訊播放需求。

  • 背景媒體播放功能新增至您的應用程式資訊清單,如本文稍後所述。
  • 如果您的應用程式停用 MediaPlayer 與系統媒體傳輸控制項 (SMTC) 的自動整,例如將 CommandManager.IsEnabled 屬性設為 false,則您必須實作與 SMTC 的手動整合才能啟用背景媒體播放。 如果您使用 MediaPlayer 以外的 API,例如 AudioGraph,來播放音訊,如果您希望在應用程式移至背景時繼續播放音訊,則也必須手動與 SMTC 整合。 系統媒體傳輸控制項的手動控制之「使用背景音訊的系統媒體傳輸控制」一節描述了最低 SMTC 整合要求。
  • 當您的應用程式在背景執行時,您必須保持在系統為背景應用程式設定的記憶體使用量限制之下。 本文稍後會提供在背景中管理記憶體的指引。

背景媒體播放資訊清單功能

若要啟用背景音訊,您必須將背景媒體播放功能新增至應用程式資訊清單檔案 Package.appxmanifest。

使用資訊清單設計工具將功能新增至應用程式資訊清單

  1. 在 Microsoft Visual Studio 的 [方案總管] 中,按兩下 package.appxmanifest 項目,開啟應用程式資訊清單的設計工具。
  2. 選取 [功能] 索引標籤。
  3. 選取背景媒體播放核取方塊。

若要透過手動編輯應用程式資訊清單 xml 來設定功能,請先確保在套件元素中定義了 uap3 命名空間首碼。 如果沒有,請如下所示新增。

<Package
  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
  xmlns:uap3="http://schemas.microsoft.com/appx/manifest/uap/windows10/3"
  IgnorableNamespaces="uap uap3 mp">

接下來,將 backgroundMediaPlayback 功能新增至功能元素:

<Capabilities>
    <uap3:Capability Name="backgroundMediaPlayback"/>
</Capabilities>

處理前景和背景之間的轉換

當您的應用程式從前景移至背景時,會引發 EnteredBackground 事件。 當您的應用程式回到前景時,會引發 LeavingBackground 事件。 因為這些是應用程式生命週期事件,因此您應該在建立應用程式時註冊這些事件的處理常式。 在預設專案範本中,這意味著將其新增至 App.xaml.cs 中的 App 類別建構函式中。

public App()
{
    this.InitializeComponent();
    this.Suspending += OnSuspending;

    this.EnteredBackground += App_EnteredBackground;
    this.LeavingBackground += App_LeavingBackground;
}

建立變數來追蹤您目前是否在背景中執行。

bool _isInBackgroundMode = false;

引發 EnteredBackground 事件時,請設定追蹤變數,指出您目前正在背景中執行。 您不應該在 EnteredBackground 事件中執行長時間執行的工作,因為這可能會導致使用者覺得到背景的轉換速度很慢。

private void App_EnteredBackground(object sender, EnteredBackgroundEventArgs e)
{
    _isInBackgroundMode = true;
}

LeavingBackground 處理常式中,您應該設定追蹤變數以指示您的應用程式不再在背景執行。

private void App_LeavingBackground(object sender, LeavingBackgroundEventArgs e)
{
    _isInBackgroundMode = false;
}

記憶體管理需求

處理前景和背景之間轉換最重要的部分是管理應用程式所使用的記憶體。 由於在背景執行會減少系統允許您的應用程式保留的記憶體資源,因此您也應該註冊 AppMemoryUsageIncreasedAppMemoryUsageLimitChanging 事件。 引發這些事件時,您應該檢查應用程式的目前記憶體使用量和目前的限制,然後視需要減少記憶體使用量。 如需在背景執行時減少記憶體使用量的相關資訊,請參閱當應用程式移至背景時釋放記憶體

背景媒體應用程式的網路可用性

所有網路感知媒體來源 (不是從串流或檔案建立的媒體來源) 將在擷取遠端內容時保持網路連線處於使用中狀態,並在非使用中時釋放網路連線。 具體來說,MediaStreamSource 依賴應用程式使用 SetBufferedRange 向平台正確報告正確的緩衝範圍。 全部內容完全緩衝後,將不再代表應用程式保留網路。

如果您需要在媒體未下載時在背景進行網路呼叫,則必須將這些呼叫包裝在適當的工作中,例如 MaintenanceTriggerTimeTrigger。 如需詳細資訊,請參閱使用背景工作支援應用程式