質問

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