AVFoundation-播放和录制音频

2019-11-12  本文已影响0人  亡灵诅咒

目标

学习AVAudioPlayer和AVAudioRecorder类来实现音频播放及录制功能

理解音频会话

iOS默认音频会话的预配置

音频会话分类

屏幕快照 2019-11-12 下午10.05.39.png

配置音频会话

    //配置音频会话
    AVAudioSession *session = [AVAudioSession sharedInstance];
    NSError *error = nil;
    if ([session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error]) {
        NSLog(@"AVAudioSession setCategory error = %@",error.userInfo);
    }
    
    if ([session setActive:YES error:&error]) {
        NSLog(@"AVAudioSession setActive error = %@",error.userInfo);
    }
    

AVAudioPlayer播放音频

-(void)adjustPan:(float)pan{
    self.player.pan = pan;
}

-(void)adjustVolume:(float)volume{
    self.player.volume = volume;
}

- (void)adjustRate:(float)rate{
    self.player.rate = rate;
}

-(AVAudioPlayer *)playerWithFile:(NSString *)file{
    NSURL *fileUrl = [NSURL fileURLWithPath:file];
    NSError *error = nil;
    
    AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:fileUrl error:&error];
    if (player) {
        //无限循环
        player.numberOfLoops = -1;
        player.delegate = self;
        //循序修改倍速
        player.enableRate = YES;
        [player prepareToPlay];
    }else{
        if ([self.delegate respondsToSelector:@selector(DKAudioPlayerManagerDidFailedWithError:target:)]) {
            [self.delegate DKAudioPlayerManagerDidFailedWithError:error target:self];
        }
    }
    return player;
}

音频会话通知

        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeRate:) name:AVAudioSessionInterruptionNotification object:[AVAudioSession sharedInstance]];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didChangeRate:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];
通知处理
    NSDictionary *userInfo = noti.userInfo;
    //AVAudioSessionInterruptionTypeKey 确认系统中断类型
    //来电、QQ微信语音、其他音乐软件暂停
    AVAudioSessionInterruptionType reason = [userInfo[AVAudioSessionInterruptionTypeKey] unsignedIntegerValue];
    
    //中断开始
    if (reason == AVAudioSessionInterruptionTypeBegan) {
        if (self.isPlaying) {
            [self stop];
            if ([self.delegate respondsToSelector:@selector(DKAudioPlayerManagerPlayBackStoppedWithTarget:)]) {
                [self.delegate DKAudioPlayerManagerPlayBackStoppedWithTarget:self];
            }
        }
    }else if (reason == AVAudioSessionInterruptionTypeEnded){
        //中断结束
        if (!self.isPlaying) {
            [self play];
            if ([self.delegate respondsToSelector:@selector(DKAudioPlayerManagerPlayBackBeginWithTarget:)]) {
                [self.delegate DKAudioPlayerManagerPlayBackBeginWithTarget:self];
            }
        }
    }
通知处理
    
    //线路切换监听
    AVAudioSessionRouteChangeReason reason1 = [userInfo[AVAudioSessionRouteChangeReasonKey] unsignedIntegerValue];
    //旧音频设备中断原因
    if (reason1 == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
        //线路描述信息
        AVAudioSessionRouteDescription *previousRoute = userInfo[AVAudioSessionRouteChangePreviousRouteKey];
        //第一个输出接口并判断是否是耳机接口
        AVAudioSessionPortDescription *previousOutput = previousRoute.outputs[0];
        NSString *portType = previousOutput.portType;
        if ([portType isEqualToString:AVAudioSessionPortHeadphones]) {
            [self stop];
            //输出到有线耳机
            if ([self.delegate respondsToSelector:@selector(DKAudioPlayerManagerPlayBackStoppedWithTarget:)]) {
                [self.delegate DKAudioPlayerManagerPlayBackStoppedWithTarget:self];
            }
        }
    }

AVAudioRecorder录制音频

初始化AVAudioRecorder实例(1.用于表示音频流写入文件的本地URL,2.包含用于配置录音会话健值信息的字典,3.用于捕获初始化阶段各种错误饿NSError指针)
prepareToPlay,这个方法执行底层Audio Queue初始化的必要过程。该方法还在URL参数指定的位置创建一个文件,将录制启动时的延迟降到最低
音频格式(指定的音频格式一定要和URL参数定义的文件类型兼容)

初始化

-(instancetype)init{
    if (self = [super init]) {

        NSURL *url = [NSURL fileURLWithPath:[NSTemporaryDirectory() stringByAppendingPathComponent:@"memo.caf"]];
        NSDictionary *settings = @{
                                   AVFormatIDKey: @(kAudioFormatAppleIMA4),
                                   AVSampleRateKey:@441000.0f,
                                   AVNumberOfChannelsKey:@1,
                                   AVEncoderBitDepthHintKey:@16,
                                   AVEncoderAudioQualityKey:@(AVAudioQualityMedium)
                                   };
        NSError *error = nil;
        self.recorder = [[AVAudioRecorder alloc]initWithURL:url settings:settings error:&error];
        if (self.recorder) {
            self.recorder.delegate = self;
            self.recorder.meteringEnabled = YES;
            [self.recorder prepareToRecord];
        }else{
            if (self.delegate && [self.delegate respondsToSelector:@selector(DKAudioRecorderManagerDidFailedWithError:)]) {
                [self.delegate DKAudioRecorderManagerDidFailedWithError:error];
            }
        }
    }
    return self;
}

Audio Metering

可以读取音频的平均分贝(averagePowerForChannel:)和峰值分贝(peakPowerForChannel:),[-160dB, 0db] 最小/禁音分贝-- 最大分贝
在读取之前需要设置录音器的meteringEnabled属性才支持对音频进行测量

上一篇 下一篇

猜你喜欢

热点阅读