简体   繁体   中英

Stream microphone audio in Swift 5

I have a working connection between 2 IOS-Devices. Sending a live-stream from one camera to the other device works. But now i want to send mic-audio and this does not work. I get no error, but i just receive "click"-noices.

I also can see, that bytes are transmitted, but i do not know, where the failure is.

Below you find the sending and the receiving functions. I also insert the streaming-function, which works fine for transmitting video.

sender:

func recorder() {
        let settings : Dictionary = ["AVSampleRateKey" : 44100.0,
            "AVNumberOfChannelsKey" : 1,
            "AVFormatIDKey" : 1819304813,
            "AVLinearPCMIsNonInterleaved" : 0,
            "AVLinearPCMIsBigEndianKey" : 0,
            "AVLinearPCMBitDepthKey" : 16,
            "AVLinearPCMIsFloatKey" : 0]

        audioFormat = AVAudioFormat.init(settings: settings)

        audioEngine = AVAudioEngine.init()
        audioEngine?.inputNode.installTap(onBus: 0, bufferSize: 4410, format: audioEngine?.inputNode.outputFormat(forBus: 0), block: {buffer, when in         
            let audioBuffer = buffer.audioBufferList.pointee.mBuffers
            let data : Data = Data.init(bytes: audioBuffer.mData!, count: Int(audioBuffer.mDataByteSize))
            let arraySize = Int(buffer.frameLength)
            let samples = Array(UnsafeBufferPointer(start: buffer.floatChannelData![0], count:arraySize))
            self.streamData(data: data, len: 4410)
        })

        // Start audio engine
        self.audioEngine?.prepare()
        do {
            try self.audioEngine?.start()
        }
        catch {
            NSLog("cannot start audio engine")
        }
        if(self.audioEngine?.isRunning == true){
            NSLog("Audioengine is running")
        }
    }

sender streamData (working fine for eg video)

func streamData(data : Data, len : Int)
    {
        var baseCaseCondition : Bool = false
        var _len : Int = len
        var _byteIndex : Int = 0
        func recursiveBlock(block: @escaping (()->Void)->Void) -> ()->Void {
            return { block(recursiveBlock(block: block)) }
        }
        let aRecursiveBlock :()->Void = recursiveBlock {recurse in
            baseCaseCondition = (data.count > 0 && _byteIndex < data.count) ? true : false
            if ((baseCaseCondition)) {
                _len = (data.count - _byteIndex) == 0 ? 1 : (data.count - _byteIndex) < len ? (data.count - _byteIndex) : len
                NSLog("START | byteIndex: %lu/%lu  writing len: %lu", _byteIndex, data.count, _len)
                var bytes = [UInt8](repeating:0, count:_len)
                data.copyBytes(to: &bytes, from: _byteIndex ..< _byteIndex+_len )
                _byteIndex += (self.outputStream?.write(&bytes, maxLength: _len))!
                NSLog("END | byteIndex: %lu/%lu wrote len: %lu", _byteIndex, data.count, _len)
                recurse()
            }
        }
        if (self.outputStream!.hasSpaceAvailable){
            aRecursiveBlock();
        }
    }

receiver:

func stream(_ aStream: Stream, handle eventCode: Stream.Event) {
...
    case Stream.Event.hasBytesAvailable:
      var thePCMBuffer : AVAudioPCMBuffer = AVAudioPCMBuffer.init(pcmFormat: (self.audioEngine?.inputNode.outputFormat(forBus: 0))!, frameCapacity: AVAudioFrameCount(mlen))!
      thePCMBuffer.frameLength = thePCMBuffer.frameCapacity
      let channels = UnsafeBufferPointer(start: thePCMBuffer.floatChannelData, count: Int(thePCMBuffer.format.channelCount))
      _ = mdata?.copyBytes(to: UnsafeMutableBufferPointer(start: channels[0], count: Int(thePCMBuffer.frameLength)))

      if((self.player?.isPlaying) != nil){
        DispatchQueue.global(qos: .background).async {
          // Background Thread
          DispatchQueue.main.async {
            // Run UI Updates
            self.player?.scheduleBuffer(thePCMBuffer, completionHandler: {
               NSLog("Scheduled buffer")
               NSLog("\(self.player!.isPlaying)")
               let arraySize = Int(thePCMBuffer.frameLength)
               let samples = Array(UnsafeBufferPointer(start: thePCMBuffer.floatChannelData![0], count:arraySize))
               for sample in samples{
                  NSLog("\(sample)")
               }
            })
          }
        }
      }
     }
   mdata = Data.init()
   mlen = DATA_LENGTH
   }
  break;
  ...
}

Found the solution i guess. I tried with one simulator and one real device. Now i read, that there es a problem because of different sample-rates. Running on 2 devices (or 2 simulators) just works fine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM