C#MediaElement - 为什么Play()在切换源后有时会无声地失败?

时间:2016-09-27 14:14:38

标签: c# wpf video mediaelement

我在自定义UserControl中设置MediaElement,用于我正在制作的视频播放器控件 - 播放/暂停按钮,滑块,剩余时间等。我有{{1}设置为ScrubbingEnabled,以便我可以根据SO帖子here向用户显示视频的第一帧,并使用True元素允许用户清除视频

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

XAML:

MediaElement

相关控制代码:

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

如果我一直告诉视频自动播放,播放器会100%的时间工作,奇怪的是。不幸的是,我需要在设置源时暂停视频。 是否有人知道如何避免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; } }); } 的随机隐藏失败,同时仍然交换视频,显示已加载视频的第一帧等?

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

1 个答案:

答案 0 :(得分:1)

奇怪的是,如果您将MediaElement设置为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;
        }
    });
}