热点新闻
iOS 音频采集
2023-07-16 19:48  浏览:48  搜索引擎搜索“爱农网”
温馨提示:信息一旦丢失不一定找得到,请务必收藏信息以备急用!本站所有信息均是注册会员发布如遇到侵权请联系文章中的联系方式或客服删除!
联系我时,请说明是在爱农网看到的信息,谢谢。
展会发布 发布信息 广告合作 软文发布

采集方式

  • 音频采集可以参考上次的视频采集方式,在里面添加相应的音频采集即可,只不过可定制型不强。(视频采集)
  • 使用audioUnit,可定制型强,本文主要介绍这种方式。

实现方式

详细介绍参考(iOS 音频AudioComponentDescription类型设置)

AudioComponentDescription acd; acd.componentType = kAudioUnitType_Output;//类型输出 //acd.componentSubType = kAudioUnitSubType_VoiceProcessingIO;// acd.componentSubType = kAudioUnitSubType_RemoteIO;// acd.componentManufacturer = kAudioUnitManufacturer_Apple;//ios固定这么写,mac不同 acd.componentFlags = 0; acd.componentFlagsMask = 0; //用来描述音频组件 AudioComponent component = AudioComponentFindNext(NULL, &acd); //用来表示特定音频组件的实例 AudioComponentInstance componetInstance; OSStatus status = noErr; //创建实例 status = AudioComponentInstanceNew(component, &componetInstance); UInt32 flagOne = 1; //打开IO,1 是麦克风,0 是扬声器 AudioUnitSetProperty(componetInstance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &flagOne, sizeof(flagOne));

设置输出音频属性

AudioStreamBasicDescription desc = {0}; desc.mSampleRate = 44100;//采样率 desc.mFormatID = kAudioFormatLinearPCM;//类型交错存储PCM desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked; desc.mChannelsPerframe = 2;//声道数 desc.mframesPerPacket = 1;// 非压缩数据,固定填1 desc.mBitsPerChannel = 16;//每声道占的位数 desc.mBytesPerframe = desc.mBitsPerChannel / 8 * desc.mChannelsPerframe; desc.mBytesPerPacket = desc.mBytesPerframe * desc.mframesPerPacket;

设置采集回调

AURenderCallbackStruct cb;//采集回调 cb.inputProcRefCon = (__bridge void *)(self); cb.inputProc = handleInputBuffer; status = AudioUnitSetProperty(componetInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 1, &desc, sizeof(desc));//设置流格式 status = AudioUnitSetProperty(componetInstance, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Global, 1, &cb, sizeof(cb));//设置回调

初始化

AVAudioSession *session = [AVAudioSession sharedInstance]; NSError *error; //设置采样率 [session setPreferredSampleRate:44100 error:&error]; //设置类型 [session setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:&error]; // [session setActive:YES withOptions:kAudioSessionSetActiveFlag_NotifyOthersonDeactivation error:&error]; [session setActive:YES error:&error]; //创建一个线程 taskQueue = dispatch_queue_create("com.mt.audioCapture", NULL);

开始采集

- (void)startRecord{ dispatch_async(taskQueue, ^{ NSLog(@"开始录音"); //每次设置一下状态,防止别的地方被修改或者出现其他情况 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker | AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers error:nil]; AudioOutputUnitStart(self->componetInstance); }); }

结束采集

- (void)endRecord{ dispatch_async(taskQueue, ^{ NSLog(@"停止录音"); AudioOutputUnitStop(self->componetInstance); }); }

采集的回调,数据获取

static OSStatus handleInputBuffer(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberframes, AudioBufferList *ioData) { @autoreleasepool { Test *source = (__bridge Test *)inRefCon; if (!source) { return -1; } AudioBuffer buffer; buffer.mData = NULL; buffer.mDataByteSize = 0; buffer.mNumberChannels = 1; AudioBufferList bufferList; bufferList.mNumberBuffers = 1; bufferList.mBuffers[0] = buffer; static int64_t get_audio_base_timesss = 0; Float64 currentTime = CMTimeGetSeconds(CMClockMakeHostTimeFromSystemUnits(inTimeStamp->mHostTime)); if (get_audio_base_timesss == 0) { get_audio_base_timesss = currentTime; } int64_t pts = (int64_t)((currentTime - get_audio_base_timesss) * 1000); ///获取数据 OSStatus status = AudioUnitRender(source->componetInstance, ioActionFlags, inTimeStamp, inBusNumber, inNumberframes, &bufferList); if ((NO)) { for (int i = 0; i < bufferList.mNumberBuffers; i++) { AudioBuffer ab = bufferList.mBuffers[i]; memset(ab.mData, 0, ab.mDataByteSize); } } if (status == noErr) { // //音频数据 // bufferList.mBuffers[0].mData // //音频长度 // bufferList.mBuffers[0].mDataByteSize // //pts // pts // //转为NSData // [NSData dataWithBytes:bufferList.mBuffers[0].mData length:bufferList.mBuffers[0].mDataByteSize] } return noErr; } }

Demo地址整理后奉上。
有其他不明白的,可以留言,看到就会回复。
如果喜欢,请帮忙点赞。支持转载,转载请附原文链接。

发布人:0029****    IP:120.230.30.***     举报/删稿
展会推荐
让朕来说2句
评论
收藏
点赞
转发