F.Bruno
F.Bruno

Reputation: 143

MediaElement Goes black after a while

Created a program that passes a video, in a list, every 10 seconds to mediaElement, the problem here is, after a while like 1h or maybe 2h the screen of the mediaElement goes black. I've seen it happen right in front of me, and immediately checked for memory leaks, but there where non. Is this a recurring problem with MediaElement? Also, I did the program such as, if I need to play a video, the mediaElement is created and when no longer is needed, its deleted.

[EDIT]

    namespace VideoPlayer
{
    public

 partial class MainWindow : Window
    {
    #region Global var

    private const string VIDEO_EXTENSION = "*.mp4";
    private const string URL_NEXT_PLAYLIST = "http://tomiservice.net/mop/json/?json[device]=031232bc880aab7fc6687fd9377d8756&lang=pt&json[f]=get_next_playlist&json[typologie]=1";
    private const string URL_PLAYLIST = "http://tomiservice.net/mop/json/?json[device]=031232bc880aab7fc6687fd9377d8756&lang=pt&json[f]=get_next_playlist&json[typologie]=1&json[date_interval]=";
    private const string CONTENT_TYPE = "application/json";

    private int randIndex = 0, seconds = 0;
    private string vidName = null;
    private static string DIRECTORY = System.Configuration.ConfigurationManager.AppSettings["Directory"];

    private DirectoryInfo directoryInfo = new DirectoryInfo(DIRECTORY);
    private DispatcherTimer videoPlaytimVerification = new System.Windows.Threading.DispatcherTimer();


    private JsonParser json = new JsonParser();
    private List<VideoEntity.Video> videoPlayList = new List<VideoEntity.Video>();
    private List<VideoEntity.VideoTails> videoPlayListFill = new List<VideoEntity.VideoTails>();

    MediaElement me = new MediaElement();



    #endregion

    public MainWindow()
    {
        InitializeComponent();

        [EDIT]
        me.MediaEnded += MediaEnded;

        seconds = (int)DateTime.Now.TimeOfDay.TotalSeconds;

        LoadFillVideo();

        videoPlaytimVerification.Tick += new EventHandler(videoPlaytimVerification_Tick);
        videoPlaytimVerification.Interval = new TimeSpan(0, 0, 1);
        videoPlaytimVerification.Start();
    }

    #region METHODS

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/

    private bool SearchVideo(string vidName)
    {
        foreach (var file in directoryInfo.GetFiles())
        {
            if (vidName == file.ToString())
            {
                return true;
            }
        }
        return false;
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/

    void createMediaElement(string videoSource)
    {
        me.LoadedBehavior = MediaState.Manual;
        me.Source = new Uri(DIRECTORY + videoSource, UriKind.Absolute);
        me.Play();
        mediaPlayerGrid.Children.Add(me);
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/


    private void LoadFillVideo()
    {
        Random rand = new Random(DateTime.Now.ToString().GetHashCode());
        randIndex = rand.Next(0, videoPlayListFill.Count);
        try
        {
            mediaPlayerGrid.Children.Remove(me);
            createMediaElement(videoPlayListFill[randIndex].Filename);
        }
        catch { }
    }


    /*###############################################*/
    /*###############################################*/
    /*###############################################*/
   [EDIT]
   private void MediaEnded(Object sender, RoutedEventArgs e)
    {
        LoadFillVideo();
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/
    #endregion

    #region EVENTS

    private void videoPlaytimVerification_Tick(object sender, EventArgs e)
    {
        foreach (VideoEntity.Video vid in videoPlayList)
        {
            if (vid.Playtime == seconds)
            {
                vidName = vid.Filename;

                try
                {
                    mediaPlayerGrid.Children.Remove(me);

                    //if the video exists, the switching happens here!!
                    createMediaElement(vidName);
                }
                catch { }

                if (!SearchVideo(vidName))
                {
                    //if the video does not exist, the fill video switching happens here!!
                    LoadFillVideo();
                    seconds++;
                    return;
                }
            }
        }


        if ((seconds >= videoPlayList[119].Playtime))
            GetPlayList(1);

        if (seconds >= 89990)
            seconds = 3599;

        seconds++;
    }
    #endregion
}

}

[EDIT][EDIT][EDIT]

OK so I've been doing some research and my code looks like this now

 namespace VideoPlayer
{
    public partial class MainWindow : Window
{
    #region Global var

    private const string VIDEO_EXTENSION = "*.mp4";
    private const string URL_NEXT_PLAYLIST = "http://tomiservice.net/mop/json/?json[device]=031232bc880aab7fc6687fd9377d8756&lang=pt&json[f]=get_next_playlist&json[typologie]=1";
    private const string URL_PLAYLIST = "http://tomiservice.net/mop/json/?json[device]=031232bc880aab7fc6687fd9377d8756&lang=pt&json[f]=get_next_playlist&json[typologie]=1&json[date_interval]=";
    private const string CONTENT_TYPE = "application/json";

    private int randIndex = 0, seconds = 0;
    private static string DIRECTORY = System.Configuration.ConfigurationManager.AppSettings["Directory"];
    private enum get { CurrentPlaylist = 0, NextPlaylist = 1 };

    private DirectoryInfo directoryInfo = new DirectoryInfo(DIRECTORY);
    private DispatcherTimer videoPlaytimVerification = new System.Windows.Threading.DispatcherTimer();

    private JsonParser json = new JsonParser();
    private List<VideoEntity.Video> videoPlayList = new List<VideoEntity.Video>();
    private List<VideoEntity.VideoTails> videoPlayListFill = new List<VideoEntity.VideoTails>();

    MediaElement me;

    #endregion

    public MainWindow()
    {
        InitializeComponent();


        me = null;
        seconds = (int)DateTime.Now.TimeOfDay.TotalSeconds;

        GetPlayList((int)get.CurrentPlaylist);

        LoadFillVideo();

        videoPlaytimVerification.Tick += new EventHandler(videoPlaytimVerification_Tick);
        videoPlaytimVerification.Interval = new TimeSpan(0, 0, 1);
        videoPlaytimVerification.Start();
    }

    #region METHODS

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/

    private bool SearchVideo(string vidName)
    {
        foreach (var file in directoryInfo.GetFiles())
        {
            if (vidName == file.ToString())
            {
                return true;
            }
        }
        return false;
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/

    void createMediaElement(string videoSource)
    {
        if (me != null )
        {
            me.Stop();
            mediaPlayerGrid.Children.Remove(me);
        }
        me = new MediaElement();
        mediaPlayerGrid.Children.Add(me);

        me.LoadedBehavior = MediaState.Manual;
        me.Source = new Uri(DIRECTORY + videoSource, UriKind.Absolute);
        me.Play();
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/

    private void GetPlayList(int urlCode)
    {
        WebRequest request;

        switch (urlCode)
        {
            case (int)get.CurrentPlaylist:
                request = WebRequest.Create(URL_PLAYLIST + seconds.ToString());
                RequestPlayList(request);

                break;
            case (int)get.NextPlaylist:
                request = WebRequest.Create(URL_NEXT_PLAYLIST);
                RequestPlayList(request);

                break;
        }
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/

    private void RequestPlayList(WebRequest request)
    {
        videoPlayList.Clear();

        request.ContentType = CONTENT_TYPE;
        string jsonSample;
        try
        {
            var response = (HttpWebResponse)request.GetResponse();

            using (var sr = new StreamReader(response.GetResponseStream()))
            {
                jsonSample = sr.ReadToEnd();
            }
            json.VideoSearch(jsonSample, ref videoPlayList, ref videoPlayListFill);
        }
        catch { }
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/

    private void LoadFillVideo()
    {
        Random rand = new Random(DateTime.Now.ToString().GetHashCode());
        randIndex = rand.Next(0, videoPlayListFill.Count);

        createMediaElement(videoPlayListFill[randIndex].Filename);
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/

    private void MediaEnded(Object sender, RoutedEventArgs e)
    {
        LoadFillVideo();
    }

    /*###############################################*/
    /*###############################################*/
    /*###############################################*/
    #endregion

    #region EVENTS

    private void videoPlaytimVerification_Tick(object sender, EventArgs e)
    {
        seconds = (int)DateTime.Now.TimeOfDay.TotalSeconds;

        if (seconds <= 3590)
            seconds = 86400 + seconds;

        foreach (VideoEntity.Video vid in videoPlayList)
        {
             if (vid.Playtime == seconds)
             {
                if (!SearchVideo(vid.Filename))
                {
                    LoadFillVideo();
                    seconds++;
                }
                else
                    createMediaElement(vid.Filename);
            }
        }

        if ((seconds >= videoPlayList[119].Playtime))
            GetPlayList((int)get.NextPlaylist);
    }
    #endregion
}
}

I've tried changing the background color of my grid to white to see if I'm really seeing a black screen or just my grid, sure enough it was my grid, and the problem here is changing the video source multiple times in quick succession, I tried with a simple code where it changes my video sources every 1 second and after 30min to 1h the mediaelement goes down. Why does the mediaElement stop after changing the source multiple times?

Upvotes: 1

Views: 1296

Answers (1)

BradleyDotNET
BradleyDotNET

Reputation: 61339

None of this would explain for sure why you are showing "black" after a while. However, the fact that you call this repeatedly is an issue:

private void VideoEnd(MediaElement me, string vidName)
{
    me.MediaEnded += (a, b) =>
   {
       Random rand = new Random(DateTime.Now.ToString().GetHashCode());
       randIndex = rand.Next(0, videoPlayListFill.Count);
       mediaPlayerGrid.Children.Remove(me);
       createMediaElement(videoPlayListFill[randIndex].Filename);
   };
}

You are registering a new lambda expression (potentially creating closures in the process) every time you load a video. The previous event handlers are never unregistered since you never do so explicitly and never re-create the MediaElement.

Also, adding and removing the MediaElement from the visual tree is a bit odd. I would try only setting the event handler once. If the behavior still occurs, try leaving the element in the visual tree (just do Visibility = Visibility.Collapsed if you need to hide it).

Finally, consider moving the code doing the playlist retrieval into your model. It may not fix your problem right away, but good design can help avoid these issues in the future.

Upvotes: 2

Related Questions