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'

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容