Windows 10 1607, UWP and Background Media

It’s been a while since I looked at background audio/video in a UWP app – perhaps long enough ago that I was still talking about Windows 8 and I was working in HTML/JS at the time I wrote this post;

Windows 8 Metro style simple music app example

and made the screencast videos that went along with it.

Here in 2016 on the UWP with build 1607 it’s a joy to find that the various changes around the background model described here;

Background activity with the Single Process Model

have found their way into the world of background media as described on MSDN over here;

Play Media in the Background

and I wanted to try out the very basics of this for myself armed with some of what I’d referenced in this post;

Windows 10 1607, UWP, Single Process Execution and Lifecycle Changes

and so I made a simple, blank app and I added a video into the Assets folder;

image

and then got rid of the MainPage.xaml/.cs files and concentrated purely on my App class which I tried to keep as simple as I could. I’m not sure that I have it entirely right just yet but I wound up with;

namespace VideoPlayerBackground
{
  using System;
  using Windows.ApplicationModel;
  using Windows.ApplicationModel.Activation;
  using Windows.Media;
  using Windows.Media.Core;
  using Windows.Media.Playback;
  using Windows.UI.Xaml;
  using Windows.UI.Xaml.Controls;

  sealed partial class App : Application
  {
    public App()
    {
      this.InitializeComponent();
      this.EnteredBackground += OnEnteredBackground;
      this.LeavingBackground += OnLeavingBackground;
    }
    void OnLeavingBackground(object sender, LeavingBackgroundEventArgs e)
    {
      this.CreateUI();
      this.isForeground = true;
    }
    void OnEnteredBackground(object sender, EnteredBackgroundEventArgs e)
    {
      this.DestroyUI();
      this.isForeground = false;
    }
    protected override void OnLaunched(LaunchActivatedEventArgs e)
    {
      if ((e.PreviousExecutionState != ApplicationExecutionState.Running) &&
          (e.PreviousExecutionState != ApplicationExecutionState.Suspended))
      {
        this.CreateMediaPlayer();
        this.CreateUI();
        this.mediaPlayer.Play();
        Window.Current.Activate();
      }
    }
    void CreateMediaPlayer()
    {
      this.mediaPlayer = new MediaPlayer()
      {
        Source = MediaSource.CreateFromUri(new Uri("ms-appx:///Assets/video.mp4"))        
      };
      this.mediaPlayer.SystemMediaTransportControls.IsEnabled = true;
      this.mediaPlayer.SystemMediaTransportControls.AutoRepeatMode = MediaPlaybackAutoRepeatMode.Track;
    }
    void CreateUI()
    {
      this.mediaPlayerElement = new MediaPlayerElement();
      this.mediaPlayerElement.AreTransportControlsEnabled = true;
      this.mediaPlayerElement.SetMediaPlayer(this.mediaPlayer);
      Window.Current.Content = this.mediaPlayerElement;
    }
    void DestroyUI()
    {
      this.mediaPlayerElement.SetMediaPlayer(null);
      this.mediaPlayerElement = null;
      Window.Current.Content = null;
    }
    MediaPlayerElement mediaPlayerElement;
    MediaPlayer mediaPlayer;
    bool isForeground;
  }
}

and what surprised me is the simplicity of it – I have a MediaPlayer which I set playing (in this example) from the start and then when the app is in the foreground I associate the MediaPlayer with a MediaPlayerElement (not a MediaElement) which I’ve simply parented in the window and when the app moves into the background I clear the contents of the window and get rid of the MediaPlayerElement but I keep the MediaPlayer around.

It’s worth saying that this work with the system transport controls so that I can hit the pause/play buttons on my keyboard as expected.

It seems so much nicer from what I had to do back in the days of early iterations of the platform that I’m wondering whether I’m missing some additional pieces that make it more complex than I’ve got it here? Answers on a postcard please! Smile