Windows Media Player w Windows Form [C#] Problem (Pętla, playlista)

0

Witam, na wstępie zacznę, od tego, że jestem nowy na forum i mam nadzieję, że zrozumiecie o co mi chodzi.
Aktualnie pracuję nad Odtwarzaczem muzyki z różnymi dość standardowymi funkcjami, wszystko prawie gotowe, zrobiłem pseudo playlisty wg. własnego pomysłu i zacząłem robić pętle dla utworów. Pętla dla pojedynczej muzyki, wyszła i to prosto. Natomiast problem zaczął się w pętli dla playlist, którą robię już cały dzień i ciągle nie wiem jak to naprawić.

CHYBA WAŻNE:
Zauważyłem, że po zamieszczeniu "MessageBox.Show("");" program działa jak należy, ale oczywiście nie chcę używać tej funkcji.

PS. Wiem, że kod nie jest zbyt estetyczny, ale to dlatego, że dużo mieszałem, gdy pracowałem nad pętlą.

KOD:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Media;
using WMPLib;
using Microsoft.Win32;
using System.Threading;

namespace MusicPlayer
{
    public partial class Form1 : Form
    {
        public static string FileName;
        public static bool first = true;

        public Form1()
        {
            InitializeComponent();
        }

        private void player_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
        {
            if ((e.newState == 1) && (turnONToolStripMenuItem.Checked) && (!fORPLAYLISTToolStripMenuItem.Checked))
            {
                axWindowsMediaPlayer1.Ctlcontrols.play();
                return;
            }
        }

        private void player_PlayStateChange1(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
        {
            if ((e.newState == 1) && (turnOFFToolStripMenuItem.Checked))
            {
                axWindowsMediaPlayer1.Ctlcontrols.stop();
                return;
            }
        }

        private void player_PlayStateChange2(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
        {
            if ((fORPLAYLISTToolStripMenuItem.Checked) && (e.newState == 1))
            {
                //double musicduration = axWindowsMediaPlayer1.currentMedia.duration;
                while (axWindowsMediaPlayer1.Ctlcontrols.currentPosition == 0)
                {
                    try
                    {
                        listBox1.SelectedItem = listBox1.Items[listBox1.SelectedIndex + 1];
                        axWindowsMediaPlayer1.Ctlcontrols.play();
                    }

                    catch (ArgumentOutOfRangeException)
                    {
                        listBox1.SelectedItem = listBox1.Items[0];
                    }

                    textBox1.Text = listBox1.SelectedItem.ToString();

                    if (e.newState == 1)
                    {
                        axWindowsMediaPlayer1.Ctlcontrols.currentPosition = 1;
                        Newurl();
//Message box, o którym wspomniałem
                        MessageBox.Show("");
                        
                    }
                }

                //return;
            }
        }

        private void Downloadbutton_Click(object sender, EventArgs e)
        {
            Process.Start("chrome.exe", "https://www.youtube.com/");
            Process.Start("chrome.exe", "https://www.onlinevideoconverter.com/pl/mp3-converter");
        }

        private void Addbutton_Click(object sender, EventArgs e)
        {
            Browse browse = new Browse();
            browse.Show();
        }

        private void Removebutton_Click(object sender, EventArgs e)
        {
            try
            {
                File.Delete(@"music\" + listBox1.SelectedItem);
                listBox1.Items.Remove(listBox1.SelectedItem);
            }

            catch (UnauthorizedAccessException)
            {

            }

        }

        private void Folderbutton_Click(object sender, EventArgs e)
        {
            try
            {
                Process.Start("explorer.exe", @"music\");
            }

            catch (DirectoryNotFoundException)
            {

            }
        }

        private void AxWindowsMediaPlayer1_Enter(object sender, EventArgs e)
        {
            try
            {
                axWindowsMediaPlayer1.URL = @"music\" + listBox1.SelectedItem.ToString();
                axWindowsMediaPlayer1.PlayStateChange += new AxWMPLib._WMPOCXEvents_PlayStateChangeEventHandler(player_PlayStateChange);
                axWindowsMediaPlayer1.PlayStateChange += new AxWMPLib._WMPOCXEvents_PlayStateChangeEventHandler(player_PlayStateChange1);
                axWindowsMediaPlayer1.PlayStateChange += new AxWMPLib._WMPOCXEvents_PlayStateChangeEventHandler(player_PlayStateChange2);
            }


            catch (NullReferenceException)
            {

            }

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            ChoosePlaylistPanel.Visible = false;

            if (!Directory.Exists("music"))
            {
                Directory.CreateDirectory(@"music");
            }

            try
            {
                string[] files = Directory.GetDirectories(@"music\");

                foreach (string s in files)
                {
                    listBox2.Items.Add(Path.GetFileName(s));
                    listBox2.Sorted = true;
                }
            }

            catch (FileNotFoundException)
            {

            }

            try
            {
                string[] files = Directory.GetFiles(@"music\");

                foreach (string s in files)
                {
                    listBox1.Items.Add(Path.GetFileName(s));
                    listBox1.Sorted = true;
                }
            }

            catch (FileNotFoundException)
            {

            }

            listBox1.SelectedItem = listBox1.Items[0];
            textBox1.Text = listBox1.SelectedItem.ToString();
        }

        private void Newurl()
        {
            axWindowsMediaPlayer1.URL = @"music\" + listBox1.SelectedItem.ToString();
            return;
        }

        private void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
        private void MenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }
        private void SettingsToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            Playlist playlist = new Playlist();
            playlist.Show();
        }

        private void AboutProgramToolStripMenuItem_Click(object sender, EventArgs e)
        {
            MessageBox.Show("This program was made by Lodomir, all Rights Reserved!", "Info");
        }

        private void TurnONToolStripMenuItem_Click(object sender, EventArgs e)
        {
            turnONToolStripMenuItem.Checked = true;
            turnONToolStripMenuItem.CheckState = CheckState.Checked;

            turnOFFToolStripMenuItem.Checked = false;
            turnOFFToolStripMenuItem.CheckState = CheckState.Unchecked;

            fORPLAYLISTToolStripMenuItem.Checked = false;
            fORPLAYLISTToolStripMenuItem.CheckState = CheckState.Unchecked;
        }

        private void TurnOFFToolStripMenuItem_Click(object sender, EventArgs e)
        {
            turnOFFToolStripMenuItem.Checked = true;
            turnOFFToolStripMenuItem.CheckState = CheckState.Checked;

            turnONToolStripMenuItem.Checked = false;
            turnONToolStripMenuItem.CheckState = CheckState.Unchecked;

            fORPLAYLISTToolStripMenuItem.Checked = false;
            fORPLAYLISTToolStripMenuItem.CheckState = CheckState.Unchecked;
        }

        private void ChoosePlaylistToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ChoosePlaylistPanel.Visible = true;
            MainPanel.Visible = false;
        }






        private void FORPLAYLISTToolStripMenuItem_Click(object sender, EventArgs e)
        {
            turnOFFToolStripMenuItem.Checked = false;
            turnOFFToolStripMenuItem.CheckState = CheckState.Unchecked;

            turnONToolStripMenuItem.Checked = false;
            turnONToolStripMenuItem.CheckState = CheckState.Unchecked;
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            try
            {
                string[] files = Directory.GetFiles(@"music\" + listBox2.SelectedItem.ToString() + @"\");
                listBox1.Items.Clear();

                foreach (string s in files)
                {
                    listBox1.BeginUpdate();
                    listBox1.Items.Add(Path.GetFileName(s));
                    listBox1.Sorted = true;
                    listBox1.EndUpdate();
                    listBox1.Update();
                }

            }

            catch (NullReferenceException)
            {

            }

            catch (DirectoryNotFoundException)
            {
                MessageBox.Show("Nie ma takiej ścieżki!");
                listBox2.Items.Remove(listBox2.SelectedItem);
            }

            ChoosePlaylistPanel.Visible = false;
            MainPanel.Visible = true;
        }

        private void AllMusicToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                string[] files = Directory.GetFiles(@"music\");
                listBox1.Items.Clear();

                foreach (string s in files)
                {
                    listBox1.Items.Add(Path.GetFileName(s));
                    listBox1.Sorted = true;
                    listBox1.Refresh();
                }
                ChoosePlaylistPanel.Visible = false;
            }

            catch (NullReferenceException)
            {
                MessageBox.Show("Wybierz Playlistę, lub zamknij opcję!");
                ChoosePlaylistPanel.Visible = false;
            }
        }

        private void AddMusicToPlaylistToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AddRemoveMusicToPlaylist option = new AddRemoveMusicToPlaylist();
            option.Show();
        }

        private void ExitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }

        private void ImportPlaylistToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Browse browse = new Browse();
            Browse.folder = true;
            browse.Show();
        }
    }
}```c#
0

MessageBox czeka aż klikniesz 'ok', a spróbuj wrzucić zamiast niego:
"System.Threading.Thread.Sleep(1000);"
jeśli będzie śmigać, to znaczy że coś idzie równolegle, i taka 'przerwa' dobrze robi - można później zmniejszyć czas. Nie jest to ładne rozwiązanie, ładniej byłoby znaleźć 'na co musimy poczekać i do kiedy', ale warto najpierw w ten sposób sprawdzić imo.

0
Boski napisał(a):

MessageBox czeka aż klikniesz 'ok', a spróbuj wrzucić zamiast niego:
"System.Threading.Thread.Sleep(1000);"
jeśli będzie śmigać, to znaczy że coś idzie równolegle, i taka 'przerwa' dobrze robi - można później zmniejszyć czas. Nie jest to ładne rozwiązanie, ładniej byłoby znaleźć 'na co musimy poczekać i do kiedy', ale warto najpierw w ten sposób sprawdzić imo.

Kiedy wstawiam cokolwiek za tego Message Box'a dzieją się naprawdę dziwne rzeczy, na przykład gdy wstawiam Thread.Sleep(1000) i się skończy pierwsza muzyka to po kolei w listboxie przestawia zaznaczenie do ostatniej opcji i zatrzymuje odtwarzanie.

Jak ktoś by chciał pomóc i przerobić kod to zachęcam ;)

Nie mam pojęcia co jest z tym nie tak, w ogóle cały czas są problemy z tym Windows Media Playerem.
Zastanawiam się czy nie zamienić tego na Naudio, ale w ogóle jeszcze nie znam go i ogarnianie wszystkich metod, a następnie podmienienie kodu zajmie mi dużo czasu, dlatego próbuję ten kod naprawić.

Można by ewentualnie trochę "oszukać" i spróbować usunąć MessageBox'a po jego pojawieniu się tak, aby nie przeszkadzało to użytkownikowi i wtedy wszystko by działało, ale taki zabieg z pewnością nie był by najprostszy, jeżeli w ogóle możliwy, bo raczej nie można przechwycić okna Box'a, ale nie wiem.

0

Generalnie głównymi problemami podczas prób naprawiania tego kodu jest przestawianie się zaznaczenie w ListBox, lub zatrzymywanie się muzyki na samym początku, oczywiście niechciany efekt. Może z url jest jakiś problem, albo playstate ma efekty uboczne, które tu gdzieś występują, nie mam pojęcia. Lepiej to próbować naprawić, czy zamienić na Naudio? Cholera sam nie wiem.

0

Ja bym nic nie zamieniał. Musi się dać zrobić w ten sposób. Mógłbym zerknąć na kod, ale szczerze to jakbyś wrzucił cały projekt - żeby ręcznie nie podpinać tych eventów i nie wrzucać kontrolek.
Zastanawia mnie czysto teoretycznie te miejsce jeszcze:

                while (axWindowsMediaPlayer1.Ctlcontrols.currentPosition == 0)
                {
                    try
                    {
                        listBox1.SelectedItem = listBox1.Items[listBox1.SelectedIndex + 1];
                        axWindowsMediaPlayer1.Ctlcontrols.play();
                    }

czy jak ten kod zostanie wykonany, to czy dalej nie utkwi we while, i nie będzie właśnie tego przelatywania po liście?
konkretnie te axWindowsMediaPlayer1.Ctlcontrols.currentPosition == 0 mnie zastanawia, czy na pewno dobry warunek

i jeszcze coś takiego:
https://www.codeguru.com/csharp/csharp/cs_controls/tutorials/article.php/c16597/Tip-C--Detect-the-End-of-Media--axWindowsMediaPlayer.htm
tutaj jest opisany stan 8 = Media Ended - może on będzie lepszy?

0
Boski napisał(a):

Ja bym nic nie zamieniał. Musi się dać zrobić w ten sposób. Mógłbym zerknąć na kod, ale szczerze to jakbyś wrzucił cały projekt - żeby ręcznie nie podpinać tych eventów i nie wrzucać kontrolek.
Zastanawia mnie czysto teoretycznie te miejsce jeszcze:

                while (axWindowsMediaPlayer1.Ctlcontrols.currentPosition == 0)
                {
                    try
                    {
                        listBox1.SelectedItem = listBox1.Items[listBox1.SelectedIndex + 1];
                        axWindowsMediaPlayer1.Ctlcontrols.play();
                    }

czy jak ten kod zostanie wykonany, to czy dalej nie utkwi we while, i nie będzie właśnie tego przelatywania po liście?
konkretnie te axWindowsMediaPlayer1.Ctlcontrols.currentPosition == 0 mnie zastanawia, czy na pewno dobry warunek

i jeszcze coś takiego:
https://www.codeguru.com/csharp/csharp/cs_controls/tutorials/article.php/c16597/Tip-C--Detect-the-End-of-Media--axWindowsMediaPlayer.htm
tutaj jest opisany stan 8 = Media Ended - może on będzie lepszy?

Wiesz co, ja już sam nie wiem, w sensie przed tym while miałem if, playstate w wersji 8 też próbowałem, no generalnie to już to poprzerabiałem na tyle sposobów, że nie wiem co dalej zrobić. Będę pewnie jeszcze coś kombinował, wrzuciłem aktualny projekt na GitHuba, to może uda się Ci jeżeli będziesz chciał przerobić ten kod, albo znaleźć ten błąd, ja dzisiaj i tak nie mogę nad tym popracować, bo za parę godzin mam samolot i niezbyt mam ochotę się z tym teraz użerać.

Link: https://github.com/R3GG3/MusicPlayer

1

Po drobnych zmianach śmiga, dopóki nie klikam na liście, a przesuwam tylko na pasku pozycji:
https://4programmers.net/Pastebin/11249

Zakomentowałem tymczasowo 2 wpięcia:
axWindowsMediaPlayer1.PlayStateChange += new AxWMPLib._WMPOCXEvents_PlayStateChangeEventHandler(player_PlayStateChange)

Zakomentowałem nietymczasowo kilka linijek w player_PlayStateChange2 (głównie duplikacja kodu z tym w Newurl)

Na górze player_PlayStateChange2 dałem sprawdzanie z newState == 10 <- to się spełnia, jak nowy dźwięk jest 'gotowy do odtwarzania' - wywoływałeś play zanim był gotowy, skutkiem czego nic się nie działo.

Na pewno przyda się sporo refaktoryzacji - zanim przejdziesz do dalszych fixów, polecam:

  • zrobić enum LoopState/LoopType, trzymać zmienną tego typu, i tylko zmieniać przy kliknięciach
  • trzymać info o selectedTrack, nie robić tego na bazie listboxa -> niech listbox tylko reaguje na zmiany
    i przesyła kliknięcia
  • zabezpieczyć te wybieranie ścieżek przed pustym stringiem, i dodać jakieś "anuluj"
0

Mi dalej nie działa, pojawił się nowy nieobsługiwany wyjątek.screenshot-20190621200517.pngscreenshot-20190621200602.png
A jak próbowałem to naprawić to efekt ten sam jak przed twoją edycją, czyli przenosi, ale nie odtwarza.

0
Boski napisał(a):

Po drobnych zmianach śmiga, dopóki nie klikam na liście, a przesuwam tylko na pasku pozycji:
https://4programmers.net/Pastebin/11249

Zakomentowałem tymczasowo 2 wpięcia:
axWindowsMediaPlayer1.PlayStateChange += new AxWMPLib._WMPOCXEvents_PlayStateChangeEventHandler(player_PlayStateChange)

Zakomentowałem nietymczasowo kilka linijek w player_PlayStateChange2 (głównie duplikacja kodu z tym w Newurl)

Na górze player_PlayStateChange2 dałem sprawdzanie z newState == 10 <- to się spełnia, jak nowy dźwięk jest 'gotowy do odtwarzania' - wywoływałeś play zanim był gotowy, skutkiem czego nic się nie działo.

Na pewno przyda się sporo refaktoryzacji - zanim przejdziesz do dalszych fixów, polecam:

  • zrobić enum LoopState/LoopType, trzymać zmienną tego typu, i tylko zmieniać przy kliknięciach
  • trzymać info o selectedTrack, nie robić tego na bazie listboxa -> niech listbox tylko reaguje na zmiany
    i przesyła kliknięcia
  • zabezpieczyć te wybieranie ścieżek przed pustym stringiem, i dodać jakieś "anuluj"

Dobra, już ogarnąłem, nie działało przed chwilą, bo za szybkie tempo, było narzucone i już wszystkie pętle śmigają. Do skończenia mojego projektu zostało ulepszenie przycisku download, przy użyciu html w myśl przechwycania atrybutów i wpisywania tam wartości etc. Chcę skorzystać z DotNetBrowser, co o tym sądzisz?

0

A i dzięki wielkie za tą pomoc, bo błąd choć banalny w mojej ocenie to jednak denerwował mnie przez parę dni i w końcu działa, dzięki tobie! :)

0

Cieszę się bardzo : ) Co do DotNetBrowser nie wypowiem się - nie używałem, ani też za bardzo tematu pobierania plików z serwisów nie ogarniałem.

1 użytkowników online, w tym zalogowanych: 0, gości: 1