iOS音视频开发相关文章:
一、使用Audio Queues录制音频
输入端连接的是设备的外部音频硬件部分,比如麦克风。输出端采用回调函数的方式,操作录制的音频数据。
标准的录音流程是六步,但写出一个可用的例子并没有这么复杂,三步就能实现:
1. 初始化操作,设置音频格式、建立audio queue的队列、新建几个buffer(通常是三个)并塞到队列中
- (instancetype)init {
self = [super init];
if (self) {
_audioDescription.mSampleRate = kDefaultSampleRate;
_audioDescription.mFormatID = kAudioFormatLinearPCM;
_audioDescription.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
_audioDescription.mFramesPerPacket = 1;
_audioDescription.mChannelsPerFrame = 1;
_audioDescription.mBitsPerChannel = 16;
_audioDescription.mBytesPerPacket = (_audioDescription.mBitsPerChannel / 8) * _audioDescription.mChannelsPerFrame;
_audioDescription.mBytesPerFrame = _audioDescription.mBytesPerPacket;
AudioQueueNewInput(&_audioDescription, AQInputCallback, (__bridge void *)self, NULL, kCFRunLoopCommonModes, 0, &_audioQueue);
//计算估算的缓存区大小
int frames = (int)ceil(kDefaultBufferDurationSeconds * _audioDescription.mSampleRate); //返回大于或者等于指定表达式的最小整数
int bufferSize = frames *_audioDescription.mBytesPerFrame; //缓冲区大小在这里设置,这个很重要,在这里设置的缓冲区有多大,那么在回调函数的时候得到的inbuffer的大小就是多大。
for (int i = 0; i < QUEUE_BUFFER_SIZE; i ++) {
AudioQueueAllocateBuffer(_audioQueue, bufferSize, &_audioQueueBuffers[i]);
AudioQueueEnqueueBuffer(_audioQueue, _audioQueueBuffers[i], 0, NULL);
}
_recordFile = fopen("/Users/XCHF-ios/Documents/phone.pcm", "w");
}
return self;
}
2. 启动audio queue
- (void)startRecord {
// [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];
// [[AVAudioSession sharedInstance] setActive:YES error:nil];
OSStatus status = AudioQueueStart(_audioQueue, NULL);
if (status != noErr) {
NSLog(@"AudioQueueStart Error: %d", status);
}
}
3. 音频输出回调,输出的buffer使用后,再将该buffer塞到audio queue队列中
static void AQInputCallback (
void * __nullable inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,
UInt32 inNumberPacketDescriptions,
const AudioStreamPacketDescription * __nullable inPacketDescs) {
PCMAudioRecorder *recorder = (__bridge PCMAudioRecorder *)inUserData;
if (inBuffer->mAudioDataByteSize > 0) {
[recorder processAudioBuffer:inBuffer];
}
}
- (void)processAudioBuffer:(AudioQueueBufferRef)buffer {
NSLog(@"processAudioData :%u",buffer->mAudioDataByteSize);
fwrite(buffer->mAudioData, 1, buffer->mAudioDataByteSize, _recordFile);
AudioQueueEnqueueBuffer(_audioQueue, buffer, 0, NULL);
}
二、AVAudioRecorder录制本地音频
AVAudioRecorder的用法比Audio Queue简单一些,但只能录制音频保存在本地。在使用时,只需要对其进行初始化的设置,就能开始录制。
- (AVAudioRecorder *)audioRecorder {
if (!_audioRecorder) {
NSURL *url = [self getSavePath]; //音频的保存路径
NSDictionary *setting = [self getAudioSetting]; //音频的参数设置
NSError *error;
_audioRecorder = [[AVAudioRecorder alloc] initWithURL:url settings:setting error:&error];
_audioRecorder.delegate = self;
_audioRecorder.meteringEnabled = YES;
if (error) {
NSLog(@"创建录音机对象时发生错误,错误信息:%@",error.localizedDescription);
return nil;
}
}
return _audioRecorder;
}
demo下载:iOS音频操作