Windows 8 Metro Style Apps Background Audio with XAML/C#

23 May 2012

Creating a background audio capable app in Windows 8 is very easy once you have the steps.

There’s a great blog post that provides working code that gets you most of the way there.

Do remember to wrap the calls within the MediaControl handlers to marshall them back to UI thread to avoid cross-thread exceptions though as follows:

void MediaControl_PausePressed(object sender, object e)
{
    Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        CurrentTrack.Pause(); // call pause on the media element
    });
}

However, you will run into a problem if you declare your media element directly on the xaml page, which is that any navigation from the page will cause the audio to stop, not exactly what we’re after.

There is a forum post which details this problem in more detail, and we’ve drawn from one of the recommended solutions broken out here in more detail for reference.

The solution is to ensure you apply a style to your application’s root frame in App.xaml.cs as follows:

Frame frame = new Frame();
frame.Style = Resources["RootFrameStyle"] as Style;

Then you can have a xaml style which declares your media element on every page of your app:

 
<Style x:Key="RootFrameStyle" TargetType="Frame">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="Frame">
                <Grid>
                    <MediaElement x:Name="CurrentTrack" AudioCategory="BackgroundCapableMedia" AutoPlay="True"  />
                    <ContentPresenter />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Lastly on your player page you can get access to the MediaElement using the VisualTreeHelper as follows:

private MediaElement CurrentTrack 
{
    get
    {
        if (_currentTrack == null)
        {
            DependencyObject rootGrid = VisualTreeHelper.GetChild(Window.Current.Content, 0);
            _currentTrack = (MediaElement)VisualTreeHelper.GetChild(rootGrid, 0);
            _currentTrack.Source = new Uri("yourmusictrack.mp3", UriKind.Absolute);
            _currentTrack.CurrentStateChanged += CurrentTrack_CurrentStateChanged;
        }
        return _currentTrack;
    }
}

Hey presto, full background audio within and outside of your app.

Want to get started?

We would love to help with your next app or game, please do get in touch.