Search code examples
c#winformstrackbar

Music plays choppy with TrackBar


I am creating a simple music (mp3) player in WinForm in C#. What I want to achieve is:
1) Play music file selected
2) Move TrackBar automatically as the music plays
3) Allow the user to move the trackbar back and forth so they can play music from anywhere in the track. (While the music is playing too)

I got #1 and #2 working without any problem. However, I am having difficulty implementing #3. The music plays very choppy as I overwrite the value. Here is my code.

private AxWMPLib.AxWindowsMediaPlayer player;

/*Play the music file selected (#1) */
private void BtnPlay_Click(object sender, EventArgs e)
{
    player = new AxWMPLib.AxWindowsMediaPlayer();
    player.CreateControl();
    player.URL = filePath; //Initialized somewhere in the code
    player.PlayStateChange += player_PlayStateChange;
    player.Ctlcontrols.play();
}

private void player_PlayStateChange(object sender, AxWMPLib._WMPOCXEvents_PlayStateChangeEvent e)
{
    if (player.playState == WMPLib.WMPPlayState.wmppsPlaying)
    {
        MyTrackBar.Maximum = (int)player.Ctlcontrols.currentItem.duration;
        TmrPlay.Start();
    }
    else if(player.playState == WMPLib.WMPPlayState.wmppsStopped)
    {
        TmrPlay.Stop();
        MyTrackBar.Value = 0;
    }
}

/*Move the TrackBar automatically with Timer. (#2) Runs every 100 ms */
private void TmrPlay_Tick(object sender, EventArgs e)
{
    if (player.playState == WMPLib.WMPPlayState.wmppsPlaying)         
        MyTrackBar.Value = (int)player.Ctlcontrols.currentPosition;
}

/* Trying to play music from anywhere when the TrackBar is manually moved. 
   For example, they can move the TrackBar and move it towards the end of the 
   music, WHILE THE MUSIC IS PLAYING. */
/* With this below event code, I can move the TrackBar freely, but the music
   plays very choppy because it keeps changing the currentPosition. */
private void MyTrackBar_ValueChanged(object sender, EventArgs e)
{
    player.Ctlcontrols.currentPosition = MyTrackBar.Value;
}

Can anyone give me advice on how to play music without it being choppy when the TrackBar is moved?


Solution

  • The issue you're facing is that you're updating the trackbar from the tick event and then that is triggering the player position to be re-updated to the position it's at. So each tick forces the trackbar to update twice which is introducing the stutter you're experiencing.

    To fix it you need to not update the player position if the tick event is firing.

    A class level bool variable will do the trick:

    private bool ticking = false;
    

    In your TmrPlay_Tick you should set ticking to true:

    if (player.playState == WMPLib.WMPPlayState.wmppsPlaying)         
    {
        ticking = true;
        MyTrackBar.Value = (int)player.Ctlcontrols.currentPosition;
    }
    

    Then in your MyTrackBar_ValueChanged event don't update the trackbar again if ticking is true:

    if (ticking)
    {
        ticking = false;
    }
    else
    {
        player.Ctlcontrols.currentposition = MyTrackBar.Value;
    }