我将简要介绍一下我的应用程序的所有元素:
我有一个将音频记录到 AVAudioPCMBuffer 的应用程序。然后将该缓冲区转换为 NSData,然后转换为 [UInt8]。然后通过 OutputStream 进行流式传输。在另一台设备上,使用 InputStream 接收此数据。然后它被转换为 NSData,并返回到 AVAudioPCMBuffer。然后播放该缓冲区。
问题是音频非常不稳定,您无法听清声音,只是音频会根据对方是否在说话而变大或变小。
<小时/>调度缓冲区时:
self.peerAudioPlayer.scheduleBuffer(audioBuffer, completionHandler: nil)
我延迟了播放该音频几秒钟,然后再播放,希望这样可以使音频更清晰,但没有帮助。我最好的猜测是我正在创建的缓冲区以某种方式切断了一些音频。所以我将向您展示我的相关代码:
这是我录制音频的方法:
localInput?.installTap(onBus: 1, bufferSize: 4096, format: localInputFormat) {
(buffer, when) -> Void in
let data = self.audioBufferToNSData(PCMBuffer: buffer)
let output = self.outputStream!.write(data.bytes.assumingMemoryBound(to: UInt8.self), maxLength: data.length)
}
audioBufferToNSData 只是将 AVAudioPCMBuffer 转换为 NSData 的方法,如下:
func audioBufferToNSData(PCMBuffer: AVAudioPCMBuffer) -> NSData {
let channelCount = 1 // given PCMBuffer channel count is 1
let channels = UnsafeBufferPointer(start: PCMBuffer.floatChannelData, count: channelCount)
let data = NSData(bytes: channels[0], length:Int(PCMBuffer.frameCapacity * PCMBuffer.format.streamDescription.pointee.mBytesPerFrame))
return data
}
我想知道问题是否出在上面的方法上。可能当我计算 NSData 对象的长度时,我可能会切断部分音频。
<小时/>在接收端我有这个:
case Stream.Event.hasBytesAvailable:
DispatchQueue.global().async {
var tempBuffer: [UInt8] = .init(repeating: 0, count: 17640)
let length = self.inputStream!.read(&tempBuffer, maxLength: tempBuffer.count)
self.testBufferCount += length
self.testBuffer.append(contentsOf: tempBuffer)
if (self.testBufferCount >= 17640) {
let data = NSData.init(bytes: &self.testBuffer, length: self.testBufferCount)
let audioBuffer = self.dataToPCMBuffer(data: data)
self.peerAudioPlayer.scheduleBuffer(audioBuffer, completionHandler: nil)
self.testBuffer.removeAll()
self.testBufferCount = 0
}
}
我检查17640的原因是因为发送的数据正好是17640字节,所以我需要在播放之前获取所有这些数据。
此外,dataToPCMBuffer方法只是将NSData转换为AVAudioPCMBuffer以便可以播放。这是该方法:
func dataToPCMBuffer(data: NSData) -> AVAudioPCMBuffer {
let audioFormat = AVAudioFormat(commonFormat: .pcmFormatFloat32, sampleRate: 44100, channels: 1, interleaved: false) // given NSData audio format
let audioBuffer = AVAudioPCMBuffer(pcmFormat: audioFormat, frameCapacity: UInt32(data.length) / audioFormat.streamDescription.pointee.mBytesPerFrame)
audioBuffer.frameLength = audioBuffer.frameCapacity
let channels = UnsafeBufferPointer(start: audioBuffer.floatChannelData, count: Int(audioBuffer.format.channelCount))
data.getBytes(UnsafeMutableRawPointer(channels[0]) , length: data.length)
return audioBuffer
}
提前谢谢您!
最佳答案
我认为在audioBufferToNSData中你应该使用frameLength而不是frameCapacity。
let data = NSData(bytes: channels[0], length:Int(PCMBuffer.<strong>frameLength</strong> * PCMBuffer.format.streamDescription.pointee.mBytesPerFrame))
PCMBuffer.frameCapacity -> 可以存储多少 PCMBuffer.frameLength -> PCMBuffer.frameCapacity 有多少是实际有效数据
关于ios - 通过流播放的音频出现抖动/断断续续,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43098349/