2
votes

I have a simple video player that plays a series of videos using the WPF MediaElement. The videos together form one continuous film that move around a still image. At the end of each video the movement freezes on the final frame of the currently playing video. When I press a button the next video plays, which continues the movement around the still image. It's an application I'm going to use to give a speech. Effectively I've got a series of videos for which the last frame of each video is the same as the first frame of the next video.

I'm using a WPF MediaElement and changing the Source property when the user clicks on the mouse.

The problem that I have is that, when I change the Source property, the MediaElement becomes transparent while the next video is loaded. This means there is a flicker between videos. Is there any way of preventing this flicker? What other strategies could I use?

Here's some code:

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

1 Answers

4
votes

I am gonna be honest with you. MediaElement has more bugs than you can count with fingers. Starting from that the mediaElement blows up after playing 20 videos(no more MediaEnded event, it will crash or something like that). And ofcourse the performance. Its not synchronized with vertical sync. So the video might actually seem laggy.

I advise you to look into DirectShow technology(essentially what WPF is based on, but you can switch renderer which will avoid lag). COnsidering that you will not be developing any professional application, I guess MediaElement will be fine.

However, MediaElement is the simplest option, and if it works for you, then keep working with it. As for your problem, I think there are few possible solutions:

  • Have two MediaElements and switch between them. If one video ends, start another vid in another MediaElement, as long as you play first frame on second mediaElement, hide the first mediaElement, and vice versa. You can poll for position, and maybe MediaStarted event. This way the flicker will be almost impossible to notice.
  • If you want fluent video playing without ANY flicker at all, there is GMFPlay. You can check it out. Though it's not MediaElement. But it can play videos simultaneously without any flicker.
  • Take screenshot of the last frame(you can take screenshots with WPF) and show it as Image while MediaElement is secretly loading.