Qt:如何在不阻塞主线程的情况下播放声音?
Posted
技术标签:
【中文标题】Qt:如何在不阻塞主线程的情况下播放声音?【英文标题】:Qt: How to play sound witout blocking main thread? 【发布时间】:2011-04-08 20:36:45 【问题描述】:我想知道 Qt 中是否有一种简单的方法可以在不阻塞主线程的情况下播放声音?
我知道通常我应该启动一个单独的线程来执行此操作。但也许有捷径? :)
感谢您的帮助。
【问题讨论】:
【参考方案1】:标准 QSound 和 Phonon 库在播放声音时都存在严重问题。它们都需要主消息循环,这意味着主线程中的轻微阻塞或播放声音的延迟。最终,他们都使用后台线程,但很容易注意到滞后。更不用说 Phonon 在许多平台上的支持存在问题。
我已经与这两者合作了一段时间,并尝试构建一个简单的声音系统来播放用户界面声音(只是偶尔发出哔哔声和弹出声)。使用标准 Qt 库是不可能的。
我建议使用 OpenAL,我最终也这样做了。这是一个相对简单的库,似乎有很好的跨平台支持。另一个选项是 SDL_mixer,但 OpenAL 似乎更容易在 Windows 上安装(虽然可能不是很多)。所以基本上,如果QSound::play
没有做你想做的事,那么标准的 Qt API 将不适合你。
另一个重要说明,不要费心尝试使用单独的线程修复 Qt 声音 api。它行不通。声子至少需要在主线程中被实例化和调用。
【讨论】:
+1 用于建议 OpenAL。早期版本的 SDL 很难集成到其他库的消息循环中。 QSound 对我来说很好用。很高兴了解 OpenAL,将来可能会有用。 我很高兴我没有尝试单独的线程路由。我无法在 Windows 上进行无缝播放,我考虑过使用 SDL。很高兴知道 OpenAL 也是一种选择。 为了将来参考,能否请您提供您使用的 Qt/OpenAL 版本,以及您测试的平台?【参考方案2】:http://doc.qt.nokia.com/latest/qsound.html
Qt 提供了 GUI 应用程序中最常用的音频操作:异步播放声音文件。使用静态 play() 函数最容易做到这一点:
QSound::play("mysounds/bells.wav");
这似乎是一个异步操作,所以它不应该阻塞你的主线程。
【讨论】:
请注意,这仅适用于声音文件,不适用于以编程方式生成的声音。前者可能是所有 OP 需要的,但后者我发现执行确实阻塞了 QAudioOutput::start()。【参考方案3】:我一直在使用 QT 声音系统,尤其是线程问题。
这个解决方案对我有用:
-
将任何 wav 转换为 mp3,因为在播放 wav 时存在问题
qt 5.5。
将这些 mp3 文件添加到 QT (qrc) 中的资源中。
使用 QMediaPlayer 播放声音。
例子:
http://doc.qt.io/qt-5/qtmultimediawidgets-player-player-cpp.html
https://www.youtube.com/watch?v=DS7CDpIrwN4
【讨论】:
【参考方案4】:QMediaPlayer 不应阻塞您的线程。
#include <QtMultimedia/QMediaPlayer>
QMediaPlayer *player = new QMediaPlayer;
player->setMedia(QUrl::fromLocalFile("/path"));
player->setVolume(50);
player->play();
【讨论】:
以上是关于Qt:如何在不阻塞主线程的情况下播放声音?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不更改声音指示器的情况下在 iOS 中以最大音量播放声音文件
HTML:如何在不缓冲所有声音数据的情况下从 URL 中间文件开始声音播放