imzyf / ios-swift-learning-notes

📝 iOS Swift Learning Notes - see Issues
MIT License
0 stars 0 forks source link

Audio Session #94

Open imzyf opened 6 years ago

imzyf commented 6 years ago

常见的音频相关框架有 AVPlayer,AVAudioPlayer,AVAudioRecorder,AudioQueue 以及 Audio Unit。

另外还有一个和音视频联系非常紧密的一个东西,就是 Audio Session。这个类本身并不参与控制音频的播放,它作为 iOS 设备播放音频策略的一个辅助工具并提供了以下几个主要功能:

决定 APP 的音频共存行为 选择合适的音频设备 音频的中断处理

什么是“APP 的音频共存行为”?你应该注意到,当你在用网易云音乐播放一首喜欢的歌,然后进入酷狗查看最新的华语排行榜时,正在播放的歌曲自动暂停了。于是曰:“网易云和酷狗的音乐不能共存。”共存即同时播放,一般情况下你见不到两个同时播放不同音乐的 APP,同时播放两首歌不是很反人类么?

iOS 系统如何处理具有竞争性的音频需求? 激活 Session iOS 为每一个应用程序提供了一个 Audio Session,每个 Audio Session 单独参与各自 APP 的辅助管理。虽然我们一般用 [AVAudioSession sharedInstance]获取一个音频会话单例,这个单例只存在于我们创建的 APP 中。你可以试着创建两个 APP,在下面的方法中展示各自获取到的 Session,不难看出它们是两个不同的实例。


23456789 | - (void)applicationDidBecomeActive:(UIApplication *)application {    NSString *message = [NSString stringWithFormat:@"%@", [AVAudioSession sharedInstance]];    UIAlertView *a = [[UIAlertView alloc] initWithTitle:nil                                                message:message                                               delegate:nil                                      cancelButtonTitle:@"OK"                                      otherButtonTitles:nil, nil];    [a show];}

应用程序在启动时,iOS 为其提供一个应用内的全局 Session,在默认情况下,系统会自动激活这个 Session,但是苹果推荐我们明确显式地激活它。

23 NSError activationError = nil;BOOL success = [[AVAudioSession sharedInstance] setActive: YES error:&activationError];if (!success) { / handle the error in activationError */ }

为什么需要激活? 假设我正在用网易云音乐听《New Soul》这首歌,然后我切换到酷狗去听《Five Hundred Miles》。这时候酷狗需要向系统请求播放音频,而此时网易云正在欢乐地唱着歌,于是系统的 Core Audio 服务会暂停网易云的音频播放,让酷狗能安静深情地演唱。激活的目的就在于此,禁用其他 APP 的 Audio Session 以使自身的 Audio Session 处于活跃状态。苹果官方文档用了一个飞机场的例子形象地说明了这个问题。

imzyf commented 6 years ago
Categories Description
AVAudioSessionCategoryAmbient 只用于音频播放。
特点是允许其他应用程序播放音频,当 Audio Session 的 Active 设为 NO 时(即不激活 Session),你应该会听到两个 APP 同时播放声音。
注意,使用该 Category 的 APP 的音频会随着屏幕关闭、进入后台和开启静音键而中断。
AVAudioSessionCategorySoloAmbient Audio Session 默认的 Category,只用于音频播放。
当 Category 设置为它时,不管 Session 是否被激活,其他 APP 的音频都会被中断(不允许音频共存)。
注意,使用该 Category 的 APP 的音频会随着屏幕关闭、进入后台和开启静音键而中断。
AVAudioSessionCategoryPlayback 只用于音频播放。
不允许音频共存。
允许后台播放,且忽略静音键作用。
注意,为了支持后台播放,你需要在应用程序的 info.plist 文件中正确设置 Required background modes。
AVAudioSessionCategoryRecord 只用于音频录制。
设置该 Category 后,除了来电铃声,闹钟或日历提醒之外的其它系统声音都不会被播放。该 Category 只提供单纯录音功能。
AVAudioSessionCategoryPlayAndRecord 用于音频播放和录制。
用于既需要播放声音又需要录音的应用,语音聊天应用(如微信)应该使用这个Category。如果你的应用需要用到 iPhone 上的听筒,该 Category是你唯一的选择,在该 Category 下声音的默认出口为听筒(在没有外接设备的情况下)。
AVAudioSessionCategoryAudioProcessing 只用于离线音频处理,即使用硬件编解码器处理音频,如离线音频格式转换。
该音频会话使用期间,不能播放和录制音频。
不过实测中并没有什么卵用,音频还是正常播,How?😧
AVAudioSessionCategoryMultiRoute 用于音频播放和录制。
它允许多个音频输入/输出,比如音频数据同时从耳机和 USB 接口中出来。好像也不怎么常用。