音视频(三):音频采集

428 阅读1分钟

对于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);