更改 MediaElement 源而不发生闪烁

Ste*_*lis 3 wpf mediaelement

我有一个简单的视频播放器,它使用 WPF MediaElement 播放一系列视频。这些视频一起形成一部围绕静止图像移动的连续电影。在每个视频结束时,运动会冻结在当前播放视频的最后一帧。当我按下按钮时,会播放下一个视频,并继续围绕静止图像进行移动。这是我将用来发表演讲的应用程序。实际上,我有一系列视频,每个视频的最后一帧与下一个视频的第一帧相同。

我正在使用 WPF MediaElement 并在用户单击鼠标时更改 Source 属性。

我遇到的问题是,当我更改 Source 属性时,MediaElement 在加载下一个视频时变得透明。这意味着视频之间存在闪烁。有什么办法可以防止这种闪烁吗?我还可以使用哪些其他策略?

这是一些代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        this.x_MediaElement.MouseLeftButtonDown += x_MediaElement_MouseLeftButtonDown;
        this.MouseLeftButtonDown += MainWindow_MouseLeftButtonDown;


        this.WindowStyle = WindowStyle.None;
        this.WindowState = WindowState.Maximized;
    }

    void MainWindow_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        MoveNext();   
    }

    private void MoveNext()
    {
        _sourceIndex++;
        if (_sourceIndex >= _sources.Length)
            _sourceIndex = 0;

        Debug.WriteLine(string.Format("Playing {0}", _sources[_sourceIndex]));

        this.x_MediaElement.Source = new Uri(_sources[_sourceIndex]);
        this.x_MediaElement.Play();

    }

    private int _sourceIndex = -1;

    private string[] _sources = new string[] {
        //SOURCE GO HERE
    };

    void x_MediaElement_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        MoveNext();
        e.Handled = true;
    }
}
Run Code Online (Sandbox Code Playgroud)

Ert*_*maa 5

我会对你说实话。MediaElement 的错误多得用手指头都数不过来。从那开始,mediaElement 在播放 20 个视频后爆炸(不再有 MediaEnded 事件,它会崩溃或类似的情况)。当然还有表演。它与垂直同步不同步。所以视频实际上可能看起来很滞后。

我建议您研究 DirectShow 技术(本质上是 WPF 所基于的技术,但您可以切换渲染器以避免延迟)。考虑到您不会开发任何专业应用程序,我想 MediaElement 会很好。

但是,MediaElement 是最简单的选项,如果它适合您,请继续使用它。至于你的问题,我认为可能的解决方案有以下几种:

  • 有两个 MediaElement 并在它们之间切换。如果一个视频结束,则在另一个 MediaElement 中开始另一个 vid,只要在第二个 mediaElement 上播放第一帧,隐藏第一个 mediaElement,反之亦然。您可以轮询位置,也可以轮询 MediaStarted 事件。这样,闪烁几乎不可能被注意到。
  • 如果您想要流畅的视频播放而没有任何闪烁,GMFPlay 是您的最佳选择。你可以检查一下。虽然它不是 MediaElement。但它可以同时播放视频,没有任何闪烁。
  • 截取最后一帧的屏幕截图(您可以使用 WPF 截取屏幕截图)并在 MediaElement 秘密加载时将其显示为图像。