문제

I want to get duration ( TotalMiliseconds ) of a Song object when I play music in the library by using MediaPlayer

My code :

DispatcherTimer timer = new DispatcherTimer();

private void btnPlay_Click(object sender, EventArgs e)
{
    using (MediaLibrary library = new MediaLibrary())
    {
        foreach (var item in library.Songs)
        {                       
            FrameworkDispatcher.Update();
            MediaPlayer.Play(item);

            int duration =(int)MediaPlayer.Queue.ActiveSong.Duration.TotalMilliseconds;                                
            processbar.Maximum =  duration ;                          
            timer.Start();

            // I show total duration here to test . but it shows 0 value 
            MessageBox.Show(duration+"");    

            // I just want to play the first song, so I break here
            break;
        }
        library.Dispose();
    }
}

void timer_Tick(object sender, EventArgs e)
{
    int current_duration = (int)MediaPlayer.PlayPosition.TotalMilliseconds;
    processbar.Value = current_duration;

    // i show current duration here to test, it shows OK with a milisecond value.
    MessageBox.Show(current_duration + "");    

}

When I get totalmiliseconds duration in btnPlay_Click method, it always returns 0. It's the reason why My processbar maximum value is 0, so It can't show process bar correctly

Can you help me to get total duration (Milisecond or anything else) of playing song with MediaPlayer ?

Thank you very very much !!!

도움이 되었습니까?

해결책

There are two events that you'll find helpful.

  1. MediaStateChanged
    (http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.media.mediaplayer.mediastatechanged.aspx)
  2. ActiveSongChanged
    (http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.media.mediaplayer.activesongchanged.aspx)

Register to these events and from the event handlers check MediaPlayer.Queue.ActiveSong.Duration. The problem you're encountering is that the ActiveSong isn't set immediately after calling MediaPlayer.Play().

private void btnPlay_Click(object sender, EventArgs e)
{
    using (MediaLibrary library = new MediaLibrary())
    {
        foreach (var item in library.Songs)
        {                       
            MediaPlayer.MediaStateChanged += _onMediaStateChanged; //register for event
            MediaPlayer.ActiveSongChanged += _onActiveSongChanged;

            FrameworkDispatcher.Update();
            MediaPlayer.Play(item);

            timer.Start();

            // I just want to play the first song, so I break here
            break;
        }
        library.Dispose();
    }
}

private void _onMediaStateChanged(object sender, EventArgs e)
{
    if(MediaPlayer.State == MediaState.Playing)
    {
        int duration = (int)MediaPlayer.Queue.ActiveSong.Duration.TotalMilliseconds;                                
        processbar.Maximum = duration;
    }
}

private void _onActiveSongChanged(object sender, EventArgs e)
{
    int duration = (int)MediaPlayer.Queue.ActiveSong.Duration.TotalMilliseconds;                                
    processbar.Maximum = duration;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top