May 2012

Volume 27 Number 05

Windows Phone - Creating Media Apps for Windows Phone

By Mark Hopkins | May 2012

Windows Phone is a great platform for consuming media. The built-in media player and the Windows Phone Marketplace are my main sources of listening material for both music and my favorite podcasts. I listen at the gym, in the car, on the bus and even while I’m getting ready for my day. I love media apps that help me discover material I might not otherwise know about. For example, I learn about a lot of new music through the built-in Smart DJ feature, as well as various other streaming music apps. Several apps allow me to access video content provided by YouTube and Vimeo.

If you’re interested in creating media apps for Windows Phone, you need to put a number of pieces in place to integrate well with the OS. In particular, you’ll want to make sure your app participates and surfaces in the Music + Videos Hub.

Integrating with the Music + Videos Hub

“Hubs” provide a convenient place for users to find their content. The Music + Videos Hub is the go-to place for media on a Windows Phone-based device. You go there not only to see your content, but also because it provides instant access to the media that’s most relevant to you. Based on research done by the Windows Phone team, we’ve learned that the most common things users want to do are:

  1. Resume something they were playing.
  2. Get to the content they play most frequently.
  3. Find content that they’ve just added to their phone.

The Music + Videos Hub puts content in these three categories front and center while also aggregating media apps and the local media library in a single experience. Figure 1 shows the full panorama view of the Music + Videos Hub on Windows Phone.

The Music + Videos Hub on Windows Phone
Figure 1 The Music + Videos Hub on Windows Phone

Besides being great for end users, the Music + Videos Hub provides a great deal of value to your applications. It requires no proactive user customization, so your content is easily discoverable. If you have an application that provides playback of music or video content, you should integrate with the Music + Videos Hub. It’s an important part of what the Window Phone experience is all about.

There are four key integration points that your application can take advantage of in the music and videos experience:

  1. Populating the Now Playing tile.
  2. Adding items to the New and History lists.
  3. Determining if your app was launched from a New or History item.
  4. Integrating into the Apps list.

Populating the Now Playing Tile

This tile is the most prominent real estate in the Music + Videos Hub, displaying a relatively large image of whatever content is currently paused or was last played. Tapping on this tile will either resume or initiate playback of the content displayed. By populating this image you both promote your content and create an additional entry point into your app’s playback experience. Update the Now Playing item by setting the MediaHistory.Instance.NowPlaying property, as shown in the following code snippet (I’m using C# in this article):

MediaHistoryItem mediaHistoryItem = new MediaHistoryItem();
// <hubTileImageStream> must be a valid ImageStream.
mediaHistoryItem.ImageStream = <hubTileImageStream>;
mediaHistoryItem.Source = "";
mediaHistoryItem.Title = "NowPlaying";
mediaHistoryItem.PlayerContext.Add("keyString", "Song Name");
MediaHistory.Instance.NowPlaying = mediaHistoryItem;

Adding History Items

Content that has been played most recently on the phone can be displayed in a History tile by calling the MediaHistory.Instance.WriteRecentPlay method. Just like the Now Playing tile, History tiles display images and can be tapped to launch playback of the content they contain. Here’s how to update the History list:

MediaHistoryItem mediaHistoryItem = new MediaHistoryItem();
// <hubTileImageStream> must be a valid ImageStream.
mediaHistoryItem.ImageStream = <hubTileImageStream>;
mediaHistoryItem.Source = "";
mediaHistoryItem.Title = "RecentPlay";
mediaHistoryItem.PlayerContext.Add("keyString", "Song Name");
MediaHistory.Instance.WriteRecentPlay(mediaHistoryItem);

Adding New Items

“New” tiles function the same as History tiles, but display recently added phone content. For example, a New tile might promote a music file that’s just been downloaded to the phone. However, these tiles can also be used for things such as newly created radio stations or playlists. The same action of initiating playback on tile-touch applies here. The following code demonstrates how to update the New list:

MediaHistoryItem mediaHistoryItem = new MediaHistoryItem();
// <hubTileImageStream> must be a valid ImageStream.
mediaHistoryItem.ImageStream = <hubTileImageStream>;
mediaHistoryItem.Source = "";
mediaHistoryItem.Title = "MediaHistoryNew";
mediaHistoryItem.PlayerContext.Add("keyString", "Song Name");
MediaHistory.Instance.WriteAcquiredItem(mediaHistoryItem);

Determining How Your App Was Launched

History and New tiles should only be used to start playback and shouldn’t be used as generic launch points into your application. It’s OK if your app is launched and your UI is displayed. The important thing is that the music or video should start with a single tap, so the experience is efficient and consistent.

To determine if your app was launched from a History or New tile, start by overriding the OnNavigatedTo virtual method. The information in the NavigationContext is used to determine the media associated with the item, in this case a song from the media library on the device. The song starts playing in the Loaded event handler for the PhoneApplicationPage after the page has finished loading. For more information about this, download the Music + Videos Hub Sample in the MSDN Library at bit.ly/y0tEiX.

The code in Figure 2shows how to determine whether the application was launched from an item in the History or New list.

Figure 2 Determining Whether an App Was Launched from an Item in the History or New List

// Indicates whether the app was launched from a MediaHistoryItem.
bool _historyItemLaunch = false;
// Key for MediaHistoryItem key-value pair.
const String _playSongKey = "keyString";   
// The song to play.
Song _playingSong = null;
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
  MediaLibrary library = new MediaLibrary();
  if (NavigationContext.QueryString.ContainsKey(_playSongKey))
  {
    // The app launched from a history item.
    // Change _playingSong even if something was already playing
    // because the user directly chose a song history item.
    // Use the navigation context to find the song by name.
    String songToPlay = NavigationContext.QueryString[_playSongKey];
    foreach (Song song in library.Songs)
    {
      if (0 == String.Compare(songToPlay, song.Name))
      {
        _playingSong = song;
        break;
      }
    }
    // Set a flag to indicate that the app started from a
    // history item and that it should immediately start
    // playing the song after the UI has finished loading.
    _historyItemLaunch = true;
  }
}
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
  if (_historyItemLaunch)
  {
    // Launched from a history item, start playing the song.
    if (_playingSong != null)
    {
      MediaPlayer.Play(_playingSong);
    }
  }
}

Integrating with the Apps Page

If your application calls one or more of the aforementioned APIs, it will automatically appear in the Apps list inside the Hub, in addition to appearing in the main applications list. This makes it easier to find and access your application and makes it a part of the core media experience. This automatic integration happens when the App Hub submission and certification process detects that your application calls the MediaHistory and MediaHistoryItem APIs and changes the application manifest to reflect that it’s a media app by setting the HubType attribute. You can set this yourself prior to submission—for testing purposes only—by updating the <App> element in the WMAppManifest.xml file in your Windows Phone project:

<App  ... HubType="1">

This will allow your program to show up in the Apps list while testing. Note that the AppHub submission process will overwrite this file before publishing based on the APIs it detects that you’re calling in your application.

Required Graphics Files

Because the Music + Videos Hub is content-centric, the amount of real estate that each application gets is based on usage. This means the more your app gets used, the more prominent your content will be. For customers who use your application regularly, the Music + Videos Hub will become filled with your content, giving you an excellent promotional opportunity.

Because the Music + Videos Hub aggregates content from many different sources, it’s important that you think about visual tile design, which will distinguish your app from others. What this means will vary based on your app. Keep in mind that, for example, the user will have generic album art shown in that same list for his actual albums. If you have a radio station that just happens to be playing a song from an album, your radio station app should display a tile that is visually distinct from the album cover artwork you’d see when playing the song from the media library. Consider using tiles that show your brand and artwork for the content.

Tiles that are displayed in the Music + Videos Hub must conform to the following iconography rules:

  • You must include your application title or logo on each tile.
  • The Now Playing tile must be 358 x 358 pixels. The file size must be 75KB or less.
  • Other tiles must be 173 x 173 pixels.
  • The Title property of the MediaHistoryItem class must be set to text that represents the content, such as a station name or video title.

To help avoid confusion for users, tiles shouldn’t contain album art unless the album plays when the tile is pressed. If your application plays a stream, the tile graphic should describe the stream that’s being played. While this isn’t a certification requirement, it is a best practice.

Playing Media

When playing video, the experience is similar whether you create an XNA Framework or a Silverlight app. In an XNA Framework app, use the MediaPlayerLauncher class, which launches the Windows Phone media player when you call MediaPlayerLauncher.Show. In Silverlight, use the MediaElement API, which allows more customization of the user experience—such as the look and placement of controls—but ultimately uses the Windows Phone media player to actually display the video. For audio, it gets a bit more interesting.

MediaElement vs. SoundEffect

In an XNA Framework application, use the SoundEffect class (or the related SoundEffectInstance or DynamicSoundEffectInstance classes) to play audio. These classes support playback of WAV audio sources only. However, you have greater control over playback and can use some nice features, such as the ability to play up to 16 sounds at once and have them mixed together on output.

In a Silverlight application, you can use the MediaElement class for playing audio in addition to video. MediaElement supports playback of WAV, WMA, MP3 and other audio sources. See the Supported Media Codecs for Windows Phone (bit.ly/aflZrb) for a complete list of audio formats playable on Windows Phone. MediaElement only allows one sound to play at a time. If another sound is already playing, MediaElement will stop it when you initiate playback of a new sound.

In a Silverlight application, you can also use the SoundEffect class to play audio. In order to use an XNA Framework API in a Silverlight application, you’ll need to simulate the Game loop found in XNA Framework applications. To do this, I usually create a method called StartGameLoop to set up a GameTimer. I call the StartGameLoop method from the constructor of my PhoneApplicationPage derived class (see Figure 3). GameTimer is a new class available in the Windows Phone 7.1 SDK to facilitate Silverlight and XNA Framework integration.

Figure 3 My Silverlight StartGameLoop Simulates an XNA Framework Game Loop

// Constructor
public MainPage()
{
  InitializeComponent();
   StartGameLoop();
}
private void StartGameLoop()
{
  // Timer to simulate the XNA game loop (SoundEffect
  // class is from the XNA Framework).
  GameTimer gameTimer = new GameTimer();
  gameTimer.UpdateInterval = TimeSpan.FromMilliseconds(33);
  // Call FrameworkDispatcher.Update to update the XNA Framework internals.
  gameTimer.Update += delegate { try { FrameworkDispatcher.Update(); } catch { } };
  // Start the GameTimer running.
  gameTimer.Start();
  // Prime the pump or you'll get an exception
  // on the first XNA Framework call.
  FrameworkDispatcher.Update();
}

After implementing this timer loop, you can call XNA Framework APIs elsewhere in your PhoneApplicationPage derived class.

Marketplace Certification

When an application calls the MediaHistory or MediaHistoryItem classes, it’s considered to be a Music + Videos Hub application and will appear in the Apps list when installed on the phone. The submission process detects that the application uses these classes and automatically updates the hub type to Music + Videos in the Windows Phone application manifest file.

Several certification requirements regarding media playback must be followed in order for your app to be accepted into the Marketplace. At the time this article was written, these were documented in sections 6.4 and 6.5 of the Application Certification Requirements for Windows Phone at bit.ly/kN6N7Z. Certification requirements are always subject to change and are updated on a regular basis, so for any of the following guidance, make sure you’re up to speed on the most recent version.

The certification requirements dictate that you can’t interrupt the music a user has playing when your app launches. This makes sense because a user might enjoy listening to her favorite music while she interacts with a game, for example. Sections 6.5.1 and 6.5.2 address this particular scenario.

Of additional interest is section 6.5.3, which states:

An application may interrupt currently playing music on the phone to play a non-interactive full motion video, or a non-interactive audio segment (e.g. cut-scene or media clip) without asking for user consent.

An application must resume the music that was previously playing, once the application is closed.

So, how do you pause and restart the user’s music? If you’re creating a Silverlight app, you’ll need to set up the simulated Game loop, as detailed earlier.

I experimented with pausing the currently playing audio, playing my sound effect and immediately restarting the audio that was playing. This created a jarring user experience and really diminished the impact of the sound effect I wanted to play. So I ended up pausing the currently playing audio when the user navigates to my page, then restarting it when she navigates away. I did this by overriding the OnNavigatedTo and OnNavigatedFrom methods. Inside those overridden methods, I call helper functions to pause and restart the audio, as shown in Figure 4.

Figure 4 Overriding OnNavigatedTo and OnNavigatedFrom to Pause Audio

protected override void OnNavigatedTo(NavigationEventArgs e)
{
  // If the MediaPlayer is already playing music,
  // pause it upon entering the app.
  PauseMediaPlayer();
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
  // If the MediaPlayer was already playing music,
  // resume playback as the user leaves the app.
  ResumeMediaPlayer();
}
private void PauseMediaPlayer()
{
  // See the MainPage Constructor earlier in the
  // article where the GameTimer object is created.
  // This enables the use of the XNA Framework MediaPlayer
  // class by pumping the XNA FrameworkDispatcher.
  // Pause the media player if it's already playing music.
  if (!MediaPlayer.GameHasControl)
  {
    MediaPlayer.Pause();
    resumeMediaPlayerAfterDone = true;
  }
}
private void ResumeMediaPlayer()
{
  // If music was playing, resume playback.
  if (resumeMediaPlayerAfterDone)
  {
    MediaPlayer.Resume();
  }
}

Be a Good Citizen

To recap, when creating media applications for the Windows Phone OS there are several things to consider beyond the low-level details of handling actual media.

Make sure you integrate with the Music + Videos Hub so your application contributes to the user experience in the ways users have come to expect from all media apps. This means populating the History and New tiles with your content and making sure your program shows up in the Apps list.

Read and understand the certification requirements surrounding media apps, so your application is more likely to pass through the Windows Phone Marketplace submission process.

By following these guidelines you ensure that users will have a head start on knowing how to interact with your app. You’ll also raise the visibility of your app and your content by making sure they surface in the proper areas in the Music + Videos Hub. And your app will be a “good citizen” on Windows Phone.


Mark Hopkins is a senior programming writer on the Windows Phone Developer Documentation Team. He has been employed at Microsoft since 1992, working on developer-focused products including developer support, Visual C++, MFC, Windows Platform SDK, Internet Explorer SDK, Tablet PC SDK, Surface SDK and Windows Phone SDK. He’s also a musician and dedicated Seattle Sounders FC fan.

Thanks to the following technical experts for reviewing this article: Andrew Byrne, Kim Cameron, Robert Lyon, Nitya Ravi,Cheryl Simmons and Matt Stroshane