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.

Tip

You can download the code for the Background Audio Player Sample and the Background Audio Streamer Sample. Code for a MediaStreamSource sample is also available. See also How to play background audio for Windows Phone 8.

This topic contains the following sections.

Background Audio Architecture

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).

Playlist Application

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.

Application UI

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.

AudioPlayerAgent

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.

Your AudioPlayerAgent runs in the background and calls into an instance of the BackgroundAudioPlayer, which then calls into the Zune Media Queue to actually play the audio.

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.

MediaStreamSource

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 AudioPlayerAgent is created by the BackgroundAudioPlayer as it is needed to process UserAction requests from either the user interface of your application or from the UVC.

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.

Background agents are disposed of when they call Abort()()() or NotifyComplete()()().

Other Background Audio Classes

A background audio application makes use of other classes to implement an audio player experience.

BackgroundAudioPlayer

The BackgroundAudioPlayer class interfaces with the Zune Media Queue. Call the methods on Instance to affect the audio playing on the device.

AudioTrack

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.

AudioStreamer

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.

Background Audio Best Practices

This section details some of the best practices to implement as you create applications that play background audio.

Debugging

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.

// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
    // Close the background audio player in case it 
    // was running from a previous debugging session.
    BackgroundAudioPlayer.Instance.Close();

    // ...

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:

  1. Successive calls to SkipNext, SkipPrevious, or Play will be processed in order regardless of how long they take.

  2. Each invocation is allowed 30 seconds.

  3. 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:

  1. IntermediatePlayState = BufferingStopped

  2. CurrentPlayState = Playing

  1. IntermediatePlayState = TrackEnded

  2. CurrentPlayState = Stopped

MediaElement and the BackgroundAudioPlayer

Care must be taken when mixing BackgroundAudioPlayer and MediaElement for audio playback.

  1. Close()()() must be called before switching to MediaElement playback.

  2. There is only one media queue. Your application cannot pause background audio, play something with MediaElement then resume the background audio stream.

Memory and Runtime Constraints

  • An implementation of AudioPlayerAgent must call NotifyComplete()()() or Abort()()() within 30 seconds.

  • 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.

See Also

Other Resources

Multitasking for Windows Phone 8

How to play background audio for Windows Phone 8

MediaStreamSource sample

Supported media codecs for Windows Phone 8