I would like to get raw audio data from the iPhone mic (in NSData format) to stream over a socket. This is not a situation where I can use twilio/etc, as it is a research project. The socket implementation is done (I can send audio files), but I'm having trouble getting the streaming mic data.
Here is my attempt:
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
}
}
Problems:
The delegate function is never called.
The data given to the delegate (if it were being called) is not NSData, is there another function that would provide NSData? Is there a way to convert CMSampleBuffer to NSData?
Any help is appreciated.
Cheers
Your AVCaptureSession
is going out of scope and being deallocated. That's why your delegate isn't being called. You can fix this by moving session
to class scope:
class ViewController: UIViewController, AVCaptureAudioDataOutputSampleBufferDelegate {
let session = AVCaptureSession()
override func viewDidLoad() {
Once you have an audio CMSampleBuffer
, you can copy the audio data into an NSData
object like this:
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. if you're careful and want to avoid copying, you can use NSData(bytesNoCopy: data, length: length, freeWhenDone: false)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With