Background audio overview for Windows Phone 8
[ This article is for Windows Phone 8 developers. If you’re developing for Windows 10, see the latest documentation. ]
You can write apps for Windows Phone that play audio in the background. This means that even after the user has left your application by pressing the Back button or the Start button, your application can continue to play audio. This article discusses the components of a background audio application and how they work together.
Code for a MediaStreamSource sample is also available.
This topic contains the following sections.
A background audio application takes advantage of background agents, which were introduced in Windows Phone OS 7.1. For more information about background agents, see Multitasking for Windows Phone 8.
All media on Windows Phone is played through the Zune Media Queue. Your background audio application sends commands to the Zune Media Queue to set the current track, start playback, pause, fast forward, rewind, and so on. You do this by calling methods in the BackgroundAudioPlayer class. The Instance object then communicates with the Zune Media Queue to manipulate the playback of audio.
The Universal Volume Control (UVC) is the set of controls that appears on the lock screen when audio is playing or when the user presses the volume control switch. The UVC also manipulates the Zune Media Queue. Therefore, when you start playing something from your application, the audio can be subsequently controlled by using the UVC. The UVC sends events to the AudioPlayerAgent in your application, allowing you to implement playlist logic. There is more discussion of the AudioPlayerAgent later in this topic.
Background audio apps don’t require special configuration to run under the lock screen.
There are two types of background audio applications. One type implements a simple playlist and passes a Uri containing the address of a media file to the Zune Media Queue to set the current track. The Uri can be local to the phone or a remote address. In either case, the audio needs to be of a type supported by Windows Phone for playback. See Supported media codecs for Windows Phone 8 for valid audio file types.
The other type of background audio application uses MediaStreamSource to implement an audio stream to feed audio samples to the playback system. The format of this stream can be anything you want because you implement a class derived from MediaStreamSource to handle the streaming and decoding of audio. Implementing a MediaStreamSource is beyond the scope of this article.
These two types of applications share several pieces. We will start with a discussion of applications that implement a playlist. Then, we’ll discuss the pieces that implement streaming using MediaStreamSource (MSS).
To create a background audio playlist application, you must implement two pieces: an application that provides a user interface for controlling playback, and an assembly that implements a class derived from AudioPlayerAgent. The two pieces you must implement are in green in the following diagram.
The application user interface is where you implement the user interface for your application. If you use the Visual Studio template to create your initial application, this will be in the MainPage.xaml and MainPage.xaml.cs files. Your main application uses Instance to set the current track in the Zune Media Queue, initiate playback, and so on.
Your AudioPlayerAgent is instantiated by the operating system to handle actions requested by the user, either through your application’s user interface or through the UVC.
After your agent has finished processing OnUserAction(BackgroundAudioPlayer, AudioTrack, UserAction, Object), OnPlayStateChanged(BackgroundAudioPlayer, AudioTrack, PlayState), or OnError(BackgroundAudioPlayer, AudioTrack, Exception, Boolean), call NotifyComplete() to let the operating system know that you are finished and the agent can be safely removed from memory.
Use the Windows Phone Audio Playback Agent template in Visual Studio to create a new AudioPlayerAgent project and add it to your solution.
Then, add a reference to the new AudioPlayerAgent from your main application project.
Right-click the References node in the application project and select Add Reference…
Streaming Audio Application
To create a streaming audio application, you must implement the same pieces as a Playlist Application. Specifically, you must create a main application that supplies the user interface, and an AudioPlayerAgent. For a streaming audio application, you must also implement a class derived from AudioStreamingAgent and a class derived from MediaStreamSource. The pieces you must implement are in green in the following diagram.
Audio Streaming Agent
The AudioStreamingAgent is responsible for creating and pointing the Zune Media Queue to a MediaStreamSource by calling SetSource(MediaStreamSource) on the AudioStreamer instance that is passed in to the OnBeginStreaming(AudioTrack, AudioStreamer) method.
Use the Windows Phone Audio Streaming Agent template in Visual Studio to create a new AudioStreamingAgent project and add it to your solution.
The Zune Media Queue makes calls to your MediaStreamSource to request audio samples. Creating a MediaStreamSource is beyond the scope of this topic. For more information, see the MediaStreamSource sample.
Background Agent Lifecycle
Your AudioStreamingAgent is created by the BackgroundAudioPlayer when it needs a new stream. After your agent is created, the BackgroundAudioPlayer calls the OnBeginStreaming(AudioTrack, AudioStreamer) method in your AudioStreamingAgent.
Other Background Audio Classes
A background audio application makes use of other classes to implement an audio player experience.
The AudioTrack class represents the metadata about a track, including the title, artist, album, and URI to the track. If the URI is set to null, the system assumes you are setting the track to a MediaStreamSource In this case, you can use the Tag property to pass information from the AudioPlayerAgent to the AudioStreamingAgent.
An instance of AudioStreamer is passed into OnBeginStreaming(AudioTrack, AudioStreamer). In your implementation of OnBeginStreaming, call SetSource(MediaStreamSource) to point to a class that derives from MediaStreamSource, which supplies audio samples.
This section details some of the best practices to implement as you create applications that play background audio.
During the process of coding, debugging, editing code, and restarting debugging, the debugger might attach itself to the background audio agent instead of your application when you restart debugging. To avoid this, you need to make sure the background agent is closed when your application starts. A convenient way to accomplish this is to put a call to Close() in the constructor of your App class. If you created your app from the Visual Studio templates, there is a check in the App class constructor to see if it is running under the debugger. Put the call to BackgroundAudioPlayer.Instance.Close inside this if statement.
Processing User Actions
The BackgroundAudioPlayer doesn't impose any limits on the number of UserAction requests. Actions invoked through the UI, either through your app or the Universal Volume Control (UVC), are queued up and processed one by one. The AudioPlayerAgent has no means to determine if there are successive calls. SkipNext, SkipPrevious, or Play calls that require network requests can take several seconds.
The implication on the user experience is:
Each invocation is allowed 30 seconds.
Because Play and Pause actions don't get priority, the agent can take several seconds (or even minutes) to respond to user actions. This violates the expected user experience of immediate responsiveness to Play and Pause.
Limit the number of queued up SkipNext and SkipPrevious requests and give higher priority to Play and Pause. The Background Audio Player Sample simply disables the next and prev buttons until the request is processed.
Handling state transitions
When the state of the BackgroundAudioPlayer changes, you can capture information about the state transition from the PlayStateChangedEventArgs. You can determine both the CurrentPlayState and the IntermediatePlayState that occurred before the audio player entered the current play state.
Here are some examples of the state transitions that you can handle with the information provided by the event arguments:
MediaElement and the BackgroundAudioPlayer
Memory and Runtime Constraints
An implementation of AudioStreamingAgent is allowed unlimited run time.
Both types of background audio agents are hosted in the same process and share the following maximum memory limits.
25 MB on Windows Phone 8 with Windows Phone 8 Update 3 (that is, with a version equal to or greater than 8.0.10492).
20 MB on Windows Phone 8 without Windows Phone 8 Update 3 (that is, with a version less than 8.0.10492).
15 MB on Windows Phone OS 7.1.
When running under the debugger, the memory and run-time constraints are ignored by the Windows Phone operating system.