none
win 8 app中Silder拖动无法及时控制MediaElement的播放进度,点点击slider却没有问题? RRS feed

  • 问题

  • 我设置了MediaElement的Position绑定为Slider的值并设置为TwoWay,但现在如果我拖拉Slider到某个值的时候,Slider会回退到之前的值点(而点击Slider的话,又不会退回去),以下是我的代码,高手帮忙看如何可以实现拖拉也可以实时更改进度值

         <MediaElement x:Name="mediaElement" Volume="{Binding ElementName=voiceSlider, Path=Value,Converter={StaticResource SliderValueToVolumeConvert},Mode=OneWay}" Grid.Row="1"
                          Position="{Binding ElementName=musicSlider,Path=Value,Converter={StaticResource TimeSpanToDoubleConverter},Mode=TwoWay}" AutoPlay="True" AudioCategory="BackgroundCapableMedia" />

    <Slider x:Name="musicSlider" Grid.Column="1" VerticalAlignment="Center" Background="Gray" Height="40" Style="{StaticResource MyRedSliderStyle}"/>

       public class TimeSpanToDoubleConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, string language)
            {
                double result = double.Parse(value.ToString());

                return TimeSpan.FromSeconds(result);
               
            }

            public object ConvertBack(object value, Type targetType, object parameter, string language)
            {
                TimeSpan result;
                TimeSpan.TryParse(value.ToString(), out result);

                return result.TotalSeconds;
            }
        }

    现在很困惑,不知道怎么进行操作才能做到正确的拖拉实时跟新了。求高手帮忙!

    2014年1月10日 11:29

答案

  • <Page
        x:Class="TestVideoPlay.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:conver="using:TestVideoPlay.Convert"
        xmlns:local="using:TestVideoPlay"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Page.Resources>
            <!--<convert:SliderValueToVolume  x:Key="SliderValueToVolumeConvert"/>-->
            <!--<convert:SliderValueToVolume x:Key="SliderValueToVolumeConvert"/>-->
            <conver:SliderValueToVolume x:Key="SliderValueToVolumeConvert"/>
            <conver:TimeSpanToDoubleConverter x:Key="TimeSpanConverter"/>
        </Page.Resources>
        
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            
            <!--<MediaElement x:Name="mediaElement" Volume="{Binding ElementName=voiceSlider, Path=Value,Converter={StaticResource SliderValueToVolumeConvert},Mode=OneWay}"
                         CurrentStateChanged="mediaElement_CurrentStateChanged"  AutoPlay="False" Grid.Row="0" Grid.RowSpan="3" Position="{Binding ElementName=videoSlider,Path=Value,Converter={StaticResource TimeSpanConverter},Mode=TwoWay}"/>-->
            <MediaElement x:Name="mediaElement" Volume="{Binding ElementName=voiceSlider, Path=Value,Converter={StaticResource SliderValueToVolumeConvert},Mode=OneWay}"
                         CurrentStateChanged="mediaElement_CurrentStateChanged"  AutoPlay="False" Grid.Row="0" Grid.RowSpan="3"/>
            
            <Slider x:Name="voiceSlider" Maximum="10" LargeChange="10000" SmallChange="1" Value="5" HorizontalAlignment="Left" Margin="1169.37,272.313,-37.07,0"
                    ValueChanged="voiceSlider_ValueChanged"  VerticalAlignment="Top" Width="233.7" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto">
                <Slider.RenderTransform>
                    <CompositeTransform Rotation="-91.685"/>
                </Slider.RenderTransform>
            </Slider>
    
            <TextBlock x:Name="CurrentTbk" Text="哈哈" FontSize="22"  Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Bottom"  Margin="28,0,0,37"/>
            <Slider x:Name="videoSlider" Background="Gray"  Height="40"  ValueChanged="videoSlider_ValueChanged"  Margin="109,695,106,33" />
            <TextBlock x:Name="TotalTbk" Text="呜呜"  FontSize="22"  Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,26,38"/>
            <Button x:Name="btnPlayLoclFile"  Content="播放本地视频" Tapped="btnPlayLoclFile_Tapped"  HorizontalAlignment="Left" Margin="28,625,0,0" VerticalAlignment="Top"/>
            <Button x:Name="btnPlayNetFile" Content="播放网络视频" Tapped="btnPlayNetFile_Tapped"  HorizontalAlignment="Left" Margin="181,625,0,0" VerticalAlignment="Top"/>
        </Grid>
    </Page>
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    using Windows.UI.Popups;
    using Windows.UI.Core;
    using Windows.Storage;
    
    // “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介绍
    
    namespace TestVideoPlay
    {
        /// <summary>
        /// 可用于自身或导航至 Frame 内部的空白页。
        /// </summary>
        public sealed partial class MainPage : Page
        {
            TimeSpan videoTime;
            Windows.System.Display.DisplayRequest displayRequest = new Windows.System.Display.DisplayRequest();   //激活屏幕
            private DispatcherTimer video_timer = new DispatcherTimer();
    
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            /// <summary>
            /// 在此页将要在 Frame 中显示时进行调用。
            /// </summary>
            /// <param name="e">描述如何访问此页的事件数据。Parameter
            /// 属性通常用于配置页。</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                TotalTbk.Text = "__:__:__";
                CurrentTbk.Text = "__:__:__";
                mediaElement.MediaOpened += mediaElement_MediaOpened;
                mediaElement.MediaFailed += mediaElement_MediaFailed;
                mediaElement.MediaEnded += mediaElement_MediaEnded;
            
            }
    
            async void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    CurrentTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", videoTime.Hours, videoTime.Minutes, videoTime.Seconds);
                });
            }
    
            async void mediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e)
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,async () =>
                {
                    MessageDialog mg = new MessageDialog("信息提示");
                    mg.Content = e.ErrorMessage;
                    await mg.ShowAsync();
                });
            }
    
            async void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
            {
    
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    videoTime = mediaElement.NaturalDuration.HasTimeSpan ? mediaElement.NaturalDuration.TimeSpan : TimeSpan.FromSeconds(0);
                    TotalTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", videoTime.Hours, videoTime.Minutes, videoTime.Seconds);
    
                    videoSlider.Maximum = videoTime.TotalSeconds;
                    displayRequest.RequestActive();    //激活屏幕
                    mediaElement.Play();
    
                    //将正在播放的放到top25里
    
                    video_timer.Interval = TimeSpan.FromSeconds(0.5);
                    video_timer.Tick += video_timer_Tick;
                    video_timer.Start();
                });          
            }
    
           async void video_timer_Tick(object sender, object e)
            {
               await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    if (mediaElement.CurrentState == MediaElementState.Playing)
                    {
                        if (CurrentTbk.Text.Equals("__:__:__"))
                            CurrentTbk.Text = "00:00:00";
    
                        CurrentTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", mediaElement.Position.Hours, mediaElement.Position.Minutes, mediaElement.Position.Seconds);
    
                        TimeSpan currentTime = TimeSpan.Parse(CurrentTbk.Text);
    
                        TimeSpan nowTime = videoTime - currentTime;   //减去要递减的时间
                        TotalTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", nowTime.Hours, nowTime.Minutes, nowTime.Seconds);
                    }
                });
            }
    
          
            private void voiceSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                if (voiceSlider == null) return;
    
                if (mediaElement.IsMuted || e.NewValue != 0.0)
                {
                    mediaElement.IsMuted = false; //当前静音的时候拉到了音量就变为不静音
                    return;
                }
    
                if (e.NewValue == 0.0)
                {
                    mediaElement.IsMuted = true;  
                }
                else
                {
                    mediaElement.IsMuted = false;
                }
            }
    
            private void videoSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                //mediaElement.Pause();
                mediaElement.Position = TimeSpan.FromSeconds(videoSlider.Value);
                //mediaElement.Play();
            }
    
        
    
            private async void btnPlayLoclFile_Tapped(object sender, TappedRoutedEventArgs e)
            {
                StorageFolder folder = KnownFolders.VideosLibrary;
                string fileName = "DefragTools.wmv";
                StorageFile file = await folder.GetFileAsync(fileName);
                var streamFile = await file.OpenAsync(FileAccessMode.Read);
              
                mediaElement.SetSource(streamFile,file.ContentType);
            }
    
            private void btnPlayNetFile_Tapped(object sender, TappedRoutedEventArgs e)
            {
                string strPath = "http://192.168.6.104/data/UsbDisk1/Volume1/Video/最高纪录 高清.mp4";  //http://192.168.6.104/data/UsbDisk1/Volume1/Video/功夫小蝇 高清.mp4
                mediaElement.Source = new Uri(strPath, UriKind.Absolute);
            }
    
            private void mediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
            {
                videoSlider.Value = mediaElement.Position.TotalSeconds;
            }
        }
    }
    


    2014年1月14日 6:41
  • Hi Billy-NuoYan,

    多谢 JackSlaterYu 的帮助,看样子目前你本地播放的问题已经解决,我正在查看远程播放的代码,稍后给你回复。

    ==update==

    看样子的确是buffering的问题,参考下文档:http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.media.mediaelementstate.aspx 里面有写到:

    The MediaElement is loading the media for playback. Its Position does not advance during this state. If the MediaElement was already playing video, it continues to display the last displayed frame.

    以上内容的意思就是说如果MediaElement在播放,但是之后的内容还处于Buffering的状态,MediaElement则会播放最后一个(最邻近)可以播放的帧。

    作为测试可以设定一个TextBox用于绑定MediaElement的CurrentStatus或者绑定Buffering Progress,可以看到成功拖动进度条的地方其实是已经Buffer的内容,而进度条回弹的地方则是未Buffer到的内容。

    我建议可以类似于flash缓冲那样可以做一个“正在缓冲”的字样,然后等BufferingProgress = 1的时候再继续播放应该可行。

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.


    2014年1月15日 3:29
    版主

全部回复

  • 没人回答吗?微软啊,你给点力行不?
    2014年1月11日 1:40
  • Hi Billy-NuoYan,

    一般周一到周五工作时间的问题将会在24小时之内及时被答复,请谅解,并感谢对论坛的支持。

    对于你这个问题,我这里尝试重现了下,下面是我的代码,修改了部分,但是可以运行,不存在问题

                <MediaElement x:Name="mediaElement" 
                              Height="300"
                              Position="{Binding ElementName=musicSlider,Path=Value,Converter={StaticResource TimeSpanToDoubleConverter},Mode=TwoWay}" 
                              AutoPlay="True" 
                              AudioCategory="BackgroundCapableMedia" Source="Assets/1.mp4" />
    
                <Slider x:Name="musicSlider" Background="Gray" Height="40" Maximum="15" />

    #1,你并未给Slider设置最大值,默认的最大值为100,如果你的视频只有10秒的话,那么Slider会在10的地方停止,同时你的Convert并没有做出对应的转换。

    #2,你并未对MediaElement作一个播放的处理动作,也就是说一旦你的视频播放完毕,你再拖动Slider只会有定位效果,不会有播放效果。

    在我测试的文件中,我的视频是15秒,所以我把Slider设定为15,同时我会对Slider的ValueChange事件做出一个逻辑响应,播放视频:

             private void valueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                mediaElement.Play();
            }

    这样你的问题应该能解决了。

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    2014年1月11日 7:10
    版主
  • thank you !jamles hez! 

    1:你所说的给Slider设置最大值的情况,我在后台代码中在mediaElement_MediaOpened有设置最大值的

     void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
            {
                Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    UIHelper.SetPopupHide(PopupGrid, myPoup, WaitProgressRing);  //隐藏转圈
                    videoTime = mediaElement.NaturalDuration.HasTimeSpan ? mediaElement.NaturalDuration.TimeSpan : TimeSpan.FromSeconds(0);
                    TotalTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", videoTime.Hours, videoTime.Minutes, videoTime.Seconds);

                    videoSlider.Maximum = videoTime.TotalSeconds;
                    displayRequest.RequestActive();    //激活屏幕
                    mediaElement.Play();

    }

    2:对于你说的并未对MediaElement作一个播放的处理动作情况,我在播放完的事件中,会自动进行暂停操作(我说的拉动会回退的情况也不是在播放完毕出现的)

      void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
            {
                Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    CurrentTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", videoTime.Hours, videoTime.Minutes, videoTime.Seconds);

                    videoPlayImage.Tag = "Pause";
                    videoPlayImage.Source = new BitmapImage(new Uri("ms-appx:///Assets/Images/Icons/media_stop.png"));

                    if (!m_isFullScreen) return;

                    SetFullScreenBySclae();   //播放完就退出全屏
                });
            }

    3:另外我也使用你所说的 valueChanged方法中进行播放,但还是不行

    private void valueChanged(object sender, RangeBaseValueChangedEventArgs e)
           
    {
                mediaElement
    .Play();
           
    }

    4:我提供了我现象重新的视频:现在的现象是:如果你拉动的时候马上送开手就会回弹回去,而如果你拉动到一个地方手停顿下不马上松开就可以继续播放不会回弹。具体显示可以查看我拍摄的重现视频,在skydrive   连接:https://skydrive.live.com/redir?resid=56C8C9A332A136A7!283&authkey=!ALhh5BB7f7ytGwg&ithint=video%2c.3gp

    希望jamles hez! 能帮帮我忙,这个问题实在不知道怎么解决了。

    2014年1月13日 3:48
  • Hi Billy,

    非常感谢你的视频,我回去重现一下你的代码试试,不过你提供的代码是视频打开以及关闭,从你的视频来看打开播放和关闭播放没有什么问题,可能问题还是在绑定上。

    另外我还想到一个可能性,你的视频看样子是一部电影,源是本地还是网上?如果是网络的话问题很可能在这里,举个例子来说如果你在浏览器下监控Youtube或者优酷的视频源,你会发现其实缓冲并不是一次性把整个视频全部都缓冲完成的,是分成好多个小片段来缓冲,会不会因为这个原因导致视频无法正常调节进度?

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.


    2014年1月13日 12:11
    版主
  • Hi!jamles hez!我提供的那个视频数相当于网络上的,但我播放本地的视频也是同样的出现了回弹情况。同时你说可能网络的存在缓存的问题,那我有个疑问:我拉动过去稍微停顿下就不会回弹了。

    下面我将我的这的代码写了一个demo提供出来(这里测试了本地和设备上的视频,都有回弹想象),希望能让你看到现场重现,可以让你更好的帮忙解决下这个问题。这是demo的连接https://skydrive.live.com/redir?resid=56C8C9A332A136A7!284&authkey=!AIoIofEzUbMaZxY&ithint=file%2c.rar  名字为TestVideoPlay。  如果是因为我代码中或者是我的值转换没设置好而导致出现回弹的,还请版主你帮忙指出我的问题所在点,方便我改正。这是我测试时候录制的视频:https://skydrive.live.com/redir?resid=56C8C9A332A136A7!285&authkey=!ADs3g9ZZc7SCScY&ithint=video%2c.3gp

    先谢谢了

    2014年1月14日 3:43
  • 我也下载一起研究,希望能有机会帮到你
    2014年1月14日 3:57
  • thank you ! jackstaterYU!
    2014年1月14日 4:59
  • Hi,你参考这下这个 samplecode,里面同样有 通过slider滑动条 来改变视频的播放进度看看能否解决你的问题

    3KS

    http://code.msdn.microsoft.com/Windows-8-Video-Player-ef4c3113

    2014年1月14日 5:27
  • 补充个链接 第二版的: http://code.msdn.microsoft.com/Windows-8-Video-Player-v2-2122d822
    2014年1月14日 5:31
  • thank you !  这两个例子都没有通过slider更改MediaElement的播放进度,只有音量的。但还是非常感谢!
    2014年1月14日 6:06
  • <Page
        x:Class="TestVideoPlay.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:conver="using:TestVideoPlay.Convert"
        xmlns:local="using:TestVideoPlay"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Page.Resources>
            <!--<convert:SliderValueToVolume  x:Key="SliderValueToVolumeConvert"/>-->
            <!--<convert:SliderValueToVolume x:Key="SliderValueToVolumeConvert"/>-->
            <conver:SliderValueToVolume x:Key="SliderValueToVolumeConvert"/>
            <conver:TimeSpanToDoubleConverter x:Key="TimeSpanConverter"/>
        </Page.Resources>
        
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            
            <!--<MediaElement x:Name="mediaElement" Volume="{Binding ElementName=voiceSlider, Path=Value,Converter={StaticResource SliderValueToVolumeConvert},Mode=OneWay}"
                         CurrentStateChanged="mediaElement_CurrentStateChanged"  AutoPlay="False" Grid.Row="0" Grid.RowSpan="3" Position="{Binding ElementName=videoSlider,Path=Value,Converter={StaticResource TimeSpanConverter},Mode=TwoWay}"/>-->
            <MediaElement x:Name="mediaElement" Volume="{Binding ElementName=voiceSlider, Path=Value,Converter={StaticResource SliderValueToVolumeConvert},Mode=OneWay}"
                         CurrentStateChanged="mediaElement_CurrentStateChanged"  AutoPlay="False" Grid.Row="0" Grid.RowSpan="3"/>
            
            <Slider x:Name="voiceSlider" Maximum="10" LargeChange="10000" SmallChange="1" Value="5" HorizontalAlignment="Left" Margin="1169.37,272.313,-37.07,0"
                    ValueChanged="voiceSlider_ValueChanged"  VerticalAlignment="Top" Width="233.7" RenderTransformOrigin="0.5,0.5" UseLayoutRounding="False" d:LayoutRounding="Auto">
                <Slider.RenderTransform>
                    <CompositeTransform Rotation="-91.685"/>
                </Slider.RenderTransform>
            </Slider>
    
            <TextBlock x:Name="CurrentTbk" Text="哈哈" FontSize="22"  Foreground="White" HorizontalAlignment="Left" VerticalAlignment="Bottom"  Margin="28,0,0,37"/>
            <Slider x:Name="videoSlider" Background="Gray"  Height="40"  ValueChanged="videoSlider_ValueChanged"  Margin="109,695,106,33" />
            <TextBlock x:Name="TotalTbk" Text="呜呜"  FontSize="22"  Foreground="White" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,26,38"/>
            <Button x:Name="btnPlayLoclFile"  Content="播放本地视频" Tapped="btnPlayLoclFile_Tapped"  HorizontalAlignment="Left" Margin="28,625,0,0" VerticalAlignment="Top"/>
            <Button x:Name="btnPlayNetFile" Content="播放网络视频" Tapped="btnPlayNetFile_Tapped"  HorizontalAlignment="Left" Margin="181,625,0,0" VerticalAlignment="Top"/>
        </Grid>
    </Page>
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    using Windows.UI.Popups;
    using Windows.UI.Core;
    using Windows.Storage;
    
    // “空白页”项模板在 http://go.microsoft.com/fwlink/?LinkId=234238 上有介绍
    
    namespace TestVideoPlay
    {
        /// <summary>
        /// 可用于自身或导航至 Frame 内部的空白页。
        /// </summary>
        public sealed partial class MainPage : Page
        {
            TimeSpan videoTime;
            Windows.System.Display.DisplayRequest displayRequest = new Windows.System.Display.DisplayRequest();   //激活屏幕
            private DispatcherTimer video_timer = new DispatcherTimer();
    
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            /// <summary>
            /// 在此页将要在 Frame 中显示时进行调用。
            /// </summary>
            /// <param name="e">描述如何访问此页的事件数据。Parameter
            /// 属性通常用于配置页。</param>
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
                TotalTbk.Text = "__:__:__";
                CurrentTbk.Text = "__:__:__";
                mediaElement.MediaOpened += mediaElement_MediaOpened;
                mediaElement.MediaFailed += mediaElement_MediaFailed;
                mediaElement.MediaEnded += mediaElement_MediaEnded;
            
            }
    
            async void mediaElement_MediaEnded(object sender, RoutedEventArgs e)
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    CurrentTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", videoTime.Hours, videoTime.Minutes, videoTime.Seconds);
                });
            }
    
            async void mediaElement_MediaFailed(object sender, ExceptionRoutedEventArgs e)
            {
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal,async () =>
                {
                    MessageDialog mg = new MessageDialog("信息提示");
                    mg.Content = e.ErrorMessage;
                    await mg.ShowAsync();
                });
            }
    
            async void mediaElement_MediaOpened(object sender, RoutedEventArgs e)
            {
    
                await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    videoTime = mediaElement.NaturalDuration.HasTimeSpan ? mediaElement.NaturalDuration.TimeSpan : TimeSpan.FromSeconds(0);
                    TotalTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", videoTime.Hours, videoTime.Minutes, videoTime.Seconds);
    
                    videoSlider.Maximum = videoTime.TotalSeconds;
                    displayRequest.RequestActive();    //激活屏幕
                    mediaElement.Play();
    
                    //将正在播放的放到top25里
    
                    video_timer.Interval = TimeSpan.FromSeconds(0.5);
                    video_timer.Tick += video_timer_Tick;
                    video_timer.Start();
                });          
            }
    
           async void video_timer_Tick(object sender, object e)
            {
               await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                {
                    if (mediaElement.CurrentState == MediaElementState.Playing)
                    {
                        if (CurrentTbk.Text.Equals("__:__:__"))
                            CurrentTbk.Text = "00:00:00";
    
                        CurrentTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", mediaElement.Position.Hours, mediaElement.Position.Minutes, mediaElement.Position.Seconds);
    
                        TimeSpan currentTime = TimeSpan.Parse(CurrentTbk.Text);
    
                        TimeSpan nowTime = videoTime - currentTime;   //减去要递减的时间
                        TotalTbk.Text = string.Format("{0:00}:{1:00}:{2:00}", nowTime.Hours, nowTime.Minutes, nowTime.Seconds);
                    }
                });
            }
    
          
            private void voiceSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                if (voiceSlider == null) return;
    
                if (mediaElement.IsMuted || e.NewValue != 0.0)
                {
                    mediaElement.IsMuted = false; //当前静音的时候拉到了音量就变为不静音
                    return;
                }
    
                if (e.NewValue == 0.0)
                {
                    mediaElement.IsMuted = true;  
                }
                else
                {
                    mediaElement.IsMuted = false;
                }
            }
    
            private void videoSlider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
            {
                //mediaElement.Pause();
                mediaElement.Position = TimeSpan.FromSeconds(videoSlider.Value);
                //mediaElement.Play();
            }
    
        
    
            private async void btnPlayLoclFile_Tapped(object sender, TappedRoutedEventArgs e)
            {
                StorageFolder folder = KnownFolders.VideosLibrary;
                string fileName = "DefragTools.wmv";
                StorageFile file = await folder.GetFileAsync(fileName);
                var streamFile = await file.OpenAsync(FileAccessMode.Read);
              
                mediaElement.SetSource(streamFile,file.ContentType);
            }
    
            private void btnPlayNetFile_Tapped(object sender, TappedRoutedEventArgs e)
            {
                string strPath = "http://192.168.6.104/data/UsbDisk1/Volume1/Video/最高纪录 高清.mp4";  //http://192.168.6.104/data/UsbDisk1/Volume1/Video/功夫小蝇 高清.mp4
                mediaElement.Source = new Uri(strPath, UriKind.Absolute);
            }
    
            private void mediaElement_CurrentStateChanged(object sender, RoutedEventArgs e)
            {
                videoSlider.Value = mediaElement.Position.TotalSeconds;
            }
        }
    }
    


    2014年1月14日 6:41
  • 根据上述代码修改就可以解决
    2014年1月14日 7:03
  • jackslateryu的方法对于是本地文件是可以解决次问题,而网络视频的情况下还是会有回弹现象!

    2014年1月14日 8:24
  • help! help!
    2014年1月15日 3:05
  • Hi Billy-NuoYan,

    多谢 JackSlaterYu 的帮助,看样子目前你本地播放的问题已经解决,我正在查看远程播放的代码,稍后给你回复。

    ==update==

    看样子的确是buffering的问题,参考下文档:http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.media.mediaelementstate.aspx 里面有写到:

    The MediaElement is loading the media for playback. Its Position does not advance during this state. If the MediaElement was already playing video, it continues to display the last displayed frame.

    以上内容的意思就是说如果MediaElement在播放,但是之后的内容还处于Buffering的状态,MediaElement则会播放最后一个(最邻近)可以播放的帧。

    作为测试可以设定一个TextBox用于绑定MediaElement的CurrentStatus或者绑定Buffering Progress,可以看到成功拖动进度条的地方其实是已经Buffer的内容,而进度条回弹的地方则是未Buffer到的内容。

    我建议可以类似于flash缓冲那样可以做一个“正在缓冲”的字样,然后等BufferingProgress = 1的时候再继续播放应该可行。

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.


    2014年1月15日 3:29
    版主
  • 谢谢版主!我尝试着这样去做。

    2014年1月16日 1:20