Pro-Tip: Including Background Music For Your Windows Phone App

26 February 2012

Alright! So I've finally cracked how to set up background music playing consistently in the background for a Windows Phone app. Here's a step by step lowdown:

1) Play background music with MediaElement. So we're going to hold a MediaElement object at the Application Level, so our music keeps playing while you transition between pages. Note the MediaEnded event, which we'll come to later.

In your App.xaml:

<Application.Resources>
    <MediaElement x:Key="GlobalMedia" MediaEnded="MediaElement_MediaEnded" AutoPlay="False" />
</Application.Resources>

2) Include mp3 in your project with Build Action = Content.

3) Check if we should play background music when the initial page of our application is hit. There are some Application Certification Guidelines around the use of background music in apps, namely 6.5.1, which basically states that you need to ask the user whether they want to replace their currently playing audio with your app's background music.

To check whether the user is playing background music, we can look at the MediaPlayer.GameHasControl property - you'll need to include the XNA libraries and the appropriate using statements. If MediaPlayer.GameHasControl is not true, then something outside of our app is using the Media Player (so there is background music going).

4) Set the source for the MediaElement, and play the media once it's ready.

So in the constructor for MainPage.xaml.cs, I have:

    public MainPage()
    {
        InitializeComponent();
        (Application.Current as App).TryPlayBackgroundMusic();
    }

and in App.xaml.cs:

    public static MediaElement GlobalMediaElement
    {
        get { return Current.Resources["GlobalMedia"] as MediaElement; }
    }

    public static bool BackgroundMusicAllowed()
    {
        bool allowed = true;

        //you can check a stored property here and return false if you want to disable all bgm

        if(!MediaPlayer.GameHasControl)
        {
            //ask user about background music
            MessageBoxResult mbr = MessageBox.Show("press ok if you'd like to use this app's background music (this will stop your current music playback)", "use app background music?", MessageBoxButton.OKCancel);
            if (mbr != MessageBoxResult.OK)
            {
                allowed = false;
            }
        }

        return allowed;
    }

    public void TryPlayBackgroundMusic()
    {
        if (BackgroundMusicAllowed())
        {
            MediaPlayer.Stop();  //stop to clear any existing bg music

            GlobalMediaElement.Source = new Uri("Audio/background.mp3", UriKind.Relative);
            GlobalMediaElement.MediaOpened += MediaElement_MediaOpened;  //wait until Media is ready before calling .Play()
        }
    }

    private void MediaElement_MediaOpened(object sender, RoutedEventArgs e)
    {
        App.GlobalMediaElement.Play();        
    }

5) If our Application is activated (so resumed from FAS / tombstone) - check if user background music is currently playing - if so, we leave that playing (because they would have left our app, started playing some music, and returned, so it's not likely they will want to stop their music). Otherwise, we try and play our background music.

Here's the code that goes in App.xaml.cs:

    private void Application_Activated(object sender, ActivatedEventArgs e)
    {         
        //to prevent multiple prompts...            
        if (MediaPlayer.GameHasControl)
        {
            TryPlayBackgroundMusic();
        }
    }

6) Loop the background music - we do this by catching the MediaEnded event on the MediaElement, and requesting it to play again.

    private void MediaElement_MediaEnded(object sender, RoutedEventArgs e)
    {  
        if (GlobalMediaElement.CurrentState != System.Windows.Media.MediaElementState.Playing)
        {
            //loop bg music
             GlobalMediaElement.Play();
        }
    }

Note that my solution doesn't handle resuming background music from the duration / seek position in which the app was suspended / tombstoned - I didn't think it was worth the effort, and figured it wouldn't be a dealbreaker if the music started back from the beginning of the 2 minute loop.

Hope this saves everyone a lot of time and effort!

Thanks to all the following posts for the help - worth a read if you've got the time:

Tags: background music, XNA, Windows Phone

Add a Comment

No Comments