Windows Phone 8.1 自定义媒体播放器

Windows Phone 8.1 Custom Media Player

美好的一天,

我正在创建一个需要媒体播放器的应用程序。我尝试使用 AreTransportControlsEnabled,但它有点滞后,这是我不想要的。在我的 windows phone 上,我有一个应用程序 "Files"<-(Windows Phone 8.1 中的一个应用程序)我用它来播放我的一个视频,我看到了它的视频播放器。我在想我能不能做到这样的Player。任何关于如何实现此播放器的建议?

图片:http://s22.postimg.org/plu0oqxv5/wp_ss_20150329_0002.png

我尝试制作自定义控件,但在全屏模式下控件不显示。是否有 api 或其他方法可以做到这一点?


已回答问题

我的自定义媒体播放器

主要Page.xalm

<Page
x:Class="MediaPlayer.MainPage"
IsTabStop="false"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MediaPlayer"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" 
Loaded="MainPage_Loaded">

<Page.Resources>
    <Style x:Name="transportStyle"  TargetType="Button">
        <Setter Property="Height" Value="40" />
        <Setter Property="Width" Value="75" />
        <Setter Property="FontSize" Value="11" />
    </Style>
    <Thickness x:Key="PhoneBorderThickness">2.5</Thickness>
    <FontFamily x:Key="PhoneFontFamilyNormal">Segoe WP</FontFamily>
    <FontWeight x:Key="PhoneButtonFontWeight">Semibold</FontWeight>
    <x:Double x:Key="TextStyleLargeFontSize">18.14</x:Double>

    <x:Double x:Key="PhoneButtonMinHeight">0</x:Double>
    <x:Double x:Key="PhoneButtonMinWidth">0</x:Double>
    <Thickness x:Key="PhoneTouchTargetOverhang">0,0</Thickness>

    <SolidColorBrush x:Key="ButtonDisabledBackgroundThemeBrush" Color="Transparent"/>
    <Style x:Key="RoundButtonStyle" TargetType="Button">
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="BorderBrush" Value="{ThemeResource PhoneForegroundBrush}"/>
        <Setter Property="Foreground" Value="{ThemeResource PhoneForegroundBrush}"/>
        <Setter Property="BorderThickness" Value="{ThemeResource PhoneBorderThickness}"/>
        <Setter Property="FontFamily" Value="{ThemeResource PhoneFontFamilyNormal}"/>
        <Setter Property="FontWeight" Value="{ThemeResource PhoneButtonFontWeight}"/>
        <Setter Property="FontSize" Value="{ThemeResource TextStyleLargeFontSize}"/>
        <Setter Property="Padding" Value="9.5,0"/>
        <Setter Property="MinHeight" Value="{ThemeResource PhoneButtonMinHeight}"/>
        <Setter Property="MinWidth" Value="{ThemeResource PhoneButtonMinWidth}"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Center"/>
        <Setter Property="ContentTemplate">
            <Setter.Value>
                <DataTemplate>
                    <Path Stretch="Uniform"
              RenderTransformOrigin="0.5,0.5"
              Margin="2,6,2,2"
              Fill="{Binding Path=Foreground, RelativeSource={RelativeSource Mode=TemplatedParent}}"
              Data="{Binding Path=Content, RelativeSource={RelativeSource Mode=TemplatedParent}}"></Path>
                </DataTemplate>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="Button">
                    <Grid x:Name="Grid" Background="Transparent">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="CommonStates">
                                <VisualStateGroup.Transitions>
                                    <VisualTransition From="Pressed" To="PointerOver">
                                        <Storyboard>
                                            <PointerUpThemeAnimation Storyboard.TargetName="Grid"/>
                                        </Storyboard>
                                    </VisualTransition>
                                    <VisualTransition From="PointerOver" To="Normal">
                                        <Storyboard>
                                            <PointerUpThemeAnimation Storyboard.TargetName="Grid"/>
                                        </Storyboard>
                                    </VisualTransition>
                                    <VisualTransition From="Pressed" To="Normal">
                                        <Storyboard>
                                            <PointerUpThemeAnimation Storyboard.TargetName="Grid"/>
                                        </Storyboard>
                                    </VisualTransition>
                                </VisualStateGroup.Transitions>
                                <VisualState x:Name="Normal"/>
                                <VisualState x:Name="PointerOver"/>
                                <VisualState x:Name="Pressed">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedForegroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonPressedBackgroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledForegroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush" Storyboard.TargetName="Border">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledBorderThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
                                            <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource ButtonDisabledBackgroundThemeBrush}"/>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Margin="{ThemeResource PhoneTouchTargetOverhang}" Height="{Binding Path=Height, RelativeSource={RelativeSource Mode=TemplatedParent}}" Width="{Binding Path=Width, RelativeSource={RelativeSource Mode=TemplatedParent}}" CornerRadius="72">
                            <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Page.Resources>

<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
    <Grid.RowDefinitions>
        <RowDefinition Height="*"/>
        <!--<RowDefinition Height="150"/>-->
    </Grid.RowDefinitions>

    <ContentControl x:Name="videoContainer" 
                        KeyUp="VideoContainer_KeyUp" 
                        HorizontalContentAlignment="Stretch" 
                        VerticalContentAlignment="Stretch"
                        Grid.Row="0" >
        <MediaElement Name="videoMediaElement"
                          Source="Media/video1.mp4" 
                          MediaOpened="videoElement_MediaOpened" 
                          MediaEnded="videoMediaElement_MediaEnded" 
                          MediaFailed="videoMediaElement_MediaFailed"
                          CurrentStateChanged="videoMediaElement_CurrentStateChanged"
                          PosterSource="Media/Video1_Poster.png" PointerPressed="videoMediaElement_PointerPressed" />
    </ContentControl>
    <!-- Transport Controls -->
    <StackPanel Name="TransportControlsPanel" 
                Grid.Row="0" VerticalAlignment="Bottom" Background="#CC000000" >
        <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,15,0,0">
            <Button HorizontalAlignment="Left" Click="btnReverse_Click"  VerticalAlignment="Top" Style="{StaticResource RoundButtonStyle}" Height="72" Width="72" Content="M13.862404,0L17.667,3.8059161 10.879305,10.593651 17.6241,17.568752 13.861103,21.333 3.1840002,10.678149z M0,0L3.0719999,0 3.0719999,21.032 0,21.032z" Padding="20,5" Margin="20,0" BorderBrush="White" Background="#FFE6E6E6"/>
            <Button x:Name="Play1" HorizontalAlignment="Left" Click="btnPlay_Click"     VerticalAlignment="Top" Style="{StaticResource RoundButtonStyle}" Height="72" Width="72" Content="M27.270001,0L44.310001,0 44.310001,48.643002 27.270001,48.643002z M0,0L17.040001,0 17.040001,48.643002 0,48.643002z" Padding="20,10" Margin="20,0" BorderBrush="White" Background="#FFE6E6E6"/>
            <Button HorizontalAlignment="Left" Click="btnForward_Click"  VerticalAlignment="Top" Style="{StaticResource RoundButtonStyle}" Height="72" Width="72" Content="M14.595,0L17.668,0 17.668,21.032 14.595,21.032z M3.8059254,0L14.484001,10.67815 3.8059254,21.333 0.04431057,17.568752 6.7875929,10.593651 0,3.8059165z" Padding="20,5" Margin="20,0" BorderBrush="White" Background="#FFE6E6E6"/>
            <Button HorizontalAlignment="Left" Click="btnFullScreenToggle_Click"  VerticalAlignment="Top" Style="{StaticResource RoundButtonStyle}" Height="72" Width="72" Content="M0,2.3629998L11.63953,2.3629998 9.1447105,4.8564929 2.4934592,4.8564929 2.4934592,14.710437 12.712251,14.710437 12.712251,8.4683789 15.206,5.9748863 15.206,17.204 0,17.204z M11.741774,0L17.591398,0 17.591999,5.8514608 15.648591,3.9075235 7.7964079,11.759001 5.8289994,9.7914637 13.681183,1.9400271z" Padding="13,10,10,15" Margin="20,0" BorderBrush="White" Background="#FFE6E6E6"/>

        </StackPanel>
        <Slider Name="timelineSlider" HorizontalContentAlignment="Stretch" Margin="10,20,10,0"/>
        <TextBlock x:Name="TextBlock1" Text="00:0 / 00:0" FontSize="18" Margin="20,0,20,40" Foreground="White"/>
    </StackPanel>
</Grid>

MainPage.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.  The Parameter
    /// property is typically used to configure the page.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }

    // You should use the MediaElement.IsFullWindow property instead
    // to enable and disable full window rendering.
    private bool _isFullscreenToggle = false;
    public bool IsFullscreen
    {
        get { return _isFullscreenToggle; }
        set { _isFullscreenToggle = value; }
    }

    private Size _previousVideoContainerSize = new Size();

    private async void FullscreenToggle()
    {
        this.IsFullscreen = !this.IsFullscreen;

        if (this.IsFullscreen)
        {
            //TransportControlsPanel.Visibility = Visibility.Collapsed;
            await Windows.UI.ViewManagement.StatusBar.GetForCurrentView().HideAsync(); 
            DisplayInformation.AutoRotationPreferences = DisplayOrientations.Landscape | DisplayOrientations.LandscapeFlipped;
            _previousVideoContainerSize.Width = videoContainer.ActualWidth;
            _previousVideoContainerSize.Height = videoContainer.ActualHeight;

            videoContainer.Width = Window.Current.Bounds.Width;
            videoContainer.Height = Window.Current.Bounds.Height;
            videoMediaElement.Width = Window.Current.Bounds.Width;
            videoMediaElement.Height = Window.Current.Bounds.Height;
            // Trigger the Visual State Manager
            //VisualStateManager.GoToState(this, "Landscape", false);
        }
        else
        {
            //TransportControlsPanel.Visibility = Visibility.Visible;

            await Windows.UI.ViewManagement.StatusBar.GetForCurrentView().ShowAsync(); 
            DisplayInformation.AutoRotationPreferences = DisplayOrientations.None;
            videoContainer.Width = _previousVideoContainerSize.Width;
            videoContainer.Height = _previousVideoContainerSize.Height;
            videoMediaElement.Width = _previousVideoContainerSize.Width;
            videoMediaElement.Height = _previousVideoContainerSize.Height;
            // Trigger the Visual State Manager
            //VisualStateManager.GoToState(this, "Portrait",false);
        }
    }

    private void btnFullScreenToggle_Click(object sender, RoutedEventArgs e)
    {
        FullscreenToggle();
    }

    private void VideoContainer_KeyUp(object sender, KeyRoutedEventArgs e)
    {
        if (IsFullscreen && e.Key == Windows.System.VirtualKey.Escape)
        {
            FullscreenToggle();
        }

        e.Handled = true;
    }

    private void btnPlay_Click(object sender, RoutedEventArgs e)
    {
        if (videoMediaElement.DefaultPlaybackRate != 1)
        {
            videoMediaElement.DefaultPlaybackRate = 1.0;
        }
        if (videoMediaElement.CurrentState == MediaElementState.Playing)
        {
            videoMediaElement.Pause();
            Play1.Content = "M0,0L384.885,191.965 769.768,383.928 384.885,576.035 0,768 0,383.928z"; // Play
            Play1.Padding = new Thickness(19, 5, 12, 5);
        }
        else if (videoMediaElement.CurrentState == MediaElementState.Paused)
        {
            videoMediaElement.Play();
            Play1.Content = "M27.270001,0L44.310001,0 44.310001,48.643002 27.270001,48.643002z M0,0L17.040001,0 17.040001,48.643002 0,48.643002z";
            Play1.Padding = new Thickness(20, 10, 20, 10);
        }
    }

    DispatcherTimer timer = new DispatcherTimer();
    public void Start_timer()
    {
        timer.Tick += timer_Tick;
        timer.Interval = new TimeSpan(00, 0, 5);
        bool enabled = timer.IsEnabled;
        timer.Start();
    }

    void timer_Tick(object sender, object e)
    {
        //function to execute
        if (TransportControlsPanel.Visibility == Windows.UI.Xaml.Visibility.Visible)
        {
            TransportControlsPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        }
        timer.Stop();
    }

    private void btnPause_Click(object sender, RoutedEventArgs e)
    {
        videoMediaElement.Pause();
    }

    private void btnStop_Click(object sender, RoutedEventArgs e)
    {
        videoMediaElement.Stop();
    }

    private void btnForward_Click(object sender, RoutedEventArgs e)
    {
        videoMediaElement.DefaultPlaybackRate = 2.0;
        videoMediaElement.Play();
    }

    private void btnReverse_Click(object sender, RoutedEventArgs e)
    {
        double Int1 = videoMediaElement.Position.TotalSeconds - 10;
        if (Int1 > 0)
        {
            videoMediaElement.Position = TimeSpan.FromSeconds(videoMediaElement.Position.TotalSeconds - 10);
            videoMediaElement.Play();
        }
        else
        {
            videoMediaElement.Position = TimeSpan.FromSeconds(0);
            videoMediaElement.Play();
        }
    }

    private void btnVolumeDown_Click(object sender, RoutedEventArgs e)
    {
        if (videoMediaElement.IsMuted)
        {
            videoMediaElement.IsMuted = false;
        }

        if (videoMediaElement.Volume < 1)
        {
            videoMediaElement.Volume += .1;
        }
    }

    private void btnMute_Click(object sender, RoutedEventArgs e)
    {
        videoMediaElement.IsMuted = !videoMediaElement.IsMuted;
    }

    private void btnVolumeUp_Click(object sender, RoutedEventArgs e)
    {
        if (videoMediaElement.IsMuted)
        {
            videoMediaElement.IsMuted = false;
        }

        if (videoMediaElement.Volume > 0)
        {
            videoMediaElement.Volume -= .1;
        }
    }

    private void cbAudioTracks_SelectionChanged(
        object sender, SelectionChangedEventArgs e)
    {
        //videoMediaElement.AudioStreamIndex = cbAudioTracks.SelectedIndex;
    }

    private void PopulateAudioTracks(
        MediaElement media, ComboBox audioSelection)
    {
        if (media.AudioStreamCount > 0)
        {
            for (int index = 0; index < media.AudioStreamCount; index++)
            {
                ComboBoxItem track = new ComboBoxItem();
                track.Content = media.GetAudioStreamLanguage(index);
                audioSelection.Items.Add(track);
            }
        }
    }

    private async void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        timelineSlider.ValueChanged += timelineSlider_ValueChanged;

        PointerEventHandler pointerpressedhandler = new PointerEventHandler(slider_PointerEntered);
        timelineSlider.AddHandler(Control.PointerPressedEvent, pointerpressedhandler, true);

        PointerEventHandler pointerreleasedhandler = new PointerEventHandler(slider_PointerCaptureLost);
        timelineSlider.AddHandler(Control.PointerCaptureLostEvent, pointerreleasedhandler, true);
    }

    void videoElement_MediaOpened(object sender, RoutedEventArgs e)
    {
        double absvalue = (int)Math.Round(
            videoMediaElement.NaturalDuration.TimeSpan.TotalSeconds,
            MidpointRounding.AwayFromZero);

        timelineSlider.Maximum = absvalue;

        timelineSlider.StepFrequency =
            SliderFrequency(videoMediaElement.NaturalDuration.TimeSpan);

        SetupTimer();

        // Helper method to populate the combobox with audio tracks.
        //PopulateAudioTracks(videoMediaElement, cbAudioTracks);
    }

    private bool _sliderpressed = false;

    void slider_PointerEntered(object sender, PointerRoutedEventArgs e)
    {
        _sliderpressed = true;
    }

    void slider_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
    {
        videoMediaElement.Position = TimeSpan.FromSeconds(timelineSlider.Value);
        _sliderpressed = false;
    }

    void timelineSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
    {
        if (!_sliderpressed)
        {
            videoMediaElement.Position = TimeSpan.FromSeconds(e.NewValue);
        }
    }

    void videoMediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
    {
        if (videoMediaElement.CurrentState == MediaElementState.Playing)
        {
            Play1.Content = "M27.270001,0L44.310001,0 44.310001,48.643002 27.270001,48.643002z M0,0L17.040001,0 17.040001,48.643002 0,48.643002z";
            Play1.Padding = new Thickness(20, 10, 20, 10);
            if (_sliderpressed)
            {
                _timer.Stop();
            }
            else
            {
                _timer.Start();
            }
        }

        if (videoMediaElement.CurrentState == MediaElementState.Paused)
        {
            Play1.Content = "M0,0L384.885,191.965 769.768,383.928 384.885,576.035 0,768 0,383.928z"; // Play
            Play1.Padding = new Thickness(19, 5, 12, 5);
            _timer.Stop();
        }

        if (videoMediaElement.CurrentState == MediaElementState.Stopped)
        {
            _timer.Stop();
            timelineSlider.Value = 0;
        }
    }

    void videoMediaElement_MediaEnded(object sender, RoutedEventArgs e)
    {
        StopTimer();
        timelineSlider.Value = 0.0;
    }

    private void videoMediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e)
    {
        // get HRESULT from event args 
        string hr = GetHresultFromErrorMessage(e);

        // Handle media failed event appropriately 
    }

    private string GetHresultFromErrorMessage(ExceptionRoutedEventArgs e)
    {
        String hr = String.Empty;
        String token = "HRESULT - ";
        const int hrLength = 10;     // eg "0xFFFFFFFF"

        int tokenPos = e.ErrorMessage.IndexOf(token, StringComparison.Ordinal);
        if (tokenPos != -1)
        {
            hr = e.ErrorMessage.Substring(tokenPos + token.Length, hrLength);
        }

        return hr;
    }

    private DispatcherTimer _timer;

    private void SetupTimer()
    {
        _timer = new DispatcherTimer();
        _timer.Interval = TimeSpan.FromSeconds(1);
        StartTimer();
    }

    private void _timer_Tick(object sender, object e)
    {
        if (!_sliderpressed)
        {
            timelineSlider.Value = videoMediaElement.Position.TotalSeconds;
            TimeSpan TS = new TimeSpan(videoMediaElement.Position.Hours, videoMediaElement.Position.Minutes, videoMediaElement.Position.Seconds);
            TimeSpan TS1 = new TimeSpan(videoMediaElement.NaturalDuration.TimeSpan.Hours, videoMediaElement.NaturalDuration.TimeSpan.Minutes, videoMediaElement.NaturalDuration.TimeSpan.Seconds);
            TextBlock1.Text = TS.Duration().ToString("c") + " / " + TS1.Duration().ToString("c");
        }
    }

    private void StartTimer()
    {
        _timer.Tick += _timer_Tick;
        _timer.Start();
    }

    private void StopTimer()
    {
        _timer.Stop();
        _timer.Tick -= _timer_Tick;
    }

    private double SliderFrequency(TimeSpan timevalue)
    {
        double stepfrequency = -1;

        double absvalue = (int)Math.Round(
            timevalue.TotalSeconds, MidpointRounding.AwayFromZero);

        stepfrequency = (int)(Math.Round(absvalue / 100));

        if (timevalue.TotalMinutes >= 10 && timevalue.TotalMinutes < 30)
        {
            stepfrequency = 10;
        }
        else if (timevalue.TotalMinutes >= 30 && timevalue.TotalMinutes < 60)
        {
            stepfrequency = 30;
        }
        else if (timevalue.TotalHours >= 1)
        {
            stepfrequency = 60;
        }

        if (stepfrequency == 0) stepfrequency += 1;

        if (stepfrequency == 1)
        {
            stepfrequency = absvalue / 100;
        }

        return stepfrequency;
    }

    private void videoMediaElement_PointerPressed(object sender, PointerRoutedEventArgs e)
    {
        if (TransportControlsPanel.Visibility == Windows.UI.Xaml.Visibility.Visible)
        {
            TransportControlsPanel.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
            timer.Stop();
        }
        else
        {
            TransportControlsPanel.Visibility = Windows.UI.Xaml.Visibility.Visible;
            Start_timer();
        }
    }


}

下次尝试给你代码,用这种方式展示你做了什么,这样更容易提供帮助。

您是否在 msdn 上看到了解释如何执行自定义媒体播放器控件的页面?

How to create custom media transport controls (XAML)

您提到了 AreTransportControlsEnabled 我不认为它有延迟,请记住,如果您尝试使用模拟器,它是一个运行 Windows [=43= 的虚拟机] 因此,如果您没有非常强大的计算机,您可能会看到一些延迟,例如在诺基亚 930 上看不到。

但是如果你还想自定义的话,我觉得你可以从msdn给的代码入手。

MainPage.xaml

<Page
    x:Class="MediaPlayerQuickStart.MainPage"
    IsTabStop="false"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MediaPlayerQuickStart"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" 
    Loaded="MainPage_Loaded"> 

    <Page.Resources>
        <Style x:Name="transportStyle"  TargetType="Button">
            <Setter Property="Height" Value="40" />
            <Setter Property="Width" Value="75" />
            <Setter Property="FontSize" Value="11" />
        </Style>
    </Page.Resources>

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Grid.RowDefinitions>
                <RowDefinition Height="*"/>
                <RowDefinition Height="100"/>
            </Grid.RowDefinitions>

            <ContentControl x:Name="videoContainer" 
                            KeyUp="VideoContainer_KeyUp" 
                            HorizontalContentAlignment="Center" 
                            VerticalContentAlignment="Center" 
                            Height="400" Grid.Row="0" >
                <MediaElement Name="videoMediaElement"
                              Source="Media/video1.mp4" 
                              MediaOpened="videoElement_MediaOpened" 
                              MediaEnded="videoMediaElement_MediaEnded" 
                              MediaFailed="videoMediaElement_MediaFailed"
                              CurrentStateChanged="videoMediaElement_CurrentStateChanged"
                              PosterSource="Media/Video1_Poster.png"
                              AutoPlay="False" />
            </ContentControl>
            <!-- Transport Controls -->
        <StackPanel Name="TransportControlsPanel" 
                    HorizontalAlignment="Center" 
                    Grid.Row="1" >
            <Slider Name="timelineSlider" Margin="10,0" Width="200"/>
            <StackPanel Orientation="Horizontal">
                <Button Name="btnPlay" Click="btnPlay_Click" 
                        Style="{StaticResource transportStyle}" Content="Play" />
                <Button Name="btnPause" Click="btnPause_Click"
                        Style="{StaticResource transportStyle}" Content="Pause" />
                <Button Name="btnStop" Click="btnStop_Click"
                        Style="{StaticResource transportStyle}" Content="Stop" />
                <Button Name="btnReverse" Click="btnReverse_Click"
                        Style="{StaticResource transportStyle}" Content="Rewind" />
                <Button Name="btnForward" Click="btnForward_Click"
                        Style="{StaticResource transportStyle}" Content="Forward" />
                <Button Name="btnMute" Click="btnMute_Click" 
                        Style="{StaticResource transportStyle}" Content="Mute" />
                <Button Name="btnFullScreenToggle" Click="btnFullScreenToggle_Click" 
                        Style="{StaticResource transportStyle}" Content="Full" />
                <ComboBox Name="cbAudioTracks"
                          SelectionChanged="cbAudioTracks_SelectionChanged" 
                          Width="75" />
                <Button Name="btnVolumeUp" Click="btnVolumeUp_Click" 
                        Style="{StaticResource transportStyle}" Content="-" />
                <Button Name="btnVolumeDown" Click="btnVolumeDown_Click" 
                        Style="{StaticResource transportStyle}" Content="+" />
                <TextBlock Name="txtVolume" FontSize="14"
                           Text="{Binding Volume, ElementName=videoMediaElement}" 
                           VerticalAlignment="Center" HorizontalAlignment="Right"  />
            </StackPanel>
        </StackPanel>
    </Grid>
</Page>

MainPage.xaml.cs

public sealed partial class MainPage : Page
{
    public MainPage()
    {
        this.InitializeComponent();
    }

    /// <summary>
    /// Invoked when this page is about to be displayed in a Frame.
    /// </summary>
    /// <param name="e">Event data that describes how this page was reached.  The Parameter
    /// property is typically used to configure the page.</param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    }

    // You should use the MediaElement.IsFullWindow property instead
    // to enable and disable full window rendering.
    private bool _isFullscreenToggle = false;
    public bool IsFullscreen
    {
        get { return _isFullscreenToggle; }
        set { _isFullscreenToggle = value; }
    }

    private Size _previousVideoContainerSize = new Size();

    private void FullscreenToggle()
    {
        this.IsFullscreen = !this.IsFullscreen;

        if (this.IsFullscreen)
        {    
            TransportControlsPanel.Visibility = Visibility.Collapsed;

            _previousVideoContainerSize.Width = videoContainer.ActualWidth;
            _previousVideoContainerSize.Height = videoContainer.ActualHeight;

            videoContainer.Width = Window.Current.Bounds.Width;
            videoContainer.Height = Window.Current.Bounds.Height;
            videoMediaElement.Width = Window.Current.Bounds.Width;
            videoMediaElement.Height = Window.Current.Bounds.Height;
        }
        else
        {
            TransportControlsPanel.Visibility = Visibility.Visible;

            videoContainer.Width = _previousVideoContainerSize.Width;
            videoContainer.Height = _previousVideoContainerSize.Height;
            videoMediaElement.Width = _previousVideoContainerSize.Width;
            videoMediaElement.Height = _previousVideoContainerSize.Height;
        }
    }

    private void btnFullScreenToggle_Click(object sender, RoutedEventArgs e)
    {
        FullscreenToggle();
    }

    private void VideoContainer_KeyUp(object sender, KeyRoutedEventArgs e)
    {
        if (IsFullscreen && e.Key == Windows.System.VirtualKey.Escape)
        {
            FullscreenToggle();
        }

        e.Handled = true;
    }

    private void btnPlay_Click(object sender, RoutedEventArgs e)
    {
        if (videoMediaElement.DefaultPlaybackRate != 1)
        {
            videoMediaElement.DefaultPlaybackRate = 1.0;
        }

        videoMediaElement.Play();
    }

    private void btnPause_Click(object sender, RoutedEventArgs e)
    {
            videoMediaElement.Pause();
    }

    private void btnStop_Click(object sender, RoutedEventArgs e)
    {
        videoMediaElement.Stop();
    }

    private void btnForward_Click(object sender, RoutedEventArgs e)
    {
        videoMediaElement.DefaultPlaybackRate = 2.0;
        videoMediaElement.Play();
    }

    private void btnReverse_Click(object sender, RoutedEventArgs e)
    {
        videoMediaElement.DefaultPlaybackRate = -2;
        videoMediaElement.Play();;
    }

    private void btnVolumeDown_Click(object sender, RoutedEventArgs e)
    {
        if (videoMediaElement.IsMuted)
        {
            videoMediaElement.IsMuted = false;
        }

        if (videoMediaElement.Volume < 1)
        {
            videoMediaElement.Volume += .1;
        }
    }

    private void btnMute_Click(object sender, RoutedEventArgs e)
    {
        videoMediaElement.IsMuted = !videoMediaElement.IsMuted;
    }

    private void btnVolumeUp_Click(object sender, RoutedEventArgs e)
    {
        if (videoMediaElement.IsMuted)
        {
            videoMediaElement.IsMuted = false;
        }

        if (videoMediaElement.Volume > 0)
        {
            videoMediaElement.Volume -= .1;
        }
    }

    private void cbAudioTracks_SelectionChanged(
        object sender, SelectionChangedEventArgs e)
    {
        videoMediaElement.AudioStreamIndex = cbAudioTracks.SelectedIndex;
    }

    private void PopulateAudioTracks(
        MediaElement media, ComboBox audioSelection)
    {
        if (media.AudioStreamCount > 0)
        {
            for (int index = 0; index < media.AudioStreamCount; index++)
            {
                ComboBoxItem track = new ComboBoxItem();
                track.Content = media.GetAudioStreamLanguage(index);
                audioSelection.Items.Add(track);
            }
        }
    }

    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        timelineSlider.ValueChanged += timelineSlider_ValueChanged;

        PointerEventHandler pointerpressedhandler = new PointerEventHandler(slider_PointerEntered);
        timelineSlider.AddHandler(Control.PointerPressedEvent, pointerpressedhandler, true);

        PointerEventHandler pointerreleasedhandler = new PointerEventHandler(slider_PointerCaptureLost);
        timelineSlider.AddHandler(Control.PointerCaptureLostEvent, pointerreleasedhandler, true);
    }

    void videoElement_MediaOpened(object sender, RoutedEventArgs e)
    {
        double absvalue = (int)Math.Round(
            videoMediaElement.NaturalDuration.TimeSpan.TotalSeconds,
            MidpointRounding.AwayFromZero);

        timelineSlider.Maximum = absvalue;

        timelineSlider.StepFrequency =
            SliderFrequency(videoMediaElement.NaturalDuration.TimeSpan);

        SetupTimer();

        // Helper method to populate the combobox with audio tracks.
        PopulateAudioTracks(videoMediaElement, cbAudioTracks);
    }

    private bool _sliderpressed = false;

    void slider_PointerEntered(object sender, PointerRoutedEventArgs e)
    {
        _sliderpressed = true;
    }

    void slider_PointerCaptureLost(object sender, PointerRoutedEventArgs e)
    {
        videoMediaElement.Position = TimeSpan.FromSeconds(timelineSlider.Value);
        _sliderpressed = false;
    }

    void timelineSlider_ValueChanged(object sender, Windows.UI.Xaml.Controls.Primitives.RangeBaseValueChangedEventArgs e)
    {
        if (!_sliderpressed)
        {
            videoMediaElement.Position = TimeSpan.FromSeconds(e.NewValue);
        }
    }

    void videoMediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
    {
        if (videoMediaElement.CurrentState == MediaElementState.Playing)
        {
            if (_sliderpressed)
            {
                _timer.Stop();
            }
            else
            {
                _timer.Start();
            }
        }

        if (videoMediaElement.CurrentState == MediaElementState.Paused)
        {
            _timer.Stop();
        }

        if (videoMediaElement.CurrentState == MediaElementState.Stopped)
        {
            _timer.Stop();
            timelineSlider.Value = 0;
        }
    }

    void videoMediaElement_MediaEnded(object sender, RoutedEventArgs e)
    {
        StopTimer();
        timelineSlider.Value = 0.0;
    }

    private void videoMediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e)
    {
        // get HRESULT from event args 
        string hr = GetHresultFromErrorMessage(e);

        // Handle media failed event appropriately 
    }

    private string GetHresultFromErrorMessage(ExceptionRoutedEventArgs e)
    {
        String hr = String.Empty;
        String token = "HRESULT - ";
        const int hrLength = 10;     // eg "0xFFFFFFFF"

        int tokenPos = e.ErrorMessage.IndexOf(token, StringComparison.Ordinal);
        if (tokenPos != -1)
        {
            hr = e.ErrorMessage.Substring(tokenPos + token.Length, hrLength);
        }

        return hr;
    }

    private DispatcherTimer _timer;

    private void SetupTimer()
    {
        _timer = new DispatcherTimer();
        _timer.Interval = TimeSpan.FromSeconds(timelineSlider.StepFrequency);
        StartTimer();
    }

    private void _timer_Tick(object sender, object e)
    {
        if (!_sliderpressed)
        {
            timelineSlider.Value = videoMediaElement.Position.TotalSeconds;
        }
    }

    private void StartTimer()
    {
        _timer.Tick += _timer_Tick;
        _timer.Start();
    }

    private void StopTimer()
    {
        _timer.Stop();
        _timer.Tick -= _timer_Tick;
    }

    private double SliderFrequency(TimeSpan timevalue)
    {
        double stepfrequency = -1;

        double absvalue = (int)Math.Round(
            timevalue.TotalSeconds, MidpointRounding.AwayFromZero);

        stepfrequency = (int)(Math.Round(absvalue / 100));

        if (timevalue.TotalMinutes >= 10 && timevalue.TotalMinutes < 30)
        {
            stepfrequency = 10;
        }
        else if (timevalue.TotalMinutes >= 30 && timevalue.TotalMinutes < 60)
        {
            stepfrequency = 30;
        }
        else if (timevalue.TotalHours >= 1)
        {
            stepfrequency = 60;
        }

        if (stepfrequency == 0) stepfrequency += 1;

        if (stepfrequency == 1)
        {
            stepfrequency = absvalue / 100;
        }

        return stepfrequency;
    }
}

如果你想改变按钮的外观,你可以使用 AppBarButton 而不是普通按钮(给它们圆形 windows8 的外观)

要更改全屏行为,请查看 FullscreenToggle()。在此示例中,他们使用控件折叠 StackPanel,但您不必这样做并且可以实现您自己的逻辑。