WPF MediaPlayer po dohrátí songu se nevolá eventa MediaEnded

zemla

Dobrý den, snažím se vytvořit JukeBox a jelikož se mi nedařilo zachytit eventu MediaEnded po dohrátí písničky, vytáhnul jsem kód do konzolové aplikace, kde se to snad bude ladit líp. Kód je:

Kód: [Vybrat]
using System;
using System.Windows.Media;

namespace MediaPlayerTest
{
    class Program
    {
        static void Main(string[] args)
        {
            new Program().Run();

            Console.ReadLine();
        }

        public void Run()
        {
            var player = new MediaPlayer();
            player.MediaEnded += MediaPlayer_MediaEnded;

            player.Open(new Uri(@"d:\Jukebox\mp3\ROTTROVA MARIE - Reka lasky (CZ 2003)\03 ROTTROVA MARIE - Reka lasky.mp3"));
            player.Play();
        }

        private void MediaPlayer_MediaEnded(object sender, EventArgs e)
        {
            var x = 1;
        }
    }
}

Píseň se přehraje až do konce, ale eventa se neraisne.

Napadá někoho z vás pls čím by to mohlo být? V eventě mám breakpoint.

Díky


Re:WPF MediaPlayer po dohrátí songu se nevolá eventa MediaEnded
« Odpověď #1 kdy: 25. 02. 2019, 10:00:15 »
No máš tam pár chýb...

Poprvé, nechápem prečo voláš:

Kód: [Vybrat]
new Program().Run();
pravdepodobne stačí volať len Run();

Zadruhé, objekt MediaPlayer vytváraš v metóde Run, akurát akonáhle sa metóda Run dokončí, tak tento objekt zanikne => musíš inicializáciu objektu vyňať nad metódu Run, takže vo výsledku bude tvoj kód vyzerať asi takto:

Kód: [Vybrat]
using System;
using System.Windows.Media;

namespace MediaPlayerTest
{
    class Program
    {
        // Zadefinovanie premenných
        MediaPlayer _player;

        static void Main(string[] args)
        {
            // Inicializácia mediaplayeru:
            _player = new MediaPlayer();
            _player.MediaEnded += MediaPlayer_MediaEnded;

            Run();

            Console.ReadLine();
        }

        public void Run()
        {         
            _player.Open(new Uri(@"d:\Jukebox\mp3\ROTTROVA MARIE - Reka lasky (CZ 2003)\03 ROTTROVA MARIE - Reka lasky.mp3"));
            _player.Play();
        }

        private void MediaPlayer_MediaEnded(object sender, EventArgs e)
        {
            var x = 1;
        }
    }
}

K tomu by sa mal zvážiť, že metóda _player.Play je pravdepodobne blokujúca a mala by sa vykonávať v inom vlákne aby si neblokoval UI thread.

zemla

Re:WPF MediaPlayer po dohrátí songu se nevolá eventa MediaEnded
« Odpověď #2 kdy: 28. 02. 2019, 15:18:59 »
Kdepak, problém bude jinde a Play je asynchronní.
Raději to postnu celé, protože výtah byl matoucí:

Kód: [Vybrat]
using System;
using System.Linq;
using System.Windows.Media;
using System.Threading;
using System.Collections.Generic;
using JukeBox.Models;

namespace JukeBox.Helpers
{
    public class BackgroundPlayer
    {
        private static List<SongModel> queue = new List<SongModel>();

        public static SongModel _currentSong;

        private bool threadStarted = false;
        private Thread workerThread = new Thread(new ThreadStart(ThreadMethod));

        private static MediaPlayer mediaPlayer;

        private static AutoResetEvent autoResetEvent = new AutoResetEvent(false);

        public int RandomTime { get; set; } = 1;
        public Action<string> SongFinished;
        public Action RandomTimeReached;

        public BackgroundPlayer()
        {
            workerThread.IsBackground = true;
        }

        public void EnqueueSong(SongModel songModel)
        {
            queue.Add(songModel);

            if (!threadStarted)
            {
                threadStarted = true;

                workerThread.Start();
            }
        }

        public static void ThreadMethod()
        {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.MediaEnded += MediaPlayer_MediaEnded;

            while (true)
            {
                if (queue.Count > 0)
                {
                    var _currentSong = queue.First();

                    mediaPlayer.Open(new Uri(_currentSong.SongFullPath));
                   

                    mediaPlayer.Play();

                    autoResetEvent.WaitOne();
                }

                Thread.Sleep(1000);
            }
        }

        private static void MediaPlayer_MediaEnded(object sender, EventArgs e)
        {
            queue.Remove(_currentSong);

            autoResetEvent.Set();

            //Dispatcher.CurrentDispatcher.Invoke(new Action<string>((s) => SongFinished(_currentSong.SongName)));
        }
    }
}


Díky za jakýkoliv nápad.