在 iOS 端做音视频相关 App 过程中咱们经常会遇到音频管理的相关问题,下面介绍一下 AVAudiosession 的基本使用,并结合使用腾讯云视频 TXLiteAVSDK 项目中碰到的一些问题场景实现分享。
- 如何实现与其它 App 混音播放?
- 如何打断其它 App 播放,自己 App 独占播放?
- 使用了AVPlayer播放后采集不到麦克风声音?
- 如何实现压低其它 App 播放的声音?
- 结束音频使用如何通知其它 App 继续播放?
AVAudiosession 使用
//设置音频模式
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil];
//激活音频会话
[[AVAudioSession sharedInstance] setActive:YES error:nil];
在 iOS 端使用 AVAudioSession 来管理音频,最简单的使用如上设置下音频模式,然后激活音频会话就可以了。现实情况中不同的 App 场景各不相同,我们通过设置 AVAudioSession 音频会话的 category(模式)和 option(选项)来达到自己想要的效果。
AVAudioSessionCategory 类型
Category类型 | 描述 | 是否支持后台 | 是否遵循锁屏和静音键 |
---|---|---|---|
AVAudioSessionCategoryAmbient | 混合播放 | 否 | 是 |
AVAudioSessionCategorySoloAmbient | 独占播放 | 否 | 是 |
AVAudioSessionCategoryPlayback | 默认独占,可混合播放 | 是 | 否 |
AVAudioSessionCategoryRecord | 录音模式 | 是 | 否 |
AVAudioSessionCategoryPlayAndRecord | 录音和播放 | 是 | 否 |
AVAudioSessionCategoryAudioProcessing | 硬件解码音频,此时不能播放和录制 | 是 | 否 |
AVAudioSessionCategoryMultiRoute | 多种输入输出,例如可以耳机、USB设备同时播放 | 否 | 否 |
AVAudioSessionCategoryOptions 类型
Option选项 | 描述 | 兼容的Category |
---|---|---|
AVAudioSessionCategoryOptionMixWithOthers | 支持和其它APP混合播放 | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionDuckOthers | 调低其他APP音频音量,突出本app的音量 | AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionAllowBluetooth | 支持蓝牙音频输入 | AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionCategoryOptionDefaultToSpeaker | 设置默认输出音频到扬声器,即免提 | AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers | app偶尔的使用音频播放 | AVAudioSessionCategoryPlayback AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryMultiRoute |
AVAudioSessionCategoryOptionAllowBluetoothA2DP | 支持立体声蓝牙 | AVAudioSessionCategoryPlayAndRecord |
AVAudioSessionCategoryOptionAllowAirPlay | 支持远程AirPlay设备 | AVAudioSessionCategoryPlayAndRecord |
使用 TXLiteAVSDK 常见的 AVAudioSession 音频问题
如何修改 TXLiteAVSDK 内部的 AVAudioSession 音频模式?
TXLiteAVSDK 默认推流 TXLivePush 用的音频模式是 AVAudioSessionCategoryPlayAndRecord,拉流播放 TXLivePlayer 用的是 AVAudioSessionCategoryPlayback。想要修改成其它模式,参考如下设置:
1.在推流页面或者播放页面遵循设置 TXLiveAudioSessionDelegate.h 代理;
//设置 TXLiveAudioSessionDelegate 代理
[TXLiveBase setAudioSessionDelegate:self];
2.调用startPush 和 startPlay 会先触发代理方法,在代理方法里面修改所需音频模式。
#pragma TXLiveAudioSessionDelegate
- (BOOL)setCategory:(NSString *)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError {
//设置 Category 音频模式
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:outError];
}
播放音视频的时候需要中断其它App音乐播放
TXLiteAVSDK 默认使用的播放模式是混合播放AVAudioSessionCategoryPlayback + AVAudioSessionCategoryOptionMixWithOthers,如果需要独占和后台播放,可以使用如下设置:
#pragma TXLiveAudioSessionDelegate
- (BOOL)setCategory:(NSString *)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError {
//设置 Category 音频模式
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:outError];
}
直播播放过程中突然出现画面正常,但是没有声音现象
有可能是播放过程中调用操作音频会话deactive了。
//deactive音频会话会导致本App音频无法使用,没有声音。
[[AVAudioSession sharedInstance] setActive:NO error:nil];
直播播放过程中突然使用其它播放器播放,导致直播无法采集音频
直播推流默认设置的是 AVAudioSessionCategoryPlayAndRecord 模式,可以正常录制和播放。如果这个过程使用了其它播放器播放改变了音频模式,可能导致无法正常录制采集。
#pragma TXLiveAudioSessionDelegate
- (BOOL)setCategory:(NSString *)category withOptions:(AVAudioSessionCategoryOptions)options error:(NSError **)outError {
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord withOptions:options error:outError];
}
结束音频使用如何通知其它 App 继续播放?
有种场景是在SDK停止播放调用 stopPlay 之后需要后台其它App继续播放,可以调用以下代码:
//解除激活状态通知其它App继续播放
[[AVAudioSession sharedInstance] setActive:NO withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:nil];
TXLiteAVSDK播放器结束或者暂停播放修改了音频模式
SDK内部在startPlay的时候会先记录当前的音频模式为oldGategory,然后设置成SDK自己需要的Category;在stopPlay的时候会重新还原成记录的那个oldGategory,如果没有修改默认就是 AVAudioSessionCategorySoloAmbient 模式。