首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用QIODevice播放音频数据(带VC++的Qt4.6)

使用QIODevice播放音频数据(带VC++的Qt4.6)
EN

Stack Overflow用户
提问于 2010-08-07 03:01:48
回答 2查看 7.9K关注 0票数 11

我正在使用QtMultimedia库使用VC++播放音频流中的音频。由于我对Qt的库没有太多的经验,所以我从读入一个.wav文件并将其写入缓冲区开始:

代码语言:javascript
复制
ifstream wavFile;
char* file = "error_ex.wav";
wavFile.open( file, ios::binary );

在那之后,我使用了ifstream的.read()函数并将所有数据写入一个缓冲区。在写入缓冲区之后,它被发送到音频编写器,以便为Qt做准备:

代码语言:javascript
复制
QByteArray fData;

for( int i = 0; i < (int)data.size(); ++i )
{
    fData.push_back(data.at(i));
}

m_pBuffer->open(QIODevice::ReadWrite);
m_pBuffer->write( fData );

m_pBuffer->close();

(m_pBuffer的类型为QBuffer)

一旦QBuffer准备就绪,我就会尝试播放缓冲区:

代码语言:javascript
复制
QIODevice* ioDevice = m_pAudioOut->start();
ioDevice->write( m_pBuffer->buffer() );

(m_pAudioOut的类型为QAudioOutput)

这会导致扬声器发出一声小响声,然后它将停止播放。你知道为什么吗?

使用Qt库4.6.3在Windows XP SP2上运行Visual Studios 2008。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-09 16:56:05

正如Frank所指出的,如果你的需求仅仅是播放文件中的音频数据,一个更高级别的API就可以完成这项工作,并将简化你的应用程序代码。Phonon是一种选择;或者,QtMobility项目为高级用例提供了QMediaPlayer应用编程接口。

考虑到这个问题是专门关于使用QIODevice的,而且你提到从WAV文件中读取只是你的初始方法,我假设你实际上需要一个流式应用程序接口,即允许客户端控制缓冲的接口,而不是将这种控制交给更高级别的抽象,比如Phonon。

根据调用start()重载的方式,可以在两种不同的模式下使用QAudioOutput

  • 拉取模式:void QAudioOutput::start(QIODevice *)

在此模式下,QAudioOutput将从提供的QIODevice中提取数据,而无需客户端的进一步干预。如果所使用的QIODevice是由Qt提供的(例如QFileQAbstractSocket等),这是一个很好的选择。

  • 推送模式:QIODevice* QAudioOutput::start()

在此模式下,QAudioOutput客户端必须通过调用QIODevice::write()将模式推送到音频设备。这将需要在循环中完成,类似于:

qint64 dataRemaining = ... //在此处分配正确的值while ( dataRemaining ) { qint64 bytesWritten = audioOutput->write( buffer,dataRemaining);dataRemaining -= bytesWritten;buffer += bytesWritten;//然后稍等}

如何实现等待将取决于您的应用程序的上下文-如果音频是从专用线程写入的,它可以简单地sleep()。或者,如果音频是从主线程写入的,您可能希望由QTimer触发写入。

由于您没有提到在应用程序中使用write()调用的循环,因此看起来发生的情况是您编写了一小段数据(播放为pop),然后不再编写。

您可以在示例/多媒体/音频输出应用程序中看到使用这两种模式的代码,该应用程序随Qt一起提供。

票数 12
EN

Stack Overflow用户

发布于 2010-08-09 16:25:06

您确定您使用了正确的(高级) API吗?如果你不得不手动处理数据流和缓冲,那就太奇怪了。此外,QIODevice:: write ()不一定写入整个缓冲区,但可能会在n个字节后停止,就像POSIX write()一样(这就是为什么总是要检查返回值)。

我还没有研究过QtMultimedia,但使用更成熟的电话,视频和音频输出在过去对我来说很好。它是这样工作的:

)

  • mediaObject->setCurrentSource( );

  • mediaObject->play();

::MediaSource( path )

  1. Create a Phonon::MediaObject object
  2. Phonon::createPath( mediaObject,audioObject MediaSource(Path)创建音箱::AudioOutput对象路径

在Qt中也有一些例子。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3426868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档