我正在使用QtMultimedia库使用VC++播放音频流中的音频。由于我对Qt的库没有太多的经验,所以我从读入一个.wav文件并将其写入缓冲区开始:
ifstream wavFile;
char* file = "error_ex.wav";
wavFile.open( file, ios::binary );在那之后,我使用了ifstream的.read()函数并将所有数据写入一个缓冲区。在写入缓冲区之后,它被发送到音频编写器,以便为Qt做准备:
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准备就绪,我就会尝试播放缓冲区:
QIODevice* ioDevice = m_pAudioOut->start();
ioDevice->write( m_pBuffer->buffer() );(m_pAudioOut的类型为QAudioOutput)
这会导致扬声器发出一声小响声,然后它将停止播放。你知道为什么吗?
使用Qt库4.6.3在Windows XP SP2上运行Visual Studios 2008。
发布于 2010-08-09 16:56:05
正如Frank所指出的,如果你的需求仅仅是播放文件中的音频数据,一个更高级别的API就可以完成这项工作,并将简化你的应用程序代码。Phonon是一种选择;或者,QtMobility项目为高级用例提供了QMediaPlayer应用编程接口。
考虑到这个问题是专门关于使用QIODevice的,而且你提到从WAV文件中读取只是你的初始方法,我假设你实际上需要一个流式应用程序接口,即允许客户端控制缓冲的接口,而不是将这种控制交给更高级别的抽象,比如Phonon。
根据调用start()重载的方式,可以在两种不同的模式下使用QAudioOutput:
void QAudioOutput::start(QIODevice *)在此模式下,QAudioOutput将从提供的QIODevice中提取数据,而无需客户端的进一步干预。如果所使用的QIODevice是由Qt提供的(例如QFile、QAbstractSocket等),这是一个很好的选择。
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一起提供。
发布于 2010-08-09 16:25:06
您确定您使用了正确的(高级) API吗?如果你不得不手动处理数据流和缓冲,那就太奇怪了。此外,QIODevice:: write ()不一定写入整个缓冲区,但可能会在n个字节后停止,就像POSIX write()一样(这就是为什么总是要检查返回值)。
我还没有研究过QtMultimedia,但使用更成熟的电话,视频和音频输出在过去对我来说很好。它是这样工作的:
)
::MediaSource( path )
在Qt中也有一些例子。
https://stackoverflow.com/questions/3426868
复制相似问题