使用音频队列或音频单元的 VoIP 功能
Posted
技术标签:
【中文标题】使用音频队列或音频单元的 VoIP 功能【英文标题】:VoIP functionality using Audio Queue or Audio Unit 【发布时间】:2012-12-04 19:31:10 【问题描述】:你能告诉我这是怎么做到的吗?在一台设备上录制音频并在另一台设备上播放(VoIP)?
我被困在这里:我在此功能中的一台设备上获取输入语音数据
void AQRecorder::MyInputBufferHandler( void * inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,
UInt32 inNumPackets,
const AudiostreamPacketDescription* inPacketDesc)
AQRecorder *aqr = (AQRecorder *)inUserData;
try
if (inNumPackets > 0)
// write packets to file
XThrowIfError(AudioFileWritePackets(aqr->mRecordFile, FALSE, inBuffer->mAudioDataByteSize,
inPacketDesc, aqr->mRecordPacket, &inNumPackets, inBuffer->mAudioData),
"AudioFileWritePackets failed");
//inData = inBuffer->mAudioData;
aqr->mRecordPacket += inNumPackets;
aqr->updateIndata(inBuffer);
// if we're not stopping, re-enqueue the buffe so that it gets filled again
if (aqr->IsRunning())
XThrowIfError(AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL), "AudioQueueEnqueueBuffer failed");
catch (CAXException e)
char buf[256];
fprintf(stderr, "Error: %s (%s)\n", e.mOperation, e.FormatError(buf));
我将数据包发送到 UDP:
void AQRecorder::updateIndata(AudioQueueBufferRef inBuffer)
SpeakHereAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
NSData *audioBytes = [NSData dataWithBytes:inBuffer->mAudioData
length:inBuffer->mAudioDataByteSize];
NSLog(@"bytes: %d", [audioBytes length]);
[appDelegate.udpSocket sendData:audioBytes
toHost:appDelegate.host
port:appDelegate.port
withTimeout:-1
tag:1];
& 我正在以 NSData 的形式接收另一端的数据,但不知道如何播放,请您帮忙
【问题讨论】:
【参考方案1】:你需要一个像 CARingBuffer 这样的环形缓冲区来存储接收到的音频数据,并像 Audio Unit Render Callback 方法一样从缓冲区中读取数据。因为读写操作是异步的,而且速度不同,所以很难确定环形缓冲区应该多长。 所以你也可以使用临时文件来存储接收到的数据,总是把日期写到文件的末尾,然后从头部读取。
【讨论】:
以上是关于使用音频队列或音频单元的 VoIP 功能的主要内容,如果未能解决你的问题,请参考以下文章
Core Audio(音频单元)音频会话和 MPVolumeView