2016-09-27 5 views
0

我有一个MediaElement在自定义的UserControl中设置了一个我一直在做的视频播放器控制 - 播放/暂停按钮,滑块,剩余时间等。我有ScrubbingEnabled设置为True,这样我就可以显示第一个该视频帧按照SO帖子here发送给用户,并且还使用Slider元素来允许用户擦洗视频。C#MediaElement - 为什么在切换源代码后Play()有时会以静默方式失败?

问题:我使用绑定来切换视频播放器的源代码。有时,如果我在播放视频时切换视频MediaElement将停止响应Play()命令。没有错误发生,即使在MediaFailed事件。拨打Play()(或Pause(),然后Play())每次都会失败。我可以在MediaElement失败后切换视频源,然后重新开始工作。

XAML:

<MediaElement LoadedBehavior="Manual" ScrubbingEnabled="True" 
       UnloadedBehavior="Stop" 
       MediaOpened="VideoPlayer_MediaOpened" x:Name="VideoPlayer"/> 

相关的控制代码:

public static DependencyProperty VideoSourceProperty = 
      DependencyProperty.Register("VideoSource", typeof(string), typeof(MediaElementVideoPlayer), 
       new FrameworkPropertyMetadata(null, 
        FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure, 
        new PropertyChangedCallback(OnSourceChanged))); 

private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    MediaElementVideoPlayer player = d as MediaElementVideoPlayer; 
    if (player != null) 
    { 
     player.Dispatcher.Invoke(() => { 
      if (player.VideoSource != null && player.VideoSource != "") 
      { 
       if (player._isPlaying) 
       { 
        player.VideoPlayer.Stop(); 
        var uriSource = new Uri(@"/ImageResources/vid-play.png", UriKind.Relative); 
        player.PlayPauseImage.Source = new BitmapImage(uriSource); 
        player._isPlaying = false; 
       } 
       player.VideoPlayer.Source = new Uri(player.VideoSource); 
      } 
     }); 
    } 
} 

private void VideoPlayer_MediaOpened(object sender, RoutedEventArgs e) 
{ 
    Dispatcher.Invoke(() => 
    { 
     VideoPlayer.Pause(); 
     VideoPlayer.Position = TimeSpan.FromTicks(0); 
     Player.IsMuted = false; 
     TimeSlider.Minimum = 0; 
     // Set the time slider values & time label 
     if (VideoPlayer.NaturalDuration != null && VideoPlayer.NaturalDuration != Duration.Automatic) 
     { 
      TimeSlider.Maximum = VideoPlayer.NaturalDuration.TimeSpan.TotalSeconds; 
      TimeSlider.Value = 0; 
      double totalSeconds = VideoPlayer.NaturalDuration.TimeSpan.TotalSeconds; 
      _durationString = Utilities.numberSecondsToString((int)totalSeconds, true, true); 
      TimeLabel.Content = "-/" + _durationString; 
     } 
    }); 
} 

如果我告诉视频自动播放所有的时间,玩家的工作100%的时间,奇怪的是。不幸的是,我需要在源设置时暂停视频。 有谁知道如何避免MediaElement的随机,隐藏故障,同时还在交换视频,显示加载的视频的第一帧等?

有很奇怪的类似的问题herehere,但我的问题有不同的症状,因为我只使用1 MediaElement

回答

0

奇怪的是,如果您将ScrubbingEnabled设置为False,则MediaElement不再会在随机时间停止响应。禁用ScrubbingEnabled中断显示第一帧,并使Slider元素不能很好地工作,所以这里是如何保持这些功能,同时没有,呃,打破MediaElement

显示的第一帧:

private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    MediaElementVideoPlayer player = d as MediaElementVideoPlayer; 
    if (player != null) 
    { 
     player.Dispatcher.Invoke(() => { 
      if (player.VideoSource != null && player.VideoSource != "") 
      { 
       if (player._isPlaying) 
       { 
        player.VideoPlayer.Stop(); 
        var uriSource = new Uri(@"/ImageResources/vid-play.png", UriKind.Relative); 
        player.PlayPauseImage.Source = new BitmapImage(uriSource); 
        player._isPlaying = false; 
       } 
       player.VideoPlayer.Source = new Uri(player.VideoSource); 
       // Start the video playing so that it will show the first frame. 
       // We're going to pause it immediately so that it doesn't keep playing. 
       player.VideoPlayer.IsMuted = true; // so sound won't be heard 
       player.VideoPlayer.Play(); 
      } 
     }); 
    } 
} 

private void VideoPlayer_MediaOpened(object sender, RoutedEventArgs e) 
{ 
    Dispatcher.Invoke(() => 
    { 
     // the video thumbnail is now showing! 
     VideoPlayer.Pause(); 
     // reset video to initial position 
     VideoPlayer.Position = TimeSpan.FromTicks(0); 
     Player.IsMuted = false; // unmute video 
     TimeSlider.Minimum = 0; 
     // Set the time slider values & time label 
     if (VideoPlayer.NaturalDuration != null && VideoPlayer.NaturalDuration != Duration.Automatic) 
     { 
      TimeSlider.Maximum = VideoPlayer.NaturalDuration.TimeSpan.TotalSeconds; 
      TimeSlider.Value = 0; 
      double totalSeconds = VideoPlayer.NaturalDuration.TimeSpan.TotalSeconds; 
      _durationString = Utilities.numberSecondsToString((int)totalSeconds, true, true); 
      TimeLabel.Content = "-/" + _durationString; 
     } 
    }); 
} 

启用擦洗用于视频当滑块被拖动:

// ValueChanged for Slider 
private void TimeSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e) 
{ 
    Dispatcher.Invoke(() => { 
     TimeSpan videoPosition = TimeSpan.FromSeconds(TimeSlider.Value); 
     VideoPlayer.Position = videoPosition; 
     TimeLabel.Content = Utilities.numberSecondsToString((int)VideoPlayer.Position.TotalSeconds, true, true) + "/" + _durationString; 
    }); 
} 

// DragStarted event 
private void slider_DragStarted(object sender, System.Windows.Controls.Primitives.DragStartedEventArgs e) 
{ 
    Dispatcher.Invoke(() => { 
     VideoPlayer.ScrubbingEnabled = true; 
     VideoPlayer.Pause(); 
    }); 
} 

// DragCompleted event 
private void slider_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e) 
{ 
    Dispatcher.Invoke(() => { 
     VideoPlayer.ScrubbingEnabled = false; 
     TimeSpan videoPosition = TimeSpan.FromSeconds(TimeSlider.Value); 
     VideoPlayer.Position = videoPosition; 
     if (_isPlaying) // if was playing when drag started, resume playing 
      VideoPlayer.Play(); 
     else 
      VideoPlayer.Pause(); 
    }); 
} 
相关问题