Традиционное воспроизведение мультимедиа в фоновом режимеLegacy background media playback

В этой статье описывается традиционная двухпроцессная модель добавления поддержки воспроизведения звука в фоновом режиме в приложение UWP.This article describes the legacy, two-process model for adding background audio support to your UWP app. Начиная с Windows 10 версии 1607 используется однопроцессная модель для воспроизведения звука в фоновом режиме, которую гораздо проще реализовать.Starting with Windows 10, version 1607, a single-process model for background audio that is much simpler to implement. Дополнительные сведения о текущих рекомендациях по воспроизведению звука в фоновом режиме см. в разделе Воспроизведение мультимедиа в фоновом режиме.For more information on the current recommendations for background audio, see Play media in the background. В этой статье предоставляется поддержка для приложений, разработанных с использованием традиционной двухпроцессной модели.This article is intended to provide support for apps that are have already been developed using the legacy two-process model.

Примечание

Начиная с Windows версии 1703 баккграундмедиаплайер устарела и может быть недоступна в будущих версиях Windows.Starting with Windows, version 1703, BackgroundMediaPlayer is deprecated and may not be available in future versions of Windows.

Архитектура фонового звукаBackground audio architecture

Приложение, отвечающее за воспроизведение в фоновом режиме, выполняет два процесса.An app performing background playback consists of two processes. Первый процесс — это основное приложение, содержащее пользовательский интерфейс приложения и клиентскую логику, которые выполняются на переднем плане.The first process is the main app, which contains the app UI and client logic, running in the foreground. Второй процесс — задача воспроизведения в фоновом режиме, которая реализует интерфейс IBackgroundTask, как и все фоновые задачи приложений UWP.The second process is the background playback task, which implements IBackgroundTask like all UWP app background tasks. Фоновая задача содержит логику воспроизведения в фоновом режиме и фоновые службы.The background task contains the audio playback logic and background services. Фоновая задача взаимодействует с системой с помощью системных элементов управления транспортировкой мультимедийных данных.The background task communicates with the system through the System Media Transport Controls.

На следующей схеме представлен обзор разработанной системы.The following diagram is an overview of how the system is designed.

Архитектура фонового звука в Windows 10

MediaPlayerMediaPlayer

Пространство имен Windows.Media.Playback включает интерфейсы API, используемые для воспроизведения звука в фоновом режиме.The Windows.Media.Playback namespace contains APIs used to play audio in the background. У каждого приложения есть один экземпляр класса MediaPlayer, обеспечивающий воспроизведение.There is a single instance of MediaPlayer per app through which playback occurs. Ваше приложение для воспроизведения звука в фоновом режиме вызывает методы и устанавливает свойства для класса MediaPlayer, чтобы задать текущую дорожку, начать воспроизведение, выполнить приостановку, перемотку вперед или назад и т. д.Your background audio app calls methods and sets properties on the MediaPlayer class to set the current track, start playback, pause, fast forward, rewind, and so on. Доступ к экземпляру объекта проигрывателя мультимедиа всегда обеспечивается с помощью свойства BackgroundMediaPlayer.Current.The media player object instance is always accessed through the BackgroundMediaPlayer.Current property.

Прокси-сервер и заглушка MediaPlayerMediaPlayer Proxy and Stub

Когда вы получаете доступ к свойству BackgroundMediaPlayer.Current из фонового процесса приложения, в основном элементе фоновой задачи активируется экземпляр MediaPlayer, которым можно непосредственно управлять.When BackgroundMediaPlayer.Current is accessed from your app's background process, the MediaPlayer instance is activated in the background task host and can be manipulated directly.

Когда вы получаете доступ к свойству BackgroundMediaPlayer.Current из приложения переднего плана, возвращенный экземпляр MediaPlayer фактически представляет собой прокси-сервер, который обменивается данными с заглушкой в фоновом процессе.When BackgroundMediaPlayer.Current is accessed from the foreground application, the MediaPlayer instance that is returned is actually a proxy that communicates with a stub in the background process. Эта заглушка взаимодействует с фактическим экземпляром MediaPlayer, который также размещен в фоновом процессе.This stub communicates with the actual MediaPlayer instance, which is also hosted in the background process.

Как процесс переднего плана, так и фоновый процесс могут получать доступ к большинству свойств экземпляра MediaPlayer. Исключение составляют свойства MediaPlayer.Source и MediaPlayer.SystemMediaTransportControls, доступные только из фонового процесса.Both the foreground and background process can access most of the properties of the MediaPlayer instance, with the exception of MediaPlayer.Source and MediaPlayer.SystemMediaTransportControls which can only be accessed from the background process. Приложение переднего плана и фоновый процесс могут получать уведомления о событиях, связанных с мультимедиа, таки как MediaOpened, MediaEnded и MediaFailed.The foreground app and the background process can both receive notifications of media-specific events like MediaOpened, MediaEnded, and MediaFailed.

Списки воспроизведенияPlayback Lists

Распространенный сценарий для приложений фонового звука — воспроизведение нескольких элементов в строке.A common scenario for background audio applications is to play multiple items in a row. Этот сценарий легче всего реализовать в фоновом процессе с помощью объекта MediaPlaybackList, который можно установить в качестве источника для класса MediaPlayer, назначив его свойству MediaPlayer.Source.This is most easily accomplished in your background process by using a MediaPlaybackList object, which can be set as a source on the MediaPlayer by assigning it to the MediaPlayer.Source property.

Доступ к объекту MediaPlaybackList невозможно получить из процесса переднего плана, который задан в фоновом процессе.It is not possible to access a MediaPlaybackList from the foreground process that was set in the background process.

Системные элементы управления транспортом мультимедиаSystem Media Transport Controls

Пользователь может управлять воспроизведением звука, не используя непосредственно пользовательский интерфейс приложения, с помощью таких средств, как устройства Bluetooth, SmartGlass и системные элементы управления транспортировкой мультимедийных данных.A user may control audio playback without directly using your app's UI through means such as Bluetooth devices, SmartGlass, and the System Media Transport Controls. Ваша фоновая задача использует класс SystemMediaTransportControls для подписки на эти системные события, инициализированные пользователем.Your background task uses the SystemMediaTransportControls class to subscribe to these user-initiated system events.

Чтобы получить экземпляр SystemMediaTransportControls из фонового процесса, используйте свойство MediaPlayer.SystemMediaTransportControls.To get a SystemMediaTransportControls instance from within the background process, use the MediaPlayer.SystemMediaTransportControls property. Приложения переднего плана получают экземпляр класса путем вызова метода SystemMediaTransportControls.GetForCurrentView, но при этом возвращается только экземпляр переднего плана, не связанный с фоновой задачей.Foreground apps get an instance of the class by calling SystemMediaTransportControls.GetForCurrentView, but the instance returned is a foreground-only instance that does not relate to the background task.

Отправка сообщений между задачамиSending Messages Between Tasks

Иногда возникает необходимость установить связь между двумя процессами приложения фонового звука.There are times when you will want to communicate between the two processes of a background audio app. Например, может потребоваться, чтобы фоновая задача уведомляла задачу переднего плана, что начинается проигрывание новой дорожки, и отправляла в задачу переднего плана название новой песни для отображения на экране.For example, you might want the background task to notify the foreground task when a new track starts playing, and then send the new song title to the foreground task to display on the screen.

Простой механизм связи позволяет вызывать события как в процессе переднего плана, так и в фоновом процессе.A simple communication mechanism raises events in both the foreground and background processes. Каждый из методов SendMessageToForeground и SendMessageToBackground вызывает события в соответствующем процессе.The SendMessageToForeground and SendMessageToBackground methods each invoke events in the corresponding process. Сообщения можно получить путем подписки на события MessageReceivedFromBackground и MessageReceivedFromForeground.Messages can be received by subscribing to the MessageReceivedFromBackground and MessageReceivedFromForeground events.

Данные можно передавать в качестве аргумента методам отправки сообщений, которые затем передаются в обработчики событий полученных сообщений.Data can be passed as an argument to the send message methods that are then passed into the message received event handlers. Передавайте данные с помощью класса ValueSet.Pass data using the ValueSet class. Этот класс представляет собой словарь, содержащий строку в качестве ключа и другие типы значений в качестве значений.This class is a dictionary that contains a string as a key and other value types as values. Вы можете передавать простые типы значений, такие как целые числа, строки и логические значения.You can pass simple value types such as integers, strings, and booleans.

Время существования фоновой задачиBackground Task Life Cycle

Время существования фоновой задачи тесно связано с текущим состоянием воспроизведения приложения.The lifetime of a background task is closely tied to your app's current playback status. Например, когда пользователь приостанавливает воспроизведение звука, система может завершить или отменить работу вашего приложения в зависимости от обстоятельств.For example, when the user pauses audio playback, the system may terminate or cancel your app depending on the circumstances. Если звук не будет воспроизводиться в течение некоторого времени, система может автоматически завершить работу фоновой задачи.After a period of time without audio playback, the system may automatically shut down the background task.

Метод IBackgroundTask.Run вызывается, когда приложение в первый раз получает доступ к свойству BackgroundMediaPlayer.Current из кода, выполняемого в приложении переднего плана, либо когда вы регистрируете обработчик события MessageReceivedFromBackground в зависимости от того, что происходит раньше.The IBackgroundTask.Run method is called the first time your app accesses either BackgroundMediaPlayer.Current from code running in the foreground app or when you register a handler for the MessageReceivedFromBackground event, whichever occurs first. Рекомендуется зарегистрировать обработчик полученного сообщения, прежде чем вызывать свойство BackgroundMediaPlayer.Current в первый раз, чтобы приложение переднего плана не пропустило сообщения, отправленные из фонового процесса.It is recommended that you register for the message received handler before calling BackgroundMediaPlayer.Current for the first time so that the foreground app doesn't miss any messages sent from the background process.

Чтобы поддерживать активность фоновой задачи, ваше приложение должно запросить класс BackgroundTaskDeferral из метода Run и вызвать метод BackgroundTaskDeferral.Complete, когда экземпляр задачи получает события Canceled или Completed.To keep the background task alive, your app must request a BackgroundTaskDeferral from within the Run method and call BackgroundTaskDeferral.Complete when the task instance receives the Canceled or Completed events. Не используйте цикл или ожидание в методе Run, так как это ведет к потреблению ресурсов и может вызвать прерывание выполнения вашего приложения в фоновом режиме.Do not loop or wait in the Run method because this consumes resources and may cause your app's background task to be terminated by the system.

Ваша фоновая задача получает событие Completed, когда завершается метод Run и не запрашивается отсрочка выполнения.Your background task gets the Completed event when the Run method is completed and deferral is not requested. В некоторых случаях, когда ваше приложение получает событие Canceled, за ним может следовать событие Completed.In some cases, when your app gets the Canceled event, it can be also followed by the Completed event. Ваша задача может получить событие Canceled даже при выполнении метода Run, поэтому обязательно отслеживайте такую возможность синхронного захвата.Your task may receive a Canceled event while Run is executing, so be sure to manage this potential concurrence.

Фоновая задача может быть отменена в следующих ситуациях.Situations in which the background task can be cancelled include:

  • В системах, в которых применяется вспомогательная политика монопольности, запускается новое приложение, поддерживающее воспроизведение звука.A new app with audio playback capabilities starts on systems that enforce the exclusivity sub-policy. См. раздел Политики системы в течение времени существования фоновой задачи ниже.See the System policies for background audio task lifetime section below.

  • Фоновая задача запущена, но воспроизведение музыки не началось. В этом случае фоновая задача приостанавливается.A background task has been launched but music is not yet playing, and then the foreground app is suspended.

  • Воспроизведение мультимедиа прерывается другими способами, например вследствие входящих телефонных звонков или вызовов по протоколу VoIP.Other media interruptions, such as incoming phone calls or VoIP calls.

Фоновая задача может быть завершена без предварительного уведомления в следующих ситуациях.Situations in which the background task can be terminated without notice include:

  • При поступлении вызова по протоколу VoIP в системе имеется недостаточно доступной памяти, чтобы поддерживать активность фоновой задачи.A VoIP call comes in and there is not enough available memory on the system to keep the background task alive.

  • Нарушается политика ресурсов.A resource policy is violated.

  • Имеют место аварийные отмена или завершение задачи.Task cancellation or completion does not end gracefully.

Политики системы в течение времени существования фоновой задачиSystem policies for background audio task lifetime

Следующие политики помогают определить, как система управляет временем существования фоновых задач воспроизведения звука.The following policies help determine how the system manages the lifetime of background audio tasks.

МонопольностьExclusivity

Если включить эту вспомогательную политику, число фоновых задач воспроизведения звука будет ограничено до 1 в любой момент времени.If enabled, this sub-policy limits the number of background audio tasks to be at most 1 at any given time. Эта политика активируется на мобильных устройствах и других SKU, отличных от настольных компьютеров.It is enabled on Mobile and other non-Desktop SKUs.

Время ожидания активностиInactivity Timeout

Из-за ограничений на ресурсы система может завершить фоновую задачу после бездействия в течение определенного периода.Due to resource constraints, the system may terminate your background task after a period of inactivity.

Фоновая задача считается "неактивной", если выполнены оба следующих условия:A background task is considered “inactive” if both of the following conditions are met:

  • приложение переднего плана невидима (его работа приостановлена или прекращена);The foreground app is not visible (it is suspended or terminated).

  • мультимедиапроигрыватель не воспроизводит содержимое в фоновом режиме.The background media player is not in the playing state.

Если удовлетворены оба этих условия, системная политика воспроизведения мультимедийных данных в фоновом режиме запустит таймер.If both of these conditions are satisfied, the background media system policy will start a timer. Если ни одно из условий не изменилось по завершении отсчета таймера, эта системная политика прекратит выполнение фоновой задачи.If neither condition has changed when the timer expires, the background media system policy will terminate the background task.

Общее время существованияShared Lifetime

Если включить эту вспомогательную политику, фоновая задача будет зависеть от времени существования задачи переднего плана.If enabled, this sub-policy forces the background task to be dependent on the lifetime of the foreground task. Если выполнение задачи переднего плана прекращено (пользователем или системой), фоновая задача также завершит работу.If the foreground task is shut down, either by the user or the system, the background task will also shut down.

Однако обратите внимание, что это не значит, что задача переднего плана зависит от фоновой задачи.However, note that this does not mean that the foreground is dependent on the background. Прекращение фоновой задачи не приводит к завершению работы задачи переднего плана.If the background task is shut down, this does not force the foreground task to shut down.

В следующей таблице перечислены политики, применяемые к устройствам определенных типов.The following table lists the which policies are enforced on which device types.

Вспомогательная политикаSub-policy Классические приложенияDesktop Мобильные приложенияMobile ДругоеOther
МонопольностьExclusivity ВыключеноDisabled АктивированоEnabled АктивированоEnabled
Время ожидания бездействияInactivity Timeout ВыключеноDisabled АктивированоEnabled ВыключеноDisabled
Общее время существованияShared Lifetime АктивированоEnabled ВыключеноDisabled ВыключеноDisabled