swift audio stream avaudioplayer

swift - iOS: cómo leer audio de una transmisión y reproducir el audio



stream avaudioplayer (2)

¡Gracias a todos los que se toman el tiempo de leer la pregunta!

Así que hice una transmisión usando MultipeerConnectivity. Puedo grabar audio en un CMSampleBuffer y convertir ese búfer en datos UInt8. Luego envíe esa información a un compañero usando el método:

outputStream!.write(u8ptr, maxLength: Int(buffer.mDataByteSize))

Luego, cuando los datos aparecen en InputStream, se llama al siguiente método:

func stream(_ aStream: Stream, handle eventCode: Stream.Event) {

Tengo instrucciones de impresión, así que esta parte funciona bien. Cuando los datos realmente aparecen, llamo a mi función

func readFromStream() {

Sé que necesito llamar al método inputStream.read para que realmente lea de la transmisión, pero no estoy seguro de cómo leer los datos y luego convertirlos a NSData para que se puedan reproducir con AVAudioPlayer.

(A menos que sepa de una manera mejor y más eficiente)

Esto es lo que tengo hasta ahora, pero no lo he probado y supongo que habrá problemas.

func readFromStream() { var buffer = [UInt8](repeating: 0, count: 1024) while (inputStream!.hasBytesAvailable) { let length = inputStream!.read(&buffer, maxLength: buffer.count) if (length > 0) { if (audioEngine!.isRunning) { audioEngine!.stop() audioEngine!.reset() } print("/(#file) > /(#function) > /(length) bytes read") let audioBuffer = bytesToAudioBuffer(buffer) let mainMixer = audioEngine!.mainMixerNode audioEngine!.connect(audioPlayer!, to: mainMixer, format: audioBuffer.format) audioPlayer!.scheduleBuffer(audioBuffer, completionHandler: nil) do { try audioEngine!.start() } catch let error as NSError { print("/(#file) > /(#function) > error: /(error.localizedDescription)") } audioPlayer!.play() } } }

Basado en lo que tengo, no hay reproducción de audio. Es silencio, pero puedo ver que el audio está siendo recibido por uno de los dispositivos.

Entonces, básicamente, mi pregunta es, ¿cómo convierto este buffer al tipo de datos correcto para que pueda ser reproducido en vivo?

¡Gracias por tu ayuda! Si necesita más información, hágamelo saber.


Para convertir UInt8 en NSData> NSData desde UInt8

Una vez que hayas hecho eso, solo usa AVAudioPlayer

let player = AVAudioPlayer(data: data) player.play()


En lugar de usar CMSampleBuffers, utilicé AVAudioPCMBuffers. Estos se pueden crear grabando desde un AVAudioEngine. Básicamente aquí es cómo convertí el AVAudioPCMBuffer a NSData y viceversa.

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.frameLength * PCMBuffer.format.streamDescription.pointee.mBytesPerFrame)) return data } func dataToPCMBuffer(format: AVAudioFormat, data: NSData) -> AVAudioPCMBuffer { let audioBuffer = AVAudioPCMBuffer(pcmFormat: format, frameCapacity: UInt32(data.length) / format.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 }