【发布时间】:2017-01-23 04:07:17
【问题描述】:
我正在尝试通过 Apple 的 Multipeer Connectivity 框架将音频从麦克风流式传输到另一部 iPhone。为了进行音频捕获和播放,我使用了 AVAudioEngine(非常感谢 Rhythmic Fistman's 回答 here)。
我通过在输入端安装一个水龙头从麦克风接收数据,从中我得到一个 AVAudioPCMBuffer,然后我将其转换为 UInt8 数组,然后我将其流式传输到另一部手机。
但是当我将数组转换回 AVAudioPCMBuffer 时,我得到一个 EXC_BAD_ACCESS 异常,编译器指向我再次将字节数组转换为 AVAudioPCMBuffer 的方法。
这是我在哪里获取、转换和流式传输输入的代码:
input.installTap(onBus: 0, bufferSize: 2048, format: input.inputFormat(forBus: 0), block: {
(buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in
let audioBuffer = self.typetobinary(buffer)
stream.write(audioBuffer, maxLength: audioBuffer.count)
})
我的两个数据转换函数(取自Martin.R的答案here):
func binarytotype <T> (_ value: [UInt8], _: T.Type) -> T {
return value.withUnsafeBufferPointer {
UnsafeRawPointer($0.baseAddress!).load(as: T.self)
}
}
func typetobinary<T>(_ value: T) -> [UInt8] {
var data = [UInt8](repeating: 0, count: MemoryLayout<T>.size)
data.withUnsafeMutableBufferPointer {
UnsafeMutableRawPointer($0.baseAddress!).storeBytes(of: value, as: T.self)
}
return data
}
在接收端:
func session(_ session: MCSession, didReceive stream: InputStream, withName streamName: String, fromPeer peerID: MCPeerID) {
if streamName == "voice" {
stream.schedule(in: RunLoop.current, forMode: .defaultRunLoopMode)
stream.open()
var bytes = [UInt8](repeating: 0, count: 8)
stream.read(&bytes, maxLength: bytes.count)
let audioBuffer = self.binarytotype(bytes, AVAudioPCMBuffer.self) //Here is where the app crashes
do {
try engine.start()
audioPlayer.scheduleBuffer(audioBuffer, completionHandler: nil)
audioPlayer.play()
}catch let error {
print(error.localizedDescription)
}
}
}
问题是我可以在流式传输它(在同一部手机中)之前来回转换字节数组并从中播放声音,但不能在接收端创建 AVAudioPCMBuffer。有谁知道为什么转换在接收端不起作用?这是正确的方法吗?
对此的任何帮助、想法/意见将不胜感激。
【问题讨论】:
-
您能否提供一些参考如何使用音频队列或任何示例项目?
-
不,我不敢。
标签: swift avfoundation audio-streaming swift3 avaudioengine