在没有闪烁的情况下更改MediaElement源

时间:2012-09-02 06:23:22

标签: 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;
    }
}

1 个答案:

答案 0 :(得分:4)

我会诚实地对待你。 MediaElement有比手指更多的错误。从此开始,mediaElement在播放20个视频后爆炸(不再有MediaEnded事件,它会崩溃或类似的事情)。而且当然是表现。它与垂直同步不同步。所以视频可能看起来有点滞后。

我建议你研究DirectShow技术(基本上是WPF的基础,但你可以切换渲染器,这将避免滞后)。考虑到你不会开发任何专业应用程序,我猜MediaElement会很好。

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

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