【问题标题】:Music plays choppy with TrackBar使用 TrackBar 播放音乐时断断续续
【发布时间】:2019-04-06 02:03:12
【问题描述】:

我正在用 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 时播放音乐而不出现断断续续的情况?

【问题讨论】:

  • 因为.Value正在改变和调整播放器。
  • 对,我明白了,但我不确定我还能如何做到这一点...顺便说一句,如果我删除最后一个方法,它可以正常工作并且音乐播放流畅。没有波涛汹涌。但是如果我添加最后一个方法,它就会变得不稳定。

标签: c# winforms trackbar


【解决方案1】:

您面临的问题是您正在从滴答事件更新轨迹栏,然后触发播放器位置重新更新到它所在的位置。因此,每次滴答都会强制跟踪栏更新两次,这会引入您遇到的口吃。

要解决此问题,您无需在触发滴答事件时更新玩家位置。

类级别的布尔变量可以解决问题:

private bool ticking = false;

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

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

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

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

【讨论】:

  • 非常感谢。它得到了修复!
猜你喜欢
  • 2017-11-21
  • 1970-01-01
  • 1970-01-01
  • 2018-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-02
相关资源
最近更新 更多