Customizing your Media Player Framework on Windows Phone (XAML, C#)

来源:互联网 时间:1970-01-01


As you know here at Dailymotion we strive to deliver the best video player experience no matter what platform you are on (Windows, iOS, Android etc).

Thus, I have spent a lot of time customizing the Media Player for our Windows apps and needless to say that it has been a long journey for me because of the lack of any good tutorials and examples. Many times I used trial and error to try and figure out what worked and what did not.

That is why I have created this tutorial, we will cover how to customize the XAML template for the Media Player Framework (version 3.0.0.1). I will only focus on Windows Phone 8.1 but these examples also work for Windows 8.1 and UAP and the version 2.0.0.0 of the Media Player.

This tutorial will cover 3 different examples: How to set a theme on your Media player Framework and play with the different controls How to Add your own custom controls, title, message box, buttons, etc How to customize your own AppBarButton using its default style The final version of our player will have: A title in the Media Player that will be shown only when we click/tap on the player A custom button inside the player that users can click on A CommandBar button that can hide and show elements in the player A customized play pause button so that it doesn't have its ellipse element around it

All of the code can be found on Github here

Let's get started, I will assume that you have:

Windows OS ;) Visual Studio 2015 ( here) installed, or 2013 Media Player Framework vsixinstalled. Setting a theme on the Media Player Framework

On Codeplex you will find 4 different themes:

Classic Entertainment Generic Phone

To use any of these default themes you need to download and reference it into your project, here is an example with the Entertainment.xaml template downloaded:

<Page.Resources> <ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="Theme/Entertainment.xaml" /></ResourceDictionary.MergedDictionaries></ResourceDictionary></Page.Resources><Grid x:Name="LayoutRoot"> <playerFramework:MediaPlayer x:Name="player" Source="http://smf.blob.core.windows.net/samples/videos/wildlife.mp4" /></Grid> Using the different elements of the Media Player:

If you want to show or hide elements on the MediaPlayerelement you need to look for the properties that contain the word 'Visible' in them. For example: when the user clicks on a button he can hide or show the rewind, fastForwardand playPausebuttons:

private void HideBtn_OnClick(object sender, RoutedEventArgs e) {player.IsRewindVisible = false;player.IsFastForwardVisible = false;player.IsPlayPauseVisible = false;}private void ShowBtn_OnClick(object sender, RoutedEventArgs e) {player.IsFastForwardVisible = true;player.IsRewindVisible = true;player.IsPlayPauseVisible = true;}

Code can be found: in the MediaPlayerFramework_Theme project

Adding custom controls

First you will need to copy one of the default templates, hereyou can find the phone theme.

In this theme we have a ControlTemplatewhich contains a Gridwith a VerticalAlignment="Bottom"property:

Remove the VerticalAlignment="Bottom"property and add it to your Borderelement named 'border' that contains all of the controls for the player.

Here is the XAML:

<Style TargetType="local:MediaPlayer"> <Setter Property="InteractiveDeactivationMode" Value="All" /><Setter Property="AutoHideBehavior" Value="All" /><Setter Property="ControlPanelTemplate"><Setter.Value><ControlTemplate TargetType="local:ControlPanel"><Grid VerticalAlignment="Bottom"> <-- remove VerticalAlignment="Bottom"<VisualStateManager.VisualStateGroups><VisualStateGroup x:Name="MediaStates"> ... <Border x:Name="Border" <- add it hereBackground="{TemplateBinding Background}"DataContext="{TemplateBinding ViewModel}"><Border.Resources><local:BoolToVisibilityConverter x:Key="VisibleIfConverter" /></Border.Resources>

Now that we have moved this property we can start customizing our player.

For example:

We can add another borderelement that we will position at the top with a TextBlockin it that will hold the title of our video: <Border x:Name="TopBorder" Height="30" VerticalAlignment="Top" Background="DarkRed"> <TextBlock Text="{Binding TitleOfTheVideo}" /></Border> We could also add another Borderelement that contains a GridView, or a Buttonfor example: <Border x:Name="CustomElement" HorizontalAlignment="Center"VerticalAlignment="Center"Visibility="{Binding Path=IsCustomControlVisible, Mode=TwoWay, Converter={StaticResource BTVConverter}}"> <Button Command="{Binding CustomElementCommand}" Content="CLick Me" /></Border>

We can even play with the visibility of this Borderelement using its visibility property and only show this element when the video is finished or when the user does an action.

Here is an example on how to show the Borderwith a button when the video is finished, you need to use the MediaEndedevent which is fired when the video has finished playing:

protected override void OnNavigatedTo(NavigationEventArgs e) {player.MediaEnded += Player_MediaEnded;}private void Player_MediaEnded(object sender, Microsoft.PlayerFramework.MediaPlayerActionEventArgs e){ViewModel.IsCustomControlVisible = true;} Customizing an AppBarButton

What if you wanted to customize one of the AppBarButtonsin the player, here is what the default PlayPauseButtonlooks like:

<AppBarButton x:Name="PlayPauseButton" Width="70"Height="70"Margin="50,0,50,0"Style="{TemplateBinding TransportBarButtonStyle}"Visibility="{Binding IsPlayPauseButtonVisible, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource VisibleIfConverter}}"> <local:MediaControls.Behavior> <local:PlayPauseButtonBehavior ViewModel="{Binding ViewModel, RelativeSource={RelativeSource TemplatedParent}}" /> </local:MediaControls.Behavior></AppBarButton>

The AppBarButtonis styled using the default TransportBarButtonStylestyle.

In this next example we will be removing the Ellipseelements that are around the PlayPausebuttonand we will name this style CircleLessTransportBarButtonStyle.

First, we need to copy the style TransportBarButtonStyle, and rename it so that we can customize it. You can find the defaut TransportBarButtonStylestyle hereon codeplex, copy the TransportBarButtonStylestyle in your ResourceDictionaryfile.

Next, we need to comment both Ellipseelements that are located in the ViewBox. Also we will need to comment all of the ObjectAnimationUsingKeyFrameslocated in the VisualStatethat are targeting the Ellipseelements.

Here is the XAML modified with these changes:

<Style x:Key="CircleLessTransportBarButtonStyle" TargetType="AppBarButton"> <Setter Property="Foreground" Value="{ThemeResource AppBarItemForegroundThemeBrush}" /><Setter Property="VerticalAlignment" Value="Center" /><Setter Property="HorizontalAlignment" Value="Center" /><Setter Property="Padding" Value="0" /><Setter Property="IsCompact" Value="True" /><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="AppBarButton"><Grid x:Name="RootGrid" Background="Transparent"><VisualStateManager.VisualStateGroups><VisualStateGroup x:Name="ApplicationViewStates"><VisualState x:Name="FullSize" /><VisualState x:Name="Compact" /></VisualStateGroup><VisualStateGroup x:Name="CommonStates"><VisualState x:Name="Normal" /><VisualState x:Name="PointerOver"><Storyboard><!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundEllipse" Storyboard.TargetProperty="Fill"><DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemPointerOverBackgroundThemeBrush}" /></ObjectAnimationUsingKeyFrames>--><ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground"><DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemPointerOverForegroundThemeBrush}" /></ObjectAnimationUsingKeyFrames></Storyboard></VisualState><VisualState x:Name="Pressed"><Storyboard><!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineEllipse" Storyboard.TargetProperty="Stroke"><DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemForegroundThemeBrush}" /></ObjectAnimationUsingKeyFrames><ObjectAnimationUsingKeyFrames Storyboard.TargetName="BackgroundEllipse" Storyboard.TargetProperty="Fill"><DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemForegroundThemeBrush}" /></ObjectAnimationUsingKeyFrames>--><ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground"><DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemPressedForegroundThemeBrush}" /></ObjectAnimationUsingKeyFrames></Storyboard></VisualState><VisualState x:Name="Disabled"><Storyboard><!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="OutlineEllipse" Storyboard.TargetProperty="Stroke"><DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemDisabledForegroundThemeBrush}" /></ObjectAnimationUsingKeyFrames>--><ObjectAnimationUsingKeyFrames Storyboard.TargetName="Content" Storyboard.TargetProperty="Foreground"><DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource AppBarItemDisabledForegroundThemeBrush}" /></ObjectAnimationUsingKeyFrames></Storyboard></VisualState></VisualStateGroup><VisualStateGroup x:Name="FocusStates"><VisualState x:Name="Focused"><Storyboard><DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualWhite" Storyboard.TargetProperty="Opacity" To="1" /><DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualBlack" Storyboard.TargetProperty="Opacity" To="1" /></Storyboard></VisualState><VisualState x:Name="Unfocused" /><VisualState x:Name="PointerFocused" /></VisualStateGroup></VisualStateManager.VisualStateGroups><Viewbox Margin="{TemplateBinding Padding}"><Grid Width="40" Height="40"><!--<Ellipse x:Name="BackgroundEllipse" Fill="{ThemeResource AppBarItemBackgroundThemeBrush}" UseLayoutRounding="False"/><Ellipse x:Name="OutlineEllipse" Stroke="{ThemeResource AppBarItemForegroundThemeBrush}" StrokeThickness="2" UseLayoutRounding="False"/>--><ContentPresenter x:Name="Content" HorizontalAlignment="Center" VerticalAlignment="Center" AutomationProperties.AccessibilityView="Raw" Content="{TemplateBinding Icon}" Foreground="{TemplateBinding Foreground}" /></Grid></Viewbox><Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}" StrokeDashArray="1,1" StrokeDashOffset="1.5" StrokeEndLineCap="Square" /><Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}" StrokeDashArray="1,1" StrokeDashOffset="0.5" StrokeEndLineCap="Square" /></Grid></ControlTemplate></Setter.Value></Setter></Style>

Now we need to change the referenced style on the AppBarButton, on our example we wanted to change the play pause button so we need to reference our new style called CircleLessTransportBarButtonStylein the AppBarButtonnamed 'PlayPauseButton'.

Here is the final XAML for this AppBarButton:

<AppBarButton x:Name="PlayPauseButton" Width="70"Height="70"Margin="50,0,50,0"Style="{StaticResource CircleLessTransportBarButtonStyle}"Visibility="{Binding IsPlayPauseButtonVisible, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource VisibleIfConverter}}"> <local:MediaControls.Behavior> <local:PlayPauseButtonBehavior ViewModel="{Binding ViewModel, RelativeSource={RelativeSource TemplatedParent}}" /> </local:MediaControls.Behavior></AppBarButton>

Code can be found: in the MediaPlayerFramework_Custom project

Once you run your code you will see that the play pause button doesn't have the ellipse around it.

This concludes this tutorial, if you have arrived here then you have read everything! Thank you for reading and good luck in your customization of your Media Player!

All of the code can be found on Github here



相关阅读:
Top