TrackBar 播放的音乐断断续续

Music plays choppy with TrackBar

我正在使用 C# 在 WinForm 中创建一个简单的音乐 (mp3) 播放器。 我想要实现的是:
1) 播放选定的音乐文件
2) 播放音乐时自动移动 TrackBar
3) 允许用户来回移动轨迹条,以便他们可以从曲目中的任何位置播放音乐。 (同时播放音乐)

我让#1 和#2 正常工作。但是,我很难实施#3。当我覆盖该值时,音乐播放起来非常不稳定。这是我的代码。

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;
}

谁能给我一些建议,告诉我如何在移动 TrackBar 时播放音乐时不会出现断断续续的情况?

您面临的问题是您从滴答事件更新轨迹栏,然后触发播放器位置重新更新到它所在的位置。因此,每个刻度都会迫使轨迹栏更新两次,这会引入您遇到的卡顿现象。

要修复它,您需要在 tick 事件触发时不更新玩家位置。

一个 class 级别的 bool 变量就可以了:

private bool ticking = false;

在您的 TmrPlay_Tick 中,您应该将 ticking 设置为 true:

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

然后在您的 MyTrackBar_ValueChanged 事件中,如果 ticking 为真,则不要再次更新轨迹栏:

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