が、私は簡単に私のアプリのすべての要素の上に移動します吃音/ジッタされたストリーム上で再生されている:オーディオは
私は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はNSDataのにAVAudioPCMBufferに変換ちょうど方法であり、ここにある:
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
}
ありがとうございます!
どのくらいPCMBuffer.frameCapacityの私はそれが動作するかどうかを確認するために、これをしようとします、しかし、私は前にこれらの値を印刷していて、それらは同じであった(どちらも4410)。また、実際には、オーディオを基本的に記録し、AVAudioPCMBufferからNSDataに変換し、NSDataをAVAudioPCMBufferに変換して再生するテストプロジェクトを作成しました。私は私の変換をテストするためにこれを作ったし、オーディオはうまく再生されました。 – Kember
私はこれを試してみましたが、残念ながらそれは動作しません。しかし、問題を調べるのを手伝ってくれてありがとう。 – Kember