Сделайте что-нибудь после окончания музыки с помощью SoundPlayer

Мне нужно что-то сделать после завершения моего музыкального файла с асинхронной загрузкой. Допустим, я хочу, чтобы программа вышла или что-то в этом роде. Теперь, как я могу сделать это после окончания музыки?

    private void button1_Click(object sender, EventArgs e)
    {
        player.SoundLocation = @"Music\" + FileList[0];
        player.LoadAsync();
    }

    private void Player_LoadCompleted(object sender, AsyncCompletedEventArgs e)
    {
        if (player.IsLoadCompleted)
        {
            player.PlaySync();
        }
    }

person Tom Lenc    schedule 03.12.2015    source источник
comment
какого типа переменная player? SoundPlayer, MediaPlayer,.. что?   -  person Fᴀʀʜᴀɴ Aɴᴀᴍ    schedule 03.12.2015
comment
О, извините за это .. в названии я имел в виду SoundPlayer, а не PlaySound ...   -  person Tom Lenc    schedule 03.12.2015
comment
@TomLenc Я написал кое-что в другом ответе, который может вам помочь, в нем есть событие, на которое вы можете подписаться, когда звук закончится: stackoverflow.com/questions/29905192/   -  person Ron Beyer    schedule 03.12.2015
comment
stackoverflow.com/questions/27392396/   -  person Fᴀʀʜᴀɴ Aɴᴀᴍ    schedule 03.12.2015
comment
@ FᴀʀʜᴀɴAɴᴀᴍ Я просматривал эту страницу раньше, но совсем не понял правильного ответа   -  person Tom Lenc    schedule 03.12.2015


Ответы (2)


Поскольку метод PlaySync является синхронным, он не вернется, пока файл не будет воспроизведен до конца. Итак, вы можете просто сделать это следующим образом:

if (player.IsLoadCompleted)
{
    player.PlaySync();
    DoSomethingAfterMusicIsDone();
}

ОБНОВЛЕНИЕ:

LoadAsync работает синхронно, если SoundLocation указывает на файл в файловой системе. Это означает, что вы должны вызывать LoadAsync в другом потоке, если не хотите замораживать поток пользовательского интерфейса. Вот пример:

Task.Run(() => player.LoadAsync());
person Yacoub Massad    schedule 03.12.2015
comment
Если я правильно понял... асинхронная загрузка заставляет его работать в другом потоке, поэтому окно не зависает... это означает... что это похоже на thread.sleep, который остается там в течение указанного времени... это что-то вроде этого? - person Tom Lenc; 03.12.2015
comment
@TomLenc, я не уверен, что понимаю твой вопрос. async означает, что вы не ждете, пока что-то завершится. - person Yacoub Massad; 03.12.2015

Вместо этого используйте MediaPlayer:

mediaPlayer = new MediaPlayer();
mediaPlayer.MediaEnded += delegate { MessageBox.Show("Media Ended"); };
mediaPlayer.Open(new Uri(@"C:\myfile.mp3"));
mediaPlayer.Play();

Звучит хорошо в теории. Однако, по правде говоря, я не мог запустить MediaEnded Event. Таким образом, мне пришлось опросить конец MediaEvent следующим образом:

while(true)
{
    System.Threading.Thread.Sleep(1000);
    string pos = "unknown";
    string dur = "unknown";

    try 
    {
        pos = mediaplayer1.Position.Ticks.ToString();
        dur = mediaplayer1.NaturalDurataion.TimeSpan.Ticks.ToString()
        if (pos == dur)
        {
            // MediaEnded!!!!!
            pos = "0";
            dur = "0";
        }
        catch {}
    }
}

Положительным моментом является то, что вы можете обновить ползунок аудиоплеера с помощью опроса... С другой стороны, это делает кнопку паузы немного невосприимчивой, если вы заметите задержку в 1000 миллисекунд...

Если вы используете этот обходной путь, я бы рекомендовал разместить Mediaplayer в фоновом потоке, чтобы цикл опроса не блокировал поток пользовательского интерфейса.

person Bimo    schedule 24.08.2017