Воспроизведение мультимедиа в фоновом режиме

В этой статье показано, как настроить приложение, чтобы воспроизведение мультимедиа продолжалось, когда приложение переходит в фоновый режим. Это значит, что даже после того, как пользователь свернет приложение, вернется на начальный экран или выйдет из приложения другим способом, ваше приложение продолжит воспроизводить звук.

Сценарии воспроизведения звука в фоновом режиме включают следующие элементы.

  • Долговременные плей-листы. Пользователь кратковременно вызывает приложение переднего плана, чтобы выбрать и запустить плей-лист. После этого пользователь ожидает, что плей-лист продолжит воспроизведение в фоновом режиме.

  • Использование переключателя задач: пользователь кратковременно вызывает приложение переднего плана, чтобы запустить воспроизведение звука, а затем с помощью переключателя задач переключается на другое открытое приложение. Пользователь ожидает, что воспроизведение звука продолжится в фоновом режиме.

В этой статье описано, как повсеместно реализовать воспроизведение приложением звука в фоновом режиме на всех устройствах с Windows, включая мобильные устройства, настольные компьютеры и консоли Xbox.

Примечание

В этой статье используется код, адаптированный из примера воспроизведения звука в фоновом режиме на платформе UWP.

Описание модели одного процесса

В Windows 10 версии 1607 представлена новая модель одного процесса, которая значительно упрощает работу с фоновым звуком. Ранее приложение должно было управлять фоновым процессом, в дополнение к приложению переднего плана, а затем вручную передавать изменения состояния между двумя процессами. В новой модели вы просто добавляете возможность фонового звука в манифест приложения, и оно автоматически будет продолжать воспроизводить звук после перехода в фоновый режим. Два новых события жизненных цикла приложения, EnteredBackground и LeavingBackground, позволяют приложению определить, когда оно переходит в фоновый режим и выходит из него. Когда приложение переходит в фоновый режим или выходит из него, ограничения памяти, применяемые системой, могут изменяться, поэтому вы можете использовать эти события, чтобы узнать текущий объем используемой памяти и освободить ресурсы, чтобы не нарушать ограничение.

За счет устранения сложных механизмов взаимодействия между процессами и управления состоянием новая модель позволяет гораздо быстрее реализовать фоновое воспроизведение звука, значительно сократив объем кода. Однако модель с двумя процессами по-прежнему поддерживается в текущем выпуске для обеспечения обратной совместимости. Подробнее: Старая модель воспроизведения звука в фоновом режиме.

Требования для фонового воспроизведения звука

Приложение должно соответствовать следующим требованиям для воспроизведения звука в фоновом режиме.

  • Добавьте возможность Воспроизведение мультимедиа в фоновом режиме в манифест приложения, как описано далее в этой статье.
  • Если приложение отключает автоматическую интеграцию MediaPlayer с системными элементами управления транспортировкой мультимедиа (SMTC), например если свойству CommandManager.IsEnabled присвоено значение false, то необходимо вручную реализовать интеграцию с SMTC для использования функции воспроизведения мультимедиа в фоновом режиме. Также необходимо вручную интегрироваться с SMTC, если вы используете API, отличный от MediaPlayer, например AudioGraph, для воспроизведения звука, если вы хотите, чтобы звук продолжал воспроизводиться при переходе приложения в фоновый режим. Минимальные требования к интеграции SMTC описаны в разделе "Использование системных элементов управления транспортом мультимедиа для воспроизведения звука в фоновом режиме" статьи Ручное управление системными элементами управления воспроизведением мультимедиа.
  • Когда приложение работает в фоновом режиме, вам нужно следить за тем, чтобы не превышать ограничения использования памяти, заданные системой для фоновых приложений. Рекомендации по управлению памятью в фоновом режиме представлены далее в этой статье.

Возможность воспроизведения мультимедиа в фоновом режиме в манифесте

Чтобы включить фоновое воспроизведение звука, следует добавить возможность воспроизведения мультимедиа в фоновом режиме в файл манифеста приложения, Package.appxmanifest.

Добавление возможностей в манифест приложения с помощью конструктора манифестов

  1. В Microsoft Visual Studio откройте конструктор манифеста приложения, дважды щелкнув элемент package.appxmanifest в Обозревателе решений.
  2. Перейдите на вкладку Возможности.
  3. Установите флажок Воспроизведение мультимедиа в фоновом режиме.

Чтобы вручную добавить возможность в XML-файле манифеста приложения, сначала убедитесь, что в элементе Package задан префикс пространства имен 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 :

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

Обработка перехода между передним планом и фоновым режимом

Когда приложение переходит с переднего плана в фоновый режим, создается событие EnteredBackground. Когда приложение возвращается на передний план, вызывается событие LeavingBackground. Поскольку это события жизненного цикла приложения, вам следует зарегистрировать обработчики этих событий при создании приложения. Для этого в шаблоне проекта по умолчанию нужно добавить его в конструктор класса App в файле App.xaml.cs.

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;
}

Требования к управлению памятью

Самая важная часть обработки перехода между фоном и передним планом — управление памятью, которую использует ваше приложение. Так как в фоновом режиме объем ресурсов памяти, доступных приложению, уменьшается, вы также должна зарегистрироваться для прослушивания событий AppMemoryUsageIncreased и AppMemoryUsageLimitChanging. Когда эти события возникают, следует сравнить текущий объем памяти, занимаемой приложением, с текущим ограничением и при необходимости уменьшить его. Сведения об уменьшении объема используемой памяти в фоновом режиме см. в разделе Освобождение памяти при переходе приложения в фоновый режим.

Доступность сети для мультимедиа-приложений в фоновом режиме

Все источники мультимедиа, использующие сеть и не созданные из потока или файла, сохраняют активное подключение при получении удаленного содержимого, и отключают его в противном случае. В частности, MediaStreamSource ждет, что приложение будет предоставлять буферизированный диапазон платформе с помощью SetBufferedRange. После полной буферизации всего содержимого сеть больше не будет зарезервирована со стороны приложения.

Если вам необходимо выполнить сетевые вызовы, которые будут происходить в фоновом режиме, когда мультимедиа не загружается, для них необходимо создать оболочку в соответствующей задаче, такой как MaintenanceTrigger или TimeTrigger. Дополнительные сведения см. в статье Поддержка приложения с помощью фоновых задач.