iOS - 同时发送和接收数据

标签 ios swift multithreading audio stream

感谢您花时间阅读我的问题。

基本上,我正在使用 MultipeerConnectivity 连接到另一个设备,并且我想在接收数据时将数据流式传输到另一个设备。

我的问题是其中一个设备最终仅发送数据,而另一台设备最终仅接收数据。

这是我的发送方法。该方法是 AVCaptureAudioDataOutputSampleBufferDelegate 的委托(delegate)方法,因此会自动调用。

func captureOutput(_ captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) {
    //-------------------------------------------------------
    // Writing to output stream

    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))

        if (output == -1) {
            let error = outputStream?.streamError
            print("\(#file) > \(#function) > Error on outputStream: \(error!.localizedDescription)")
        }
        else {
            print("\(#file) > \(#function) > Data sent")
        }
    }
}

这是我的接收方法(我确实处理其他流事件,它们与这里无关)。您可以忽略所有与音频相关的内容,它现在不起作用,但这不是我的主要问题。此方法是 OutputStream 的委托(delegate),因此当流中有数据可用时也会自动调用它。

func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
    case Stream.Event.hasBytesAvailable:
        print("\(#file) > \(#function) > New data has arrived")
        readFromStream()
}


func readFromStream() {
    while (inputStream!.hasBytesAvailable) {
        var buffer = [UInt8](repeating: 0, count: 4096)
        let length = inputStream!.read(&buffer, maxLength: buffer.count)

        if (length > 0) {

            if (audioEngine!.isRunning) {
                print("\(#file) > \(#function) > audioEngine is running")
                audioEngine!.stop()
                audioEngine!.reset()
            }
            else {
                print("\(#file) > \(#function) > audioEngine is NOT running")
            }

            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()
        }
    }
}

从这两个方法中,您可以看到我有数据何时传入和何时发送的打印语句。在其中一个设备上,我最终不断地读取数据,但从不发送任何数据,而在另一台设备上,我最终不断地发送数据,但从不接收任何数据。

我想这是因为我没有使用线程..但我从未在 iOS 上使用过线程。如果是这种情况,谁能指导我该怎么做?

如果您需要更多信息,请告诉我。

最佳答案

最终我确实找到了一种使用线程的可行方法:

让streamReceiverQueue = DispatchQueue(标签:“newQueue”,qos:DispatchQoS.userInteractive)

streamReceiverQueue.sync {
    // code here
}

streamReceiverQueue.async {
    // code here
}

关于iOS - 同时发送和接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42098834/

相关文章:

objective-c - UICollectionViewData indexPathForItemAtGlobalIndex 断言失败

ios - 带有静态单元格的 DetailView

汇编代码中的 iOS 12 错误 swift_getAssociatedTypeWitnessSlowImpl EXC_BAD_ACCESS

c - C中的线程本地数据

c - LeaveCriticalSection() 是否将缓存的变量刷新到内存中?

ios - 在连续调用 drawRect 时保留之前的 UIBezierPath 笔划

objective-c - CAShapeLayer 裁剪图像

iphone - iPhone SDK 应用程序中的 NSThread、NSTimer 和 AutoreleasePools

iphone - 如何在我的 iPhone 应用程序中同时支持 iOS 4.X SDK 和 iOS 5 SDK?

ios - 在 Swift 中监听硬件键盘按键