-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
似乎解决了"no data in list for 1e8 times access"这个问题 #38
似乎解决了"no data in list for 1e8 times access"这个问题 #38
Conversation
本 PR 所修改代码所在的逻辑,在 在理想的情况下,在尾部(或附近) 但实际情况是,由于我现在还不知道的原因, 我做了测试,仅依赖 不过, |
更加稳妥的关于判定音乐到达尾部的方法: if(m_MS.audioq.first_pkt == nullptr){
qDebug() << "ending reached";
AGStatus = AGS_FINISH;
isEndByForce = false;
break;
} 截至目前,测试的效果非常好,比用时间差判断不知道高到哪里去了。 |
a589dae
to
3d6d510
Compare
提交 3d6d510 就是可以用的,而且逻辑简明的版本了。 |
找到一个长得有些不一样的 |
这个项目的播放逻辑是参考复制一个酷狗demo的,https://github.com/BensonLaur/KuGouDemo |
我又来打扰 watching 本项目的各位了。看来被关闭的 PR 不能自动更新,现在我提交了一个更改,所以要把 PR 打开。等最后一起修复(提交总的 PR )的时候我会再来关闭。抱歉。 |
好的,谢谢。 我发现了一个新问题,在 这会使得 这或许与 但是做进一步分析能发现,这个循环的开头会使用 我发现本问题在 Windows 上似乎更容易复现,但按照本 PR 进行修改后,暂时还没有再次出现过。 另外,总体来说,本问题的确很难复现,所以作者测试后才会这样说: #23 (comment) 。这也是我很疑惑的地方。 |
流水账: 由于“信号——信号槽”的机制导致的滞后效果,以下的日志内容中 根据观察,在没有修改代码的状态下, //BottomWidget::positionChanged => audioOriginalPos= 2011 sliderSong->value()= 8
//BottomWidget::positionChanged => audioOriginalPos= 2115 sliderSong->value()= 9 // Audio is playing
BottomWidget::reloadMusic(QString)
MusicPlayer::stop()
//no data in list for 1e8 times access
//no data in list for 1e8 times access
//... 为了找出输出 void MusicPlayer::stop()
{
qDebug()<<"void MusicPlayer::stop() bIsLock="<<bIsLock;
playThread->setAGStatus(AGS_FINISH);
+ qDebug()<<"post playThread->setAGStatus(AGS_FINISH);";
//停止音乐必须保证线程真的退出(否则 playThread->bIsDeviceInit 可能判断成立,而实际线程还没退出,导致下一次 播放 playThread->playDevice() 没能及时起作用)
while(playThread->isRunning())
_millisecondSleep(10); //等待结束
+ qDebug()<<"post !playThread->isRunning()";
if(bIsLock)
{
audioFinishedToThreadExitMutex.unlock();
bIsLock = false;
}
//emit sig_playThreadFinished();
} 现在,正常的重新载入音乐的序列为: //BottomWidget::positionChanged => audioOriginalPos= 1541 sliderSong->value()= 5
//BottomWidget::positionChanged => audioOriginalPos= 1645 sliderSong->value()= 5// Audio is playing
void BottomWidget::reloadMusic(QString) // from MainWidget::OnPlayNewMusicAndLyric(QString, QString)
void MusicPlayer::stop() // from BottomWidget::reloadMusic(QString)
post playThread->setAGStatus(AGS_FINISH);
&PlayThread::audioFinish // emitted from PlayThread::ReleaseAll() in PlayThread::run()
&PlayThread::finished // emitted because PlayThread is end
post !playThread->isRunning()
void BottomWidget::play() // from MainWidget::OnPlayNewMusicAndLyric(QString, QString)
void MusicPlayer::play() //from BottomWidget::play()
BottomWidget::positionChanged(qint64)
void BottomWidget::onAudioFinished(bool)
BottomWidget::positionChanged(qint64)
// Audio info
&PlayThread::audioPlay // in PlayThread::run()
&PlayThread::audioPause
//seek successful from 0 to :
&PlayThread::audioPlay
//to 0
void BottomWidget::onAudioPlay()
void BottomWidget::onAudioPause()
void BottomWidget::onAudioPlay()
//BottomWidget::positionChanged => audioOriginalPos= 182 sliderSong->value()= 0 // Audio is playing
//BottomWidget::positionChanged => audioOriginalPos= 287 sliderSong->value()= 0 如果出问题了,就有以下两种情况(均有两次很接近的
没有音乐播放,界面卡死。 //BottomWidget::positionChanged => audioOriginalPos= 1541 sliderSong->value()= 5
//BottomWidget::positionChanged => audioOriginalPos= 1645 sliderSong->value()= 5// Audio is playing
void BottomWidget::reloadMusic(QString) // <------
void MusicPlayer::stop() // <------
post playThread->setAGStatus(AGS_FINISH);
&PlayThread::audioFinish
&PlayThread::finished
post !playThread->isRunning()
void BottomWidget::play()
void MusicPlayer::play()
BottomWidget::positionChanged(qint64)
void BottomWidget::onAudioFinished(bool)
// Audio info
BottomWidget::positionChanged(qint64)
&PlayThread::audioPlay // 在此之后
void BottomWidget::reloadMusic(QString) // <------
void MusicPlayer::stop() // <------
post playThread->setAGStatus(AGS_FINISH);
//no data in list for 1e8 times access
//no data in list for 1e8 times access
音乐正常播放,界面卡死,不输出 //BottomWidget::positionChanged => audioOriginalPos= 1541 sliderSong->value()= 5
//BottomWidget::positionChanged => audioOriginalPos= 1645 sliderSong->value()= 5// Audio is playing
void BottomWidget::reloadMusic(QString) // <------
void MusicPlayer::stop() // <------
post playThread->setAGStatus(AGS_FINISH);
&PlayThread::audioFinish
&PlayThread::finished
post !playThread->isRunning()
void BottomWidget::play()
void MusicPlayer::play()
void BottomWidget::reloadMusic(QString) // <------
void MusicPlayer::stop() // <------
// Audio info
&PlayThread::audioPlay // 在此之前
&PlayThread::audioPause
post playThread->setAGStatus(AGS_FINISH);
//seek successful from 0 to :
&PlayThread::audioPlay
//to 0
// 界面卡死 只有 以上两种情况的主要差别是, 重现一部分
+ static int chance = 1; //让第一次播放正常
connect(playThread, &PlayThread::audioPlay,[=](){
+ if(chance > 0){
+ chance--;
+ }else{
+ stop();
+ }
qDebug()<<"&PlayThread::audioPlay bIsLock="<<bIsLock;
emit audioPlay();
});
不过,由于 lambda 表达式作为信号槽的特性,这里调用 |
这种分析太痛苦了,而且效果不好……但是也能看出,现在的 播放逻辑 和 界面与播放交互逻辑 的设计似乎的确是有问题(互斥锁的使用,线程状态的判断等等),所以重构可能才是更好的方法。 我这边已经把 |
这个由于这边也是对ffmpeg理解很不够,所以照葫芦画瓢的拿了一段播放代码过来用,遇到问题修修补补,比如那个检测一亿次的部分也是遇到问题就尝试补一补试图临时解决问题,设计确实不大好 |
c61c84c
to
8524ad5
Compare
8524ad5
to
e6f06df
Compare
与 #23 有关。
我并没有研究与 SDL 相关的代码,仅仅是对逻辑进行了一些分析,尝试直接跳过对
tryTimes
和AGStatus
的处理,返回-1
。做测试,快速切换、重新播放歌曲,就暂时没有出现卡死的情况了。
已在 Windows 10 、 Ubuntu 18.04 和 macOS 10.14 下做了测试。
这个 PR 需要继续讨论,其中的道理可能也需要学习 SDL 后才能搞明白吧。
上述内容与提交 d05c494 有关(我又一次弄坏了 git 历史)。