gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 17:36:19 25 4
gpt4 key购买 nike

我在自定义用户控件中设置了一个 MediaElement,用于我一直在制作的视频播放器控件——播放/暂停按钮、 slider 、剩余时间等。我有 ScrubbingEnabled 设置为 True 以便我可以根据 SO 帖子 here 向用户显示视频的第一帧,并使用 Slider 元素允许用户滑动视频。

问题:我使用绑定(bind)来切换视频播放器的来源。有时,如果我在播放视频时切换视频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

最佳答案

奇怪的是,如果将 ScrubbingEnabled 设置为 FalseMediaElement 将不再随机停止响应。禁用 ScrubbingEnabled 会中断显示第一帧并使 Slider 元素无法很好地运行,因此这里介绍了如何在没有,呃,损坏的 的情况下保留这些功能媒体元素

显示第一帧:

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;
}
});
}

在拖动 slider 时启用视频擦洗:

// 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();
});
}

关于C# MediaElement -- 为什么 Play() 有时会在切换源后无提示地失败?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39727054/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com