Using and Customizing Player Framework in Windows 8 Xaml Apps

If you are creating media apps targeting Xaml frameworks i.e. apps which playback media especially videos, you start with MediaElement control. As you start using it, you’d probably search for properties to enable playback controls (play, pause, seek bar et al) to learn that there are none. That’s right, MediaElement just plays video in a rectangle for an assigned source and you are supposed to build everything else yourself.

Using MediaPlayer from Player Framework

Depending on your requirements, building a video player can be difficult and time consuming. But before you start building one yourself, you should look at Player Framework on codeplex, a set of great player controls for Windows 8, HTML5, Silverlight and Windows Phone. The project is managed by Microsoft and being continuously improved upon. The player controls in this framework have rich set of features and you probably won’t have to build one yourself. To get started, check out the documentation and samples on codeplex to learn more about all the features it supports including IIS smooth streaming, closed captioning, ads and more.

MediaPlayer control in the player framework comes with inbuilt playback controls which are good to start with. Refer the getting started documentation for using player framework in your app. Here is the experience provided by the default controls.

DefaultPlayerControls

Using Windows 8 Style Playback Controls

For Windows 8 apps, you’d want to use playback controls with a modern Windows 8 user experience with full screen overlay controls similar to the the default Video app or Khan Academy app. The MediaPlayer control ships with an entertainment theme for getting better playback controls. To enable entertainment theme, all we need to do is add entertainment theme to our page where we are using MediaPlayer control using Xaml markup as shown below. Checkout the documentation on Applying Theme for more customization options.

<Page.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ms-appx:///Microsoft.PlayerFramework/themes/EntertainmentTheme.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Page.Resources>

With the entertainment theme, you get solid UI improvement over default playback controls.
EntertainmentThemeControls

Customizing Template of Playback Controls

Now that we have good understanding of using MediaPlayer control and it’s out of the box entertainment theme, let’s look at the options to customize the playback control UI. The MediaPlayer control is designed using MVVM pattern which means that the views are completely separate from the behavior and the views are template driven. This makes the control extremely flexible for customizations as you can define a completely new template for playback controls and replace the default template. In fact, that’s what we did above by replacing the default template with the one in entertainment theme. Let’s customize the entertainment theme playback controls further and use them in our app. To start, we’ll make a copy of the entertainment theme in our app and customize the template. As an example here, we will use dark red color for the slider pushpin rather than the default color.

  • First, locate the EntertainmentTheme.xaml which is installed with player framework and also gets copied to your app’s output directory during compilation at <approot>\bin\Debug\AppX\Microsoft.PlayerFramework\Themes folder. You can also get it from installation folder located at <drive>:\Program Files (x86)\Microsoft SDKs\Windows\v8.0\ExtensionSDKs\Microsoft.PlayerFramework.Xaml\<version>\ Redist\CommonConfiguration\neutral\Microsoft.PlayerFramework\Themes.
  • Once you have located the file, add it you project in visual studio. If you don’t know how, use either of these options
    • from Visual Studio, use “Add Existing Item” item from context menu in solution explorer, or
    • copy the file to you app folder in file explorer, enable “Show All Files” from the toolbar in solution explorer and use “Include In Project” item from context menu for the file you need to add.
  • Update the Xaml markup of the player page shown above to use the EntertainmentTheme.xaml from project instead of player framework dll.
    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Common/EntertainmentTheme.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>
    
  • At this point, the control panel UI is rendered using template defined in this file in the project. You can make any changes here to customize the control panel and the changes would reflect in UI. Let’s change the color of the pushpin for our example.
    <Grid>
        <Ellipse Stroke="{StaticResource ButtonForegroundThemeBrush}" Fill="DarkRed" StrokeThickness="2" Width="35" Height="35"/>
        <Path Fill="{StaticResource ButtonForegroundThemeBrush}" Margin="0,0,0,-7" VerticalAlignment="Bottom" HorizontalAlignment="Center" Data="M 0,0 8,0 4,8Z"/>
    </Grid>
    

We changed the Fill value for the Ellipse to dark red in this example. This demonstrates how to make changes in the template.

Let’s take customization to the next level. The behavior and visibility of playback controls are driven by a ViewModel. In the entertainment theme template we changed above, you must have noticed that bindings are used to control visibility. The control panel uses InteractiveViewModel class in player framework which has a number of properties to control visibility of all the elements in playback controls. I highly recommend going through the type definition for InteractiveViewModel to understand the available properties to use in your custom template. Refer API documentation.

If you have full screen video player in your app, you might want to add a Back button to the player screen. This can be added separately to you page but we can take advantage of MediaPlayer’s extensibility. Using this approach, we can also control the visibility of Back button as per playback controls visibility on user interactions. To achieve this, we’ll have to add the Back button to the ControlPanel template in ExtertainmentTheme.xaml we added to the project above.

Another essential requirement might be to show video title for the currently playing video. Again, we can achieve this by putting a TextBlock on the page but then we will have to handle the visibility of the TextBlock ourselves. Instead of doing that, we’ll take advantage of MediaPlayer’s extensibility and add the TextBlock to the template. This has an issue though as we don’t have a property in InteractiveViewModel which can be bound to the Text property of the TextBlock. We definitely don’t want to hard code this. To resolve this, we will create a subclass of InteractiveViewModel and add the additional property in that. In the new ViewModel, we’ll also add a command for binding it to Back button. Once we have the ViewModel, all we’ll have to do is to wire up the custom ViewModel to the MediaPlayer control.

First, let’s go back to the ControlPanel template and add the title TextBlock and Back button to the playback controls template.

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>

    <Grid x:Name="HeaderContainer" Background="{StaticResource ItemBackgroundThemeBrush}" Visibility="{Binding IsTimelineVisible, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource VisibleIfConverter}}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Button Command="{Binding GoBackCommand}" Style="{StaticResource BackButtonStyle}" Margin="36,20" VerticalAlignment="Center" />
        <TextBlock Grid.Column="1" TextWrapping="NoWrap" Text="{Binding VideoTitle}" Style="{StaticResource SubheaderTextStyle}"
            Foreground="{StaticResource ApplicationForegroundThemeBrush}" VerticalAlignment="Center" FontSize="40"/>
    </Grid>

    <StackPanel Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">

Notice we are using bindings to set the Text for TextBlock and Command for Button. Next, let’s create the custom ViewModel with properties we can use for binding.

public class CustomInteractiveViewModel : InteractiveViewModel
{
    public CustomInteractiveViewModel(Action goBack, MediaPlayer player)
        : base(player)
    {
        _goBackCommand = new DelegateCommand(goBack);
    }

    private string _videoTitle;
    public string VideoTitle
    {
        get
        {
            return _videoTitle;
        }
        set
        {
            if (_videoTitle != value)
            {
                _videoTitle = value;
                base.OnPropertyChanged("VideoTitle");
            }
        }
    }

    DelegateCommand _goBackCommand;
    public DelegateCommand GoBackCommand
    {
        get
        {
            return _goBackCommand;
        }
    }
}

In the player page, let’s add the MediaPlayer control to the Xaml markup and assign an instance of the CustomInteractiveViewModel to InteractiveViewModel property of the MediaPlayer control to wire up the custom ViewModel to the MediaPlayer.

<Page x:Class="CustomizingPlayerDemo.PlayerPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:CustomizingPlayerDemo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:mmppf="using:Microsoft.PlayerFramework" mc:Ignorable="d">

    <Page.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Common/EntertainmentTheme.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Page.Resources>
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <mmppf:MediaPlayer x:Name="player" Source="http://download.ted.com/talks/BillGates_2010-480p.mp4?apikey=TEDDOWNLOAD"/>
    </Grid>
</Page>

 

using CustomizingPlayerDemo.Common;
using Windows.UI.Xaml.Controls;

namespace CustomizingPlayerDemo
{
    public sealed partial class PlayerPage : Page
    {
        public PlayerPage()
        {
            this.InitializeComponent();

            player.InteractiveViewModel = new CustomInteractiveViewModel(() => this.Frame.GoBack(), player)
            {
                VideoTitle = "Bill Gates on energy: Innovating to zero!"
            };
        }
    }
}

This gives us a fully customized playback controls UI for player framework MediaPlayer control. This is the same approach I have used in Khan Academy app as well.

CustomizedPlayerControls

The controls we have added to the ControlPanel template are part of the player so we get visibility transitions for these without any extra work. You can download the source code of this sample to see how it works. Please don’t forget to install the player framework using links above before you try to run the sample.

Update:

Hope this helps.

Advertisements

4 thoughts on “Using and Customizing Player Framework in Windows 8 Xaml Apps

  1. This is great Anand! Why do you need to pass a delegate for the back into the ViewModel? I am afraid if you look at the generated code you will probably see the Frame is getting lifted every time.

    • The Action is used for the Command which gets bound to the back button. The back button which needs to trigger back navigation is inside the template of player control panel and the code which needs to execute is on the page which hosts the player control. The code needs to execute in the page as that’s where we can access the Frame.

      Sorry, I’m not following the part about generated code and Frame getting lifted every time. The player frame get’s lifted in the approach I described in another blog post about using frames. Are you mixing the two?

  2. Anand, thanks for tutorial. I would like to do something similar for adding a video quality selector to the player framework. I’ve made it as far as adding a button and receiving the click action when the button is clicked on, but how can I access properties for the controls I’ve added in the view model? I need to make a popup visible when the video quality button is clicked on.

    • You shouldn’t have to access the properties of the control. Create a command in the viewmodel (CustomInteractiveViewModel in my example above) and bind that to your button. In that command, you can show a popup.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s