Мое приложение - это в основном телефонный звонок по MultipeerConnectivity.iOS - Потоковое и приемное аудио с устройства на другое заканчивается одной только отправкой, а другая только принимает
Вот как я настраиваю сеанс аудио: Обратите внимание, что записьSession имеет тип AVAudioSession и captureSession имеет тип AVCaptureSession.
func setupAVRecorder() {
print("\(#file) > \(#function) > Entry")
do {
try recordingSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
try recordingSession.setMode(AVAudioSessionModeVoiceChat)
try recordingSession.setPreferredSampleRate(44100.00)
try recordingSession.setPreferredIOBufferDuration(0.2)
try recordingSession.setActive(true)
recordingSession.requestRecordPermission() { [unowned self] (allowed: Bool) -> Void in
DispatchQueue.main.async {
if allowed {
do {
self.captureDevice = AVCaptureDevice.defaultDevice(withMediaType: AVMediaTypeAudio)
try self.captureDeviceInput = AVCaptureDeviceInput.init(device: self.captureDevice)
self.outputDevice = AVCaptureAudioDataOutput()
self.outputDevice?.setSampleBufferDelegate(self, queue: DispatchQueue.main)
self.captureSession = AVCaptureSession()
self.captureSession.addInput(self.captureDeviceInput)
self.captureSession.addOutput(self.outputDevice)
self.captureSession.startRunning()
}
catch let error {
print("\(#file) > \(#function) > ERROR: \(error.localizedDescription)")
}
}
}
}
}
catch let error {
print("\(#file) > \(#function) > ERROR: \(error.localizedDescription)")
}
}
Тогда я получил функцию captureOutput от AVCaptureAudioDataOutputSampleBufferDelegate. В этом методе я записываю данные в outputStream.
func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
var blockBuffer: CMBlockBuffer?
var audioBufferList: AudioBufferList = AudioBufferList.init()
CMSampleBufferGetAudioBufferListWithRetainedBlockBuffer(sampleBuffer, nil, &audioBufferList, MemoryLayout<AudioBufferList>.size, nil, nil, kCMSampleBufferFlag_AudioBufferList_Assure16ByteAlignment, &blockBuffer)
let buffers = UnsafeMutableAudioBufferListPointer(&audioBufferList)
for buffer in buffers {
let u8ptr = buffer.mData!.assumingMemoryBound(to: UInt8.self)
let output = outputStream!.write(u8ptr, maxLength: Int(buffer.mDataByteSize))
}
}
я получаю данные в потоке Func (_ aStream: поток, ручка eventCode: Stream.Event), которая из InputStreamDelegate. В этом методе, когда доступны байты, я вызываю свой метод readFromStream().
func readFromStream() {
while (inputStream!.hasBytesAvailable) {
var buffer = [UInt8](repeating: 0, count: 4096)
let length = inputStream!.read(&buffer, maxLength: buffer.count)
if (length > 0) {
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()
}
}
}
Этот метод, кажется, прекрасно работать, за исключением того, что звук фактически не играл, за исключением, есть только тишина, но это другой вопрос. Моя проблема прямо сейчас заключается в том, что когда я помещаю заявления печати внутри этих методов, одно из устройств постоянно отправляет данные, не получая их, а другое устройство постоянно получает данные, не отправляя их. Я предполагаю, что это связано с тем, что я использую один поток, чтобы следить за отправкой и получением данных, поэтому одно из устройств inputBuffers никогда не очищается.
Мое предположение заключается в том, что исправление заключается в том, чтобы сделать одну нить заботой о записи и отправке, а другую - заботиться о приеме и игре?
Я только хорошо знаком с потоками, но не знаком с тем, как потоки работают в Swift, так что если это так, кто-нибудь может мне помочь в этом?
Большое вам спасибо за ваше время!