Большое спасибо за это, я знаю, что этот вопрос может быть непростым. Если вам нужно какое-либо разъяснение или я хочу лучше объяснить метод, я с радостью поможем вам.Аудио, записанное с AVCaptureSession, генерирует ошибку «Плохой адрес» при потоковой передаче на другое устройство
Я создаю AVCaptureSession и создаю OutputStream, используя этот метод. OutputStream создается методом MultipeerConnectivity. Более конкретно, метод: startStream (withName: _, fromPeer: _). Если вы не знакомы с этим методом, он возвращает outputStream и отправляет inputStream в peer.
func setupAVRecorder() {
do {
try recordingSession.setCategory(AVAudioSessionCategoryPlayAndRecord)
try recordingSession.setMode(AVAudioSessionModeVoiceChat)
try recordingSession.setPreferredSampleRate(44000.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)
}
catch let error {
print("\(#file) > \(#function) > ERROR: \(error.localizedDescription)")
}
}
}
}
}
catch let error {
print("\(#file) > \(#function) > ERROR: \(error.localizedDescription)")
}
//------------------------------------------------------------------
// Set output stream
if (!outputStreamIsSet) {
do {
outputStream = try self.appDelegate.connectionManager.sessions[sessionIndex!].startStream(withName: "audioStream", toPeer: peerID!)
outputStreamIsSet = true
}
catch let error as NSError {
print("\(#file) > \(#function) > Failed to create outputStream: \(error.localizedDescription)")
endCallButtonIsClicked(endCallButton) // this just ends the stream
}
}
}
Как только пользователи фактически соединяются друг с другом, вызывается метод делегата. В методе делегата мы получаем InputStream, мы открываем выходные и входные потоки, и, наконец, мы начинаем запись, используя метод startRunning():
func startedStreamWithPeer(_ peerID: MCPeerID, inputStream: InputStream) {
if (peerID == self.peerID) {
self.inputStream = inputStream
self.inputStreamIsSet = true
self.inputStream?.delegate = self
self.inputStream?.open()
self.outputStream?.open()
self.captureSession.startRunning()
}
else {
print("\(#file) > \(#function) > Should not print.")
}
}
Вот проблема. Функция captureSession записывает данные в буфер и вызывает метод captureOutput (я считаю, что это метод делегата). Внутри этого метода я пытаюсь преобразовать CMSampleBuffer в UnsafePointer, чтобы я мог записать его в 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 output = outputStream?.write((buffer.mData?.load(as: UnsafePointer<UInt8>.self))!, maxLength: Int(buffer.mDataByteSize))
if (output == -1) {
let error = outputStream?.streamError
print("\(#file) > \(#function) > Error: \(error!.localizedDescription)")
}
}
}
В последнем заявлении печати я получаю сообщение об ошибке, о котором я говорил ранее: «Операция не может быть выполнена. Плохой адрес».
Есть ли у кого-нибудь опыт в записи звука, а затем преобразование этого аудио в объект UnsafePointer?
Спасибо!
Спасибо, @Martin, что исправил проблему. Единственная проблема теперь в том, что метод делегата InputStream «func stream (Stream, eventCode)» не вызывается ... Я полагаю, что это еще одна проблема. – Logan