获取iPhone麦克风数据以便通过Socket进行流传输

4
我希望能从iPhone麦克风获取原始音频数据(以NSData格式),并通过套接字进行流传输。这不是可以使用twilio等服务的情况,因为这是一个研究项目。套接字实现已完成(我可以发送音频文件),但我在获取流式麦克风数据方面遇到了问题。
以下是我的尝试:
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个回答

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)

附言:如果您很小心,想要避免复制,可以使用NSData(bytesNoCopy: data, length: length, freeWhenDone: false)


看起来可能是问题所在。我会测试并回复你! - Connor Hicks
@rythmic-fistman 第一部分完美运行!但是,当我使用第二部分时,我收到以下错误:malloc: *** error for object 0x1035662c0: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug有任何想法为什么会出现这种情况吗? - Connor Hicks
@rythmic-fistman 这是因为我试着使用bytesNoCopy:版本 - 切换回bytes:就解决了! - Connor Hicks
我的错误 - bytesNoCopy: 在完成后调用 free。你需要使用 bytesNoCopy:length:freeWhenDone:。正在更新答案。 - Rhythmic Fistman
1
@rythmic-fistman 太棒了!现在我们只需要让它在另一端播放流媒体音频!:S - Connor Hicks
@rythmic-fistman,你能否为下一部分提供一些指导?https://dev59.com/R5Hea4cB1Zd3GeqPpG4B
  • 谢谢!
- Connor Hicks

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接