通过Socket获取流式传输的iPhone麦克风数据

时间:2015-11-22 00:44:08

标签: ios swift sockets voip

我想从iPhone麦克风(NSData格式)获取原始音频数据,以便通过套接字流式传输。这不是我可以使用twilio / etc的情况,因为它是一个研究项目。套接字实现已完成(我可以发送音频文件),但我无法获取流式麦克风数据。

这是我的尝试:

class ViewController: UIViewController, AVCaptureAudioDataOutputSampleBufferDelegate
{

    override func viewDidLoad()
    {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.setupMicrophone()
    }

    override func didReceiveMemoryWarning()
    {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func setupMicrophone()
    {
        let session = AVCaptureSession()
        session.sessionPreset = AVCaptureSessionPresetMedium

        let mic = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeAudio)
        var mic_input: AVCaptureDeviceInput!

        let audio_output = AVCaptureAudioDataOutput()
        audio_output.setSampleBufferDelegate(self, queue: dispatch_get_main_queue())

        do
        {
            mic_input = try AVCaptureDeviceInput(device: mic)
        }
        catch
        {
            return
        }

        session.addInput(mic_input)
        session.addOutput(audio_output)

        session.startRunning()
    }

    func captureOutput(captureOutput: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, fromConnection connection: AVCaptureConnection!)
    {
        // Do something here
    }
}

问题:

  • 永远不会调用委托函数。

  • 提供给委托的数据(如果被调用)不是NSData,是否有另一个提供NSData的函数?有没有办法将CMSampleBuffer转换为NSData?

感谢任何帮助。

干杯

1 个答案:

答案 0 :(得分:2)

您的AVCaptureSession超出范围并被取消分配。这就是为什么你的代表没有被召唤的原因。您可以通过将session移动到类范围来解决此问题:

class ViewController: UIViewController, AVCaptureAudioDataOutputSampleBufferDelegate {

   let session = AVCaptureSession()

   override func viewDidLoad() {

获得音频CMSampleBuffer后,您可以将音频数据复制到NSData对象中,如下所示:

let block = CMSampleBufferGetDataBuffer(sampleBuffer)
var length = 0
var data: UnsafeMutablePointer<Int8> = nil
let status = CMBlockBufferGetDataPointer(block!, 0, nil, &length, &data)    // TODO: check for errors
let result = NSData(bytes: data, length: length)

P.S。如果您小心并且想避免复制,可以使用NSData(bytesNoCopy: data, length: length, freeWhenDone: false)