Share via


Frame of reference: keeping the music playing across pages

A musical score is a great way to add zip to your app, but many people are stumped because the Xaml MediaElement will play music only when it’s in the visual tree. When the user navigates to a new page the music stops.

This brings up the frequent question: How can I keep the music playing when I navigate away from the page with my MediaElement?

The straight (but kind of useless) answer is: You can’t.

The real answer is: You can’t, but you don’t have to.

Like I learned in Physic class: a problem can go from nigh-impossible to trivial by choosing the right frame of reference.

In this case, we have two things we want:

1) We have a MediaElement that we want to keep available throughout the life of the app

2) We have the meat of the app that we want to be able to page through

We can’t put the MediaElement on the page with the app and then switch to a new page, but we can turn the problem around and put the Frame with the page contents inside a page with the MediaElement:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    < MediaElement x:Name="soundTrack" Visibility="Collapsed" AudioCategory="ForegroundOnlyMedia" IsLooping="True" Source="Assets/soundtrack.mp3" />
    <Frame x:Name="mainFrame" />
< /Grid>

We can then code the visible pages of the app into separate Page objects, host them in our rootFrame, and initialize the MainPage to automatically navigate to the first sub-page:

protected override async void OnNavigatedTo(NavigationEventArgs e)
  {
     mainFrame.Navigate(typeof(BasicPage1));

     base.OnNavigatedTo(e);
  }

And the pages can navigate between each other the same way they would normally, but now this.Frame will refer to the rootFrame hosted in the MainPage rather than to the one created App.xaml.cs which hosts the MainPage.

This is the same technique used in the How to share an app bar across pages documentation, and it can be used for consistent visible UI as well.

The attached sample has a full demonstration. For the Windows Store 8.1 version it allows choosing your own audio file from the app bar. For the Windows Phone 8.1 version you’ll need to add your own “soundtrack.mp3” file to the Assets folder (the emulator doesn’t have sound files to choose). Your real app will probably follow the Phone sample’s model and include your own properly-licensed sound file.

Also see Navigating between pages and Playing and previewing audio and video

--Rob

Follow us on Twitter @wsdevsol!

MusicOnEveryPage.zip

Comments

  • Anonymous
    September 15, 2014
    Hello Rob, I tried your solution for this problem and it is working fine, but I have another issue, my MainPage must have play/pause button and this button cannot play/pause the media element as it is in other page How to make the play/pause button plays/pauses the music ??

  • Anonymous
    September 16, 2014
    You can communicate between your frame page and your content pages in several ways. Here are two that should be fairly easy to implement.

  1. Treat the frame as a singleton and expose a static "Current" method which returns the frame page. The page can provide a property to share its MediaElement or it can provide methods to play/pause, etc. the MediaElement.
  2. Bind the play/pause state to a data object which can be manipulated by the content pages. This will allow abstracting the behaviour a bit more thoroughly. --Rob
  • Anonymous
    October 23, 2014
    I think I'm nearly there now with my issue, iv added a frame inside the BasicPage1, but I'm still getting stumped on the part after where you have shown the code in CS. I don't suppose you would know what it is in VB, and also where to add it? Thanks

  • Anonymous
    October 25, 2014
    Samuel try converter.telerik.com,