对于IOS端开发者来说,音频采集可以有两种方法,一个是使用AVFoundation框架,一个是使用FFmpeg框架
一:使用AVFoundation框架进行音频采集
初始化
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
self.audioInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:nil];
self.audioDataOutput = [[AVCaptureAudioDataOutput alloc] init];
[self.audioDataOutput setSampleBufferDelegate:self queue:self.captureQueue];
self.captureSession = [[AVCaptureSession alloc] init];
[self.captureSession beginConfiguration];
if ([self.captureSession canAddInput:self.audioInputDevice]) {
[self.captureSession addInput:self.audioInputDevice];
}
if ([self.captureSession canAddOutput:self.audioDataOutput]) {
[self.captureSession addOutput:self.audioDataOutput];
}
[self.captureSession commitConfiguration];
self.audioConnection = [self.audioDataOutput connectionWithMediaType:AVMediaTypeAudio];
开始采集
[self.captureSession startRunning];
结束采集
[self.captureSession stopRunning];
数据输出代理方法
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection
{
}
二:使用FFmpeg进行音频采集
2.1注册
avdevice_register_all()
2.2获取输入格式对象
AVInputFormat *fmt = av_find_input_format("avfoundation");
if (!fmt) {
NSLog(@"获取输入格式对象失败");
return;
}
2.3创建上下文并打开设备
AVFormatContext *ctx = NULL;
const char *deviceName = ":0";
int ret = avformat_open_input(&ctx, deviceName, fmt, NULL);
if (ret < 0) {
char errbuf[1024] = {0};
av_strerror(ret, errbuf, sizeof (errbuf));
NSLog(@"打开设备失败:%s",errbuf);
return;
}
2.4读取数据
AVPacket *pkt = av_packet_alloc();
while (!self.isStop) {
ret = av_read_frame(ctx, pkt);
if (ret == 0) {
if ([self.delegate respondsToSelector: @selector(recordAudioDidCaptureAudioDataWithPacket:)]) {
[self.delegate recordAudioDidCaptureAudioDataWithPacket:pkt];
}
} else if (ret == AVERROR(EAGAIN)) {
continue;
} else {
char errbuf[1024];
av_strerror(ret, errbuf, sizeof(errbuf));
NSLog(@"av_read_frame error---%s", errbuf);
break;
}
av_packet_unref(pkt);
}
2.5 销毁AVPacket并关闭设备
av_packet_free(&pkt);
avformat_close_input(&ctx);