iOS8 AVAudioEngine如何通过Multipeer Connectivity发送麦克风数据?

Posted

技术标签:

【中文标题】iOS8 AVAudioEngine如何通过Multipeer Connectivity发送麦克风数据?【英文标题】:iOS8 AVAudioEngine how to send microphone data over Multipeer Connectivity? 【发布时间】:2014-10-09 04:02:55 【问题描述】:

我想通过 Multipeer Connectivity (ios 8) 发送麦克风音频数据,并通过接收对等方的扬声器播放。我还设置了 AVAudioEngine,我可以从(上部)扬声器输出听到麦克风数据,但我不知道如何通过网络发送 AVAudioPCMBuffer。这是我的代码 sn-p:

AVAudioInputNode *inputNode =[self.engine inputNode];
AVAudioMixerNode *mainMixer = [self.engine mainMixerNode];
[self.engine connect:inputNode to:mainMixer format:[inputNode inputFormatForBus:0]];

[mainMixer installTapOnBus:0 bufferSize:4096 format:[mainMixer outputFormatForBus:0] 
    block:^(AVAudioPCMBuffer *buffer, AVAudioTime *when) 

    //==== How to send the PCMBuffer ?? ======//
];

NSError *error = nil;
[self.engine startAndReturnError:&error];

if(error)

    NSLog(@"error: %@", [error localizedDescription]);

我是把它作为 NSData 还是 NSStream 发送?

感谢您的帮助。谢谢。

【问题讨论】:

【参考方案1】:

我没有尝试过这个解决方案:

- (NSOutputStream *)startStreamWithName:(NSString *)streamName
                                 toPeer:(MCPeerID *)peerID
                                  error:(NSError **)error

您可以使用property buffer.floatChannelData 接收浮点数组。现在您可以将这个浮点数组打包到NSOutputStream 中并发送。

在客户端,您可以尝试接收流:

- (void)session:(MCSession *)session
didReceiveStream:(NSInputStream *)stream
       withName:(NSString *)streamName
       fromPeer:(MCPeerID *)peerID

    stream.delegate = self;
    [stream scheduleInRunLoop:[NSRunLoop mainRunLoop] 
                      forMode:NSDefaultRunLoopMode];
    [stream open];

但是在你尝试这个之前,你可以尝试发送随机值(因此white noise)而不是浮点数组,这样你就可以确定发送这些缓冲区的时隙(我们正在谈论实时) 足够宽。

15.10.2014 更新 我找到了你需要的东西: http://robots.thoughtbot.com/streaming-audio-to-multiple-listeners-via-ios-multipeer-connectivity

【讨论】:

嗨迈克尔,谢谢你的答案。 MCSessionDelegate 有这个方法: session:didReceiveStream:withName:fromPeer: 是否可以将数据作为流发送?因为它是连续的数据流。而且,“时隙足够宽”是什么意思?谢谢。 我以为您只是在询问发件人。我添加了接收器的东西。对于第二个问题,我过于简单化了:如果音频数据到达接收器的速度比蓝牙连接可以处理的快;我指的是“时隙”。 嗨迈克尔,谢谢您的及时回复。请原谅我...我的意思是 startStreamWithName:toPeer:error:, didReceiveStream 是接收部分。我尝试使用 NSData 发送和接收,但接收端出现问题。我使用 [NSData dataWithBytes:buffer.floatChannelData length:buffer.frameLength] 发送,如何将接收到的字节数据转换回 AVAudioPCMBuffer ?因为我将使用 AVAudioPlayerNode 来播放缓冲区。在 Apple 文档中,buffer.floatChannelData 没有“设置器”。 这正是您尝试的演示项目:robots.thoughtbot.com/… 您提供的示例链接确实与我想要实现的非常相似。但是,我觉得实现太复杂了(尤其是在接收端)。应该有一个更简单的解决方案,只使用 AVAudioEngine。顺便说一句,我可以使用提供的代码将音乐从一个设备流式传输到另一个设备,但我还不能流式传输麦克风数据。这:CMSampleBufferRef sampleBuffer = (__bridge CMSampleBufferRef)(self.micPCMBuffer); 在尝试写出流时给我一个错误。

以上是关于iOS8 AVAudioEngine如何通过Multipeer Connectivity发送麦克风数据?的主要内容,如果未能解决你的问题,请参考以下文章

AVAudioEngine 不正确的时间管理和 AVAudioPlayerNode 回调

我可以将旧的 AVAudioPlayer 与新的 AVAudioEngine 一起使用吗?

应该如何在 AVAudioEngine 图中配置 AUMatrixMixer?

SWIFT - 是不是可以从 AVAudioEngine 或 AudioPlayerNode 保存音频?如果是,如何?

如何使用 AVAudioEngine 取消或消除回声/重复声音?

AVAudioEngine 离线渲染:仅在连接耳机时静音输出