本文内容来自于:Activating an Audio Session

Audio Session 的默认行为

在 iOS 开发中,所有 App 都具有预配置的 Default Audio Session,如下所示:

  • 支持音频播放,但不允许录制
  • 当用户通过静音键切换到静音模式时,你的 App 音频也会静音
  • 当设备锁定时,你的 App 音频也会静音
  • 当你的 App 播放音频时,其它正在播放音频的 App 会被静音

这些行为是由默认的 Category AVAudioSessionCategorySoloAmbient 设定的。通常默认设置是不能满足你的需求的,除非你的 App 对音频的控制场景如下:

  • 你的 App 只使用 System Sound Services 或者 UIKit 中的playInputClick方法来处理音频,而没有用到其他音频相关的 API 时

  • 你的 App 不适用任何音频

系统如何解决竞争的音频需求

随着 App 启动,内置应用 (Message、Music、Safari、the phone)可能在后台运行,每个都有可能产生音频:一条短信到达,10分钟前开始的播客继续播放等等。

如果将设备视为机场,则 App 表示为滑行飞机,该系统可作为一种控制塔。你的 App 可以发出音频请求并声明其所需的优先级,但是在停机场上发生的最终权限来自系统。 你可以使用 Audio Session 与“控制塔”进行通信。 下图说明了一个典型的场景 - 你的 App 要求在 Music App 播放时使用音频。 在这种情况下,你的 App 会中断 Music 应用程序。

值得一提的是,系统永远遵循一个原则:电话的优先级最高

在 AV Foundatin capture 相关的 API 中( AVCaptureDevice,AVCaptureSession)允许你从摄像头和麦克风采集同步的音视频数据。其中表示麦克风的 AVCaptureDevice 对象可以共享你的 AVAudioSession。通常情况下,如果 AVCaptureSession 需要使用麦克风进行音频录制时,它会去修改优化你的 AVAudioSession 配置。如果你不希望这样,则需要设置对应的 AVCaptureSession 对象的 automaticallyConfiguresApplicationAudioSession 属性为 NO 来让 AVCaptureSession 使用你当前的 AVAudioSession 配置而不会修改它。

激活(Activating) 和 停用(Deactivating) Audio Session

虽然AVFoundation播放和录音类别会自动激活音频会话,但手动激活它可以让你的 App 有机会测试激活是否成功。 但是,如果你的 App 具有播放/暂停UI元素,请编写代码,以便用户在会话激活之前必须按播放。 同样,当更改音频会话的活动/非活动状态时,请检查以确保呼叫成功。以优雅地处理系统拒绝激活会话。

系统会停用你的 Audio Session 以进行时钟或日历闹钟或来电。 当用户关闭闹钟或选择忽略电话时,系统可以让你的会话再次变为活动状态。是否在中断结束时重新激活会话取决于应用程序类型。

初始化 Audio Session

代码如下:

AVAudioSession *audioSession = [AVAudioSession sharedInstance];

音量和路径控制

苹果官方推荐使用 MPVolumeView来控制音频音量和路径,MPVolumeView 提供了一个 Slider 来控制音量,提供了一个按钮来供你选择音频输出路径。

你可以通过如下代码来设置音频输出路径到话筒:

[[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:nil];

但苹果推荐你用 MPVolumeView 提供的路径选择按钮来实现音频输出路径切换。

响应远程控制事件

通过响应 Remote Control Events 能让你在播放音视频内容时,可以响应来自锁屏界面、外部设备等 App 外部的控制。

具体参见Remote Control EventsMPNowPlayingInfoCenter Class Reference

激活和关闭 Audio Session

苹果官方建议如果你需要用到 Audio Session,总是应该显示地激活你的 Audio Session。并且参考Setting Preferred Hardware Values来设置相应的硬件参数。这样可以在你使用 Audio Session 前来测试是否能成功激活,以便于做出正确的处理逻辑。

激活 Audio Session 代码如下:

NSError *activationError = nil;
BOOL success = [[AVAudioSession sharedInstance] setActive:YES error:&activationError];// NO -关闭 Yes -激活
if(!success) {/* handle the error in activationError */}

值得注意的是,大部分 App 不需要明确的关闭 Audio Session,除非例外包括 VoIP(Voice over Internet Protocol)Apps、turn-by-turn 导航类 Apps 和 某些播放录制类 Apps。

  • 对于 VoIP 类应用,要确保 Audio Session 仅在处理呼叫接听是 Active 状态,当应用处于后台时,随时准备接听电话。
  • 对于定位于 Recording Category 来使用 Audio Session 的应用,要确保只在录制中设置 Audio Session 为 Active 状态,在录制开始前和录制结束后要确保 Audio Session 为 Inactive 状态以允许其他音频的播放

检查其他音频是否在播放

你可以通过 otherAudioPlaying 来检查是否当前有其他应用的音频正在播放。

例如:你的 App 是一个带有音乐声轨和声音效果的游戏,当一个正在听音乐或Safari播放视频的用户打开你的 App时,iOS中的音频人机界面指南建议你假设用户期望其他音频与游戏音效一起继续播放。

在应用程序委托的 applicationDidBecomeActive:方法中,检查音频会话的secondaryAudioShouldBeSilencedHint属性,以确定音频是否已经播放。 当具有不可混音音频会话的另一个应用程序播放音频时,该值为true。 应用程序应该使用此属性作为一个提示来静音应用程序功能的次要音频。 例如,使用AVAudioSessionCategoryAmbient的游戏可以使用此属性来确定是否应将其音轨静音,同时将其声音效果取消静音。

您还可以监听为AVAudioSessionSilenceSecondaryAudioHintNotification的通知,以确保您的应用程序在可选的辅助音频静音开始或结束时被通知。 此通知仅发送到当前处于前台并具有活动音频会话的注册用户。

results matching ""

    No results matching ""