AVAudioSession 学习笔记

连接地址 http://www.samirchen.com/ios-avaudiosession-3/

AVAudioSession类由AVFoundation框架引入。每个iOS应用都有一个音频会话。这个会话可以被AVAudioSession类的sharedInstance类方法访问,如下

在获得一个AVAudioSession类的实例后,你就能通过调用音频会话对象的setCategory:error:实例方法,来从IOS应用可用的不同类别中作出选择。下面列出了可供使用的音频会话类别[[AVAudioSession sharedInstance]

setCategory: AVAudioSessionCategoryPlayback

error: &setCategoryErr];

//设置音频是否启用

[[AVAudioSession sharedInstance]

setActive: YES

error: &activationErr];

AVAudioSessionCategorySoloAmbient

这个类别非常像AVAudioSessionCategoryAmbient类别,除了会停止其他程序的音频回放,比如iPod程序。当设备被设置为静音模式,你的音频回放将会停止。

AVAudioSessionCategoryRecord

这会停止其他应用的声音(比如iPod)并让你的应用也不能初始化音频回放(比如AVAudioPlayer)。在这种模式下,你只能进行录音。使用这个类别,调用AVAudioPlayer的prepareToPlay会返回YES,但是调用play方法将返回NO。主UI界面会照常工作。这时,即使你的设备屏幕被用户锁定了,应用的录音仍会继续。

AVAudioSessionCategoryPlayback

这个类别会静止其他应用的音频回放(比如iPod应用的音频回放)。你可以使用AVAudioPlayer的prepareToPlay和play方法,在你的应用中播放声音。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放都会继续。

AVAudioSessionCategoryPlayAndRecord

这个类别允许你的应用中同时进行声音的播放和录制。当你的声音录制或播放开始后,其他应用的声音播放将会停止。主UI界面会照常工作。这时,即使屏幕被锁定或者设备为静音模式,音频回放和录制都会继续。

AVAudioSessionCategoryAudioProcessing

这个类别用于应用中进行音频处理的情形,而不是音频回放或录制。设置了这种模式,你在应用中就不能播放和录制任何声音。调用AVAPlayer的prepareToPlay和play方法都将返回NO。其他应用的音频回放,比如iPod,也会在此模式下停止。

AVAudioSessionCategoryAmbient

这个类别不会停止其他应用的声音,相反,它允许你的音频播放于其他应用的声音之上,比如iPod。你的应用的主UI县城会工作正常。调用AVAPlayer的prepareToPlay和play方法都将返回YES。当用户锁屏时,你的应用将停止所有正在回放的音频。仅当你的应用是唯一播放该音频文件的应用时,静音模式将停止你程序的音频回放。如果正当iPod播放一手歌时,你开始播放音频,将设备设为静音模式并不能停止你的音频回放。

定制 Audio Session 的 Category

2016-07-26

本文内容主要来源于 Working with Categories

对于 Audio Session 来说,与之对应的 Category 是阐释其音频行为的关键信息。比如:你的 App 的声音是否应该受到手机的静音键的控制、你的 App 使不使用音频输入或输出、其他音乐能否和你的 Audio 共存播放等等。

每一种 Category 都指定了是否支持下列这些能力:

  • Interrupts non-mixable apps audio:是否打断不支持混音播放的应用。如果是,则当你的应用的音频开始播放时,则那些不支持混音播放的应用的音频会被打断。
  • Silenced by the Silent switch:是否响应手机静音键。如果是,则当手机静音键被拨至静音状态时,你的音频会被静音。
  • Supports audio input:是否支持音频输入。如果是,你的应用就可以录音。
  • Supports audio output:是否支持音频输出。如果是,你的应用就可以播放音频。

下面是各种 Category 的能力表格:

Category 是否会被静音键或锁屏键静音 是否打断不支持混音播放的应用 是否允许音频输入/输出
AVAudioSessionCategoryAmbient Yes NO 只输出
AVAudioSessionCategoryAudioProcessing - YES 无输入和输出
AVAudioSessionCategoryMultiRoute NO YES 支持输入和输出
AVAudioSessionCategoryPlayAndRecord NO 默认 YES,可重写开关置为 NO 支持输入和输出
AVAudioSessionCategoryPlayback NO 默认 YES,可重写开关置为 NO 只输出
AVAudioSessionCategoryRecord NO(锁屏时依然保持录制) YES 只输入
AVAudioSessionCategorySoloAmbient YES YES 只输出

大部分应用只需要在启动时设置一下 Category 即可,不过你是可以随时修改 Audio Session 的 Category,也可以随时激活和关闭 Audio Session。当你的 Audio Session 是 Inactive 的,Category 的请求会在你激活它时发送,如果是 Active 的,则立即发送。

选择最合适的 Category

每一种 Category 最准确的行为定义是由系统控制而不是你的应用,苹果可能会在将来重新定义不同的 Category 的行为,所以你最好是选择一种与你的应用使用音频方式匹配的 Category 来用。

下面列一下各种 Category 的使用场景:

  • AVAudioSessionCategoryAmbient,只支持音频播放。适用于把音频作为辅助性元素而非不可获取特性的应用,使用这个 Category,你的音频会被静音键和锁屏键静音。
  • AVAudioSessionCategorySoloAmbient,这个是默认使用的 Category,只支持音频播放。音频会被静音键和锁屏键静音。这个 Category 和 AVAudioSessionCategoryAmbient 的唯一不同在于它会打断其他应用的音频播放。
  • AVAudioSessionCategoryPlayback,只支持音频播放。你的音频不会被静音键和锁屏键静音。当你的应用把音频播放作为重要功能时,你可以使用这个 Category。

有一点需要注意的是,当你选择那些支持在静音键切到静音状态以及锁屏键切到锁屏状态下仍然支持你的音频继续播放的 Category 时,你必须在你的应用中开启 Background Audio 的能力,详见UIBackgroundModes。并且,通常你不应该通过 idleTimerDisabled 接口关闭系统的 Sleep Timer。如果你关闭了,那你应该把 idleTimerDisabled 置回 NO,以免你的应用会禁止自动屏幕锁定,毕竟锁屏并不会影响你的音频播放,你干嘛关闭它呢。Sleep Timer 可以确保你的屏幕在用户无操作一段时间后自动变暗并锁定来省电。

  • AVAudioSessionCategoryRecord,只支持音频录制。如果你的应用既要录制还要播放,那你应该用 AVAudioSessionCategoryPlayAndRecord。
  • AVAudioSessionCategoryPlayAndRecord,支持音频播放和录制。音频的输入和输出不需要同步进行,当然也可以同步进行。对于音频通话类应用,可以使用这个 Category。
  • AVAudioSessionCategoryAudioProcessing,只支持离线音频处理。支持离线音频处理,并且不支持播放和录制。
  • AVAudioSessionCategoryMultiRoute,支持音频播放和录制。允许多条音频流的同步输入和输出。比如:USB 和耳麦同时音频输出。

除了 AVAudioSessionCategoryMultiRoute 外,其他的 Category 都遵循 last in wins 原则,即最后接入的音频设备作为输入或输出的主设备。

使用 AVAudioSessionCategoryMultiRoute 来扩展音频选择

AVAudioSessionCategoryMultiRoute 并不是简单的遵循 last in wins 原则,AVAudioSessionCategoryMultiRoute 允许你的使用所有连接的输出接口而不仅是最后连上的接口。比如,当你正在通过 HDMI 输出路径听音频,这时又插上了耳麦,你的应用可以同时在 HDMI 和耳麦都输出音频。

在 AVAudioSessionCategoryMultiRoute 下,你的应用可以发送不同的音频流到不同的输出路径。例如,你的应用可以将一条音频流发送到你的左耳麦,另一条音频流发送到右耳麦,并将第三条流发送到 HDMI 路径。如下图所示:

AVAudioSessionCategoryMultiRoute 支持下列输出组合:

  • USB + 耳麦
  • HDMI + 耳麦
  • LineOut + 耳麦

AVAudioSessionCategoryMultiRoute 支持单输入接口。

设置 Audio Session Category

代码如下:

  1. NSError *setCategoryError = nil;
  2. BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:&setCategoryError];
  3. // BOOL success = [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers | AVAudioSessionCategoryOptionDuckOthers error:&setCategoryError];
  4. if (!success) { /* handle the error in setCategoryError */ }

使用 Mode 来定制 Category

正如使用 Category 可以定制应用的音频行为,我们使用 Mode 则可以定制 Category 的行为。可选的 Mode 有这些:

Mode 兼容的 Category
AVAudioSessionModeDefault All
AVAudioSessionModeVoiceChat AVAudioSessionCategoryPlayAndRecord
AVAudioSessionModeGameChat AVAudioSessionCategoryPlayAndRecord
AVAudioSessionModeVideoRecording AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord
AVAudioSessionModeMoviePlayback AVAudioSessionCategoryPlayback
AVAudioSessionModeMeasurement AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayback
AVAudioSessionModeVideoChat AVAudioSessionCategoryPlayAndRecord

除了这些 Mode 外,有时在定制你的 Category 时,你还需要使用到一些 Option:

Option 说明 兼容的 Category
AVAudioSessionCategoryOptionMixWithOthers 允许和其他音频 mix AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionDuckOthers 智能调低冲突音频音量 AVAudioSessionCategoryPlayAndRecord AVAudioSessionCategoryPlayback AVAudioSessionCategoryMultiRoute
AVAudioSessionCategoryOptionAllowBluetooth 允许蓝牙音频输入 AVAudioSessionCategoryRecord AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryOptionDefaultToSpeaker 默认输出音频到扬声器 AVAudioSessionCategoryPlayAndRecord
  • AVAudioSessionModeDefault,默认模式可以与所有的 Category 兼容使用,并配置设备用于一般用途。
  • AVAudioSessionModeVoiceChat,一般用于 VoIP 类型的应用。这个模式只用于 AVAudioSessionCategoryPlayAndRecord Category。在这个模式下,用于音频的信号会由系统提供的信号处理程序优化,并且这个模式会配置上 AVAudioSessionCategoryOptionAllowBluetooth 这个选项。这个设置下,当系统内置麦克风被使用时,系统会自动选择最佳内置麦克风组合支持语音聊天,从而优化语音聊天体验。
  • AVAudioSessionModeVideoChat,一般用于视频聊天应用,比如 FaceTime。这个模式只用于 AVAudioSessionCategoryPlayAndRecord Category。在这个模式下,用于音频的信号会由系统提供的信号处理程序优化,并且这个模式会配置上 AVAudioSessionCategoryOptionAllowBluetooth 和 AVAudioSessionCategoryOptionDefaultToSpeaker 选项。这个设置下,当系统内置麦克风被使用时,系统会自动选择最佳内置麦克风组合支持视频聊天,从而优化视频聊天体验。

苹果推荐音频或视频聊天应用也使用 Voice-Processing I/O Unit,这个模块提供了一系列的特性来支持 VoIP 类应用。

  • AVAudioSessionModeGameChat,一般用于游戏类应用。使用 GKVoiceChat 对象的应用会自动设置这个模式和 AVAudioSessionCategoryPlayAndRecord Category。这个模式使用的路径参数和 AVAudioSessionModeVideoChat 一致。
  • AVAudioSessionModeVideoRecording,一般用于需要使用摄像头采集视频的应用。这个模式只用于 AVAudioSessionCategoryPlayAndRecord 和 AVAudioSessionCategoryRecord 这两个 Category。在这个模式下,信号会被系统提供的信号处理程序修改。这个模式与 AVCaptureSession API 结合来用可以更好地控制音视频的输入输出路径。比如,通过设置 automaticallyConfiguresApplicationAudioSession 属性可以让系统根据所使用的设备自动选择最佳输出路径。
  • AVAudioSessionModeMeasurement,一般用于那些要最小化系统自带的音视频信号处理流程对信号的影响的应用。这个模式只用于 AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryRecord、AVAudioSessionCategoryPlayback 这几种 Category。输入信号由设备的主麦克风来路由。
  • AVAudioSessionModeMoviePlayback,一般用于播放电影或其他视频的应用。这个模式只用于 AVAudioSessionCategoryPlayback Category。

支持 AirPlay 的 Category 和 Mode

以下 Category 支持「镜像」和「非镜像」版本的 AirPlay:

  • AVAudioSessionCategorySoloAmbient
  • AVAudioSessionCategoryAmbient
  • AVAudioSessionCategoryPlayback

此外:

  • AVAudioSessionCategoryPlayAndRecord 只支持「镜像」版本的 AirPlay。

Mode 只有在和 AVAudioSessionCategoryPlayAndRecord Category 配合使用时才支持 AirPlay,下面的 Mode 只支持「镜像」版本的 AirPlay:

  • AVAudioSessionModeDefault
  • AVAudioSessionModeVideoChat
  • AVAudioSessionModeGameChat

Category 使用调优

你可以有多种方式来调优 Category,下面举几个例子:

  • 允许其他 App 的音频与你的音频 mix 在一起播放。你可以改写 AVAudioSessionCategoryPlayback、AVAudioSessionCategoryPlayAndRecord、AVAudioSessionCategoryMultiRoute 这些 Category 的中断特性。改写时,你需要应用 AVAudioSessionCategoryOptionMixWithOthers 选项到你的 Audio Session。如果你的应用是 mixable 的,当一个 non-mixable 应用的 Audio Session 被激活时,你的应用不会中断它的音频。同样,你的应用的音频在播放时也不会被其他 non-mixable 的应用中断。
  • 将音频输出路径从听筒改到扬声器。当你使用 AVAudioSessionCategoryPlayAndRecord 这个 Category 时,音频默认是从听筒输出的,你可以通过 overrideOutputAudioPort:error: 方法将音频输出路径改到扬声器。
  • 当你的音频播放时,你可以强制其他的音频降低音量。这时候你需要将 AVAudioSessionCategoryOptionDuckOthers 应用到你的 Category 上,使用这个特性的应用需要管理自己的 Audio Session,在播放音频前激活 Audio Session,在播放完成后关闭 Audio Session。

音频录制权限申请

从 iOS7 之后,录制音频的权限需要用户授权才能获得。如果用户不给你权限,那么你录制的就是静音。当你使用一个需要录制权限的 Category 来定制你的 Audio Session 时,系统会自动弹出权限申请提示给用户。

除了让系统自动弹出权限申请提示外,你还可以通过 requestRecordPermission: 方法来向用户请求权限。

时间: 2024-11-09 08:26:45

AVAudioSession 学习笔记的相关文章

IOS开发学习笔记(二)-语音识别(科大讯飞)

上次简单地讲解了如何利用科大讯飞完成语音合成,今天接着也把语音识别整理一下.当然,写代码前我们需要做的一些工作(如申请appid.导库),在上一篇语音合成的文章当中已经说过了,不了解的可以看看我上次的博文,那么这次直接从堆代码开始吧. 详细步骤: 1.导完类库之后,在工程里添加好用的头文件.在视图里只用了一个UITextField显示识别的内容,两个UIButton(一个开始监听语音,一个结束监听),然后引入类.添加代理,和语音合成的一样. MainViewController.h 1 #imp

iOS学习笔记23-音效与音乐

一.音频 在iOS中,音频播放从形式上能够分为音效播放和音乐播放. * 音效: * 主要指一些短音频的播放,这类音频一般不须要进行进度.循环等控制. * 在iOS中.音效我们是使用AudioToolbox.framework框架实现. * 音乐: * 主要指一些较长的音频,通常须要对播放进行精确控制. * 在iOS中,音乐我们是使用AVFoundation.framework框架实现. 二.音效 AudioToolbox.framework框架是一套基于C语言的框架 它的实现原理是将短音频注冊到

IOS开发学习笔记--语音合成(科大讯飞)

      现在语音服务越来越热,我们平时使用的很多软件都带有语音合成和识别功能,用起来也很方便.说到语音服务,Google和微软都提供过API接口,不过笔者要介绍的是国内的智能语音技术提供商---科大讯飞.之前看过一个比较Google.微软和科大讯飞语音识别引擎的博文(http://fqctyj.blog.163.com/blog/static/70843455201361955322797/),有兴趣可以去看看.笔者接触语音服务的时间也不长,对语音服务也不是很了解,但是拆解过科大讯飞的Dem

vector 学习笔记

vector 使用练习: /**************************************** * File Name: vector.cpp * Author: sky0917 * Created Time: 2014年04月27日 11:07:33 ****************************************/ #include <iostream> #include <vector> using namespace std; int main

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则

Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详细,自己在看它的文档和代码时写了一些demo和笔记,还有它实现的原理记录一下 学习Caliburn.Micro要有MEF和MVVM的基础 先说一下他的命名规则和引导类 以后我会把Caliburn.Micro的 Actions IResult,IHandle ICondu

jQuery学习笔记(一):入门

jQuery学习笔记(一):入门 一.JQuery是什么 JQuery是什么?始终是萦绕在我心中的一个问题: 借鉴网上同学们的总结,可以从以下几个方面观察. 不使用JQuery时获取DOM文本的操作如下: 1 document.getElementById('info').value = 'Hello World!'; 使用JQuery时获取DOM文本操作如下: 1 $('#info').val('Hello World!'); 嗯,可以看出,使用JQuery的优势之一是可以使代码更加简练,使开

[原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Activiti 学习笔记记录(三)

上一篇:Activiti 学习笔记记录(二) 导读:上一篇学习了bpmn 画图的常用图形标记.那如何用它们组成一个可用文件呢? 我们知道 bpmn 其实是一个xml 文件

HTML&CSS基础学习笔记8-预格式文本

<pre>标签的主要作用是预格式化文本.被包围在 pre 标签中的文本通常会保留空格和换行符.而文本也会呈现为等宽字体. <pre>标签的一个常见应用就是用来表示计算机的源代码.当然你也可以在你需要在网页中预显示格式时使用它. 会使你的文本换行的标签(例如<h>.<p>)绝不能包含在 <pre> 所定义的块里.尽管有些浏览器会把段落结束标签解释为简单地换行,但是这种行为在所有浏览器上并不都是一样的. 更多学习内容,就在码芽网http://www.