AVFoundation播放和录制音频

官方文档的摘要部分一开始就提到了AVAudioPlayer.AVAudioRecorder.这两个类

There are two facets to the AVFoundation framework—APIs related to video and APIs related just to audio. The older audio-related classes provide easy ways to deal with audio. They are described in the Multimedia Programming Guide, not in this document.
To play sound files, you can use AVAudioPlayer.
To record audio, you can use AVAudioRecorder.
You can also configure the audio behavior of your application using AVAudioSession; this is described in Audio Session Programming Guide.
翻译:
AVFoundation框架包含视频相关的APIs和音频相关的APIs。旧的音频相关类提供了简便的方法来处理音频。他们在Multimedia Programming中介绍,不在这个文档中。
要播放声音文件,您可以使用 AVAudioPlayer。
要录制音频,您可以使用 AVAudioRecorder。
您还可以使用 AVAudioSession 来配置应用程序的音频行为;这是在 Audio Session Programming Guide 文档中介绍的。

模拟一下场景:
当你在iPhone上点开一首歌曲,音频从内置扬声器中播放出来,此时有电话拨入,音乐会 立即停止并处于暂停状态,此时听到的是手机呼叫的铃声。你挂掉电话。刚才的音乐声再次响起,你又戴上了耳机。当音乐继续播放时音频输出到了耳机里。当听完音乐摘下耳机后,你会发现声音自动转回内置扬声器并处于暂停状态。
从技术角度看,上面描述的场景非常复杂,但从用户的视角看,这一切只是有些神奇而 已。iOS系统提供了一个可管理的音频环境,可以带给所有iOS用 户非常好的用户体验,但这一神奇的过程具体是如何实现的呢?这里会用到音频会话(audio session)

理解音频会话audio session

音频会话在应用程序和操作系统之间扮演着中间人的角色。它提供了一种简单实用的方 法使OS得知应用程序应该如何与iOS音频环境进行交互。你不需要了解与音频硬件交互的细 节,只需要对应用程序的行为进行语义上的描述即可。这一点使得你可以指明应用程序的一 般音频行为,并可以把对该行为的管理委托给音频会话,这样OS系统就可以对用户使用音频 的体验进行最适当的管理。
所有iOS应用程序都具有音频会话,无论其是否使用。默认音频会话来自于以下一些预配置:
● 激活了音频播放,但是音频录制未激活。
● 当用户切换响铃/静音开关到“静音”模式时,应用程序播放的所有音频都会消失。
● 当设备锁屏时,应用程序的音频处于静音状态。
● 当应用程序播放音频时,所有后台播放的音频都会处于静音状态。
默认音频会话提供了很多实用的功能,但重要的一点是要确保它是应用程序当前正确的行为。在大部分应用程序中,默认的行为都是好的,但在开发媒体应用程序时一般是不需要的。幸运的是,通过使用“分类”功能,可以很容易地定制我们的特殊需求。
AVFoundation定义了7种分类来描述应用程序所使用的音频行为。下表列出了这些分类
名称及它们相应的作用和行为。

分类 | 作用 | 是否允许混音 | 音频输入 | 音频输出
---|---
Ambient | 游戏、效率应用程序 | ✔ | | ✔
Solo Ambient (默认) | 游戏、效率应用程序 | | | ✔
Playback | 音频和视频播放器 | 可选 | | ✔
Record | 录音机、音频捕捉 | | ✔ |
Play and Record | VoIP、语音聊天 | 可选 | ✔ | ✔
Audio Processing | 离线会话和处理 | | |
Multi-Route | 使用外部硬件的高级 A/V 应用程序 | | ✔ | ✔

使用 AVAudioPlayer 播放音频

NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"music" withExtension:@"mp3"];
self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
if (self.player) {
    [self.player prepareToPlay];
}
[self.player play];//开始播放
[self.player stop];
[self.player pause];
stop和pause的区别

pause和stop方法在应用程序外面看来实现的功能都是停止当前播放行为。我们调用play方法,通过pause和stop方法停止的音频都会继续播放。这两者最主要的区 别在底层处理上。调用stop方法会撤消调用prepareToPlay时所做的设置,而调用pause方法则 不会。

配置音频会话

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error; //指定为Playback模式,此时把iphone上切换“铃音/静音”的开关关闭,也能听到播放
if (![session setCategory:AVAudioSessionCategoryPlayback error:&error]) {
NSLog(@"Category Error: %@", [error localizedDescription]); }
if (![session setActive:YES error:&error]) {
NSLog(@"Activation Error: %@", [error localizedDescription]);
}
return YES;
}

指定为Playback模式,此时把iphone上切换“铃音/静音”的开关关闭,也能听到播放。
配置音频会话后,如果锁屏的话,播放依旧会停止,如果要继续播放音乐需要target->capabilities 钩上 Backgrounds Modes里面的第一个选项

拔耳机时候的静音

同样通过AVAudioSession来处理,AVAudioSession会在插拔耳机的时候发出通知,根据通知暂停播放就可以。

NSNotificationCenter *nsnc = [NSNotificationCenter defaultCenter];
[nsnc addObserver:self selector:@selector(handleRouteChange:) name:AVAudioSessionRouteChangeNotification object:[AVAudioSession sharedInstance]];

- (void)handleRouteChange:(NSNotification *)notification {
    NSDictionary *info = notification.userInfo;
    AVAudioSessionRouteChangeReason reason = [info[AVAudioSessionRouteChangeReasonKey] unsignedIntValue];
    if (reason == AVAudioSessionRouteChangeReasonOldDeviceUnavailable) {
        AVAudioSessionRouteDescription *previousRoute = info[AVAudioSessionRouteChangePreviousRouteKey];
        AVAudioSessionPortDescription *previousOutput = previousRoute.outputs[0];
        NSString *portType = previousOutput.portType;
        if ([portType isEqualToString:AVAudioSessionPortHeadphones]) {
            if (self.player.isPlaying) {
                [self stop];//当拔出耳机的时候,停止播放
            }
        }
    }
}

拔出耳机的时候通知AVAudioSessionRouteChangeReasonOldDeviceUnavailable,指旧设备不可用,例如耳机拔出。插入耳机的时候通知AVAudioSessionRouteChangeReasonNewDeviceAvailable,指新设备可用,例如耳机插入。可以通过这个来控制音频的播放与暂停。

使用 AVAudioRecorder 播放音频

!!!首先,在degelete里面修改一下AVAudioSession为AVAudioSessionCategoryPlayAndRecord(我一开始忘了改这个,最后写完代码发现在模拟器可以正常录音,在手机上死活不行,找了半天才想起来这里没改
初始化一个AVAudioRecorder

        NSTimeInterval str = [NSDate timeIntervalSinceReferenceDate];
        NSString *fileName = [NSString stringWithFormat:@"%f.caf",str];//在录音的时候caf(Core Audio Format)通常是最好的格式,因为他和内容无关并且可以保存Core Audio支持的任何音频格式
        NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:fileName];
        NSURL *fileUrl = [[NSURL alloc]initFileURLWithPath:path];
//配置
        NSDictionary *settings = @{AVFormatIDKey:@(kAudioFormatAppleIMA4),
                                   AVSampleRateKey:@44100.0f,//码率,目前主流的有44100HZ,22050HZ,16000HZ,8000HZ,码率越高音质越好,文件越大。
                                   AVNumberOfChannelsKey:@1//通道数,1表示单声道,2表示立体声,iphone的话就写1
                                   AVEncoderBitDepthHintKey:@16,//位深为16位
                                   AVEncoderAudioQualityKey:@(AVAudioQualityMax)//声音质量
                                   };
        NSError *error;
       AVAudioRecorder *recorder = [[AVAudioRecorder alloc]initWithURL:fileUrl settings:settings error:&error];
        if (recorder) {
            recorder.delegate = self;
            [recorder prepareToRecord];
        }else{
            NSLog(@"Error: %@",[error localizedDescription]);
        }

然后有三个方法,record,pause,stop

[recorder record];//开始录音
[recorder pause];//暂停
[recorder stop];//停止录音

就ok了,很简单
做了个基本功能都有的录制和播放音频库
cocoapods pod 'XTPlayerRecoder'

你可能感兴趣的:(AVFoundation播放和录制音频)