WebRTC 提供了视频会议的核心技术,包括音视频的采集、编解码、网络传输、显示等功能,并且还支持跨平台:Windows,Mac,iOS,Android。本文主要介绍 WebRTC 其 iOS 平台的音频会话 AVAudioSession

概念介绍

iOS 音频会话 AVAudioSession 是每一个进行 iOS 音频开发的开发者必须了解的基本概念。音频会话在操作系统 iOS、tvOS、watchOS 中是一项托管服务,系统通过音频会话在应用程序内、应用程序间和设备间管理音频行为。

我们可以使用音频会话来与系统交流,计划如何在应用程序中使用音频。此时,音频会话充当应用程序与操作系统之间的中介,进而充当基础音频硬件之间的中介。我们可以使用它向操作系统传达应用程序音频的性质,而无需详细说明特定行为或与音频硬件的必要交互。将这些细节的管理委派给音频会话,可以确保对用户的音频体验进行最佳管理。

下图出自《Audio Session Programming Guide》,从图中可以看到 AVAudioSession 就是用来管理多个 APP 对音频硬件设备的资源使用。

音频会话的能力

iOS 的音频会话能力主要分为以下几种情况:

  • 配置音频会话

  • 激活音频会话

  • 响应中断

  • 响应路由更改

  • 配置设备硬件

  • 保护用户隐私

具体的详细说明可以参考官网:《Audio Session Programming Guide》,这里就不再全盘细说,本文将主要分析配置音频会话、配置设备硬件两方面的技术细节以及分享实际开发过程中踩过的坑。

配置音频会话

AVAudioSession 的 Category、CategoryOption、Mode 配合使用,不同的应用类型或者使用场景需要搭配不同的组合。

webRTC最全资料提取:https://docs.qq.com/doc/DWHhNTlVtaFJId0ht

Category 主要有以下7种类型,其主要描述以及特点在表中详细介绍:

CategoryOption 主要有以下7种类型:

下图详细列出了 Category、CategoryOption、Mode 配合使用情况:

 分类表达音频角色 

表达音频行为的主要机制是使用音频会话类别。通过设置类别,我们可以指示应用程序是使用音频输入还是音频输出,例如是否需要麦克风的采集、是否需要扬声器的播放等等。下文主要介绍音频会话类别 Category 在不同场景的应用,针对不同的 Category 的区别,可以对应上文表详细查看。

游戏引用的场景

大多数游戏都需要用户交互发生在游戏中。用户调出另一个应用程序或锁定屏幕时,他们不希望该应用程序继续播放。设计游戏时,可以使用 AVAudioSessionCategoryAmbient 或 AVAudioSessionCategorySoloAmbient 类别。

用户控制的播放和录制应用程序的场景

录制应用程序和播放应用程序具有相似的准则。这些类型的应用程序的使用 AVAudioSessionCategoryRecord,AVAudioSessionCategoryPlayAndRecord 或 AVAudioSessionCategoryPlayback 类别。

VoIP 和聊天应用程序的场景

VoIP 和聊天应用程序要求输入和输出路由均可用。这些类型的应用程序使用 AVAudioSessionCategoryPlayAndRecord 类别,并且不会与其他应用程序混合使用。

计量应用的场景

计量应用程序需要应用到输入和输出路径的系统提供的信号处理量最少。设置 AVAudioSessionCategoryPlayAndRecord 类别和测量模式以最小化信号处理。此外,此类型的应用程序不能与其他应用程序混合使用。

播放音频类似浏览器的应用程序场景

社交媒体或其他类似浏览器的应用程序经常播放短视频。他们使用 AVAudioSessionCategoryPlayback 类别,并且不服从铃声开关。这些应用程序也不会与其他应用程序混合使用。

导航和健身应用程序的场景

导航和锻炼应用程序使用 AVAudioSessionCategoryPlayback 或 AVAudioSessionCategoryPlayAndRecord 类别。这些应用的音频通常包含简短的语音提示。播放时,这些提示会中断口语音频(例如播客或有声书),并与其他音频(例如从“音乐”应用中播放)混音。

合作音乐应用的场景

合作音乐应用程序旨在播放其他应用程序时播放。这些类型的应用程序使用 AVAudioSessionCategoryPlayback 或 AVAudioSessionCategoryPlayAndRecord 类别,并与其他应用程序混合使用。

 网易云信的使用情况 

表中为网易云信在不同的使用场景下,Category、Options、Mode 的配置情况:

针对上表的内容,我们也整理了一些常见的问题:

关于大厂面试最常问到的问题和答案:https://docs.qq.com/doc/DWHhNTlVtaFJId0ht

问题一:

相信了解这块的小伙伴们肯定会有疑问,为什么 NERTC 实时音视频 SDK 默认不带 DefaultToSpeaker 选项吗?

答:其实原来我们使用听筒和扬声器切换都是使用 AVAudioSessionCategoryOptions 带AVAudioSessionCategoryOptionDefaultToSpeaker 和 不带AVAudioSessionCategoryOptionDefaultToSpeaker 操作的;当 APP 为扬声器时,AVAudioSessionCategoryOptions 带 AVAudioSessionCategoryOptionDefaultToSpeaker;而 callkit 本身切换听筒和扬声器应该使用的输出路由的变更 overrideOutputAudioPort: 操作的,因此切到听筒 AVAudioSessionPortOverrideNone 时,由于 category 和 categoryOptions 都没有变化,因此无法切换。最后 SDK 内部 AVAudioSessionCategoryOptions 将不再携带 AVAudioSessionCategoryOptionDefaultToSpeaker;同时扬声器和听筒切换都改为 overrideOutputAudioPort: 操作。

问题二:

AVAudioSessionPortOverrideSpeaker 和AVAudioSessionCategoryOptionDefaultToSpeaker 之间的区别是什么呢?

答:区别在于,AVAudioSessionPortOverride 通过调用 overrideOutputAudioPort:,设置的时间要比使用 category 选项 AVAudioSessionCategoryOptionDefaultToSpeaker 更短暂。调用overrideOutputAudioPort:和设置 AVAudioSessionPortOverride 到 AVAudioSessionPortOverrideSpeaker 是暂时压倒一切的输出将其路由到扬声器的方式。遵循后进制胜规则,任何路线更改或中断都将导致音频被路由回到其正常路线。考虑使用overrideOutputAudioPort: 可能用于实现免提电话按钮的方式,在该按钮上您希望能够在扬声器(AVAudioSessionPortOverrideSpeaker)和正常输出路线(AVAudioSessionPortOverrideNone)之间切换。AVAudioSessionCategoryOptionDefaultToSpeaker 修改 AVAudioSessionCategoryPlayAndRecord 类别的路由行为,以便在不使用其他附件(例如耳机)的情况下,音频将始终路由到扬声器,而不是接收器。使用时AVAudioSessionCategoryOptionDefaultToSpeaker,将尊重用户的手势。例如,插入耳机将导致路由更改为耳机麦克风/耳机,拔出耳机将导致路由更改为内置麦克风/扬声器(与内置麦克风/接收器相反)被设置。

问题三:

为什么 NERTC 实时音视频 SDK 会有2种模式?

答:因为 VoIP 情况下会使用AVAudioSessionModeVoiceChat模式,在 RemoteIO 情况下,会使用AVAudioSessionModeDerfault模式。

问题四:

在AVAudioSessionCategoryPlayAndRecord类别下,Mode 有哪些隐藏含义?

答:设置AVAudioSessionModeVoiceChat模式将启用AVAudioSession类别选项AVAudioSessionCategoryOptionAllowBluetooth,从而进一步修改类别的行为,AVAudioSessionCategoryPlayAndRecord以允许将配对的蓝牙免提配置文件(HFP)设备用于输入和输出。设置AVAudioSessionModeVideoChat模式将AVAudioSessionCategoryPlayAndRecord通过设置AVAudioSessionCategoryOptionAllowBluetooth选项和AVAudioSessionCategoryOptionDefaultToSpeaker选项,进一步修改类别的行为。

 网易云音乐使用情况 

正常音乐软件使用 AVAudioSessionCategoryPlayback 类别,在云音乐新上线的“一起听”功能模块会使用实时音视频,因此使用 AVAudioSessionCategoryPlayAndRecord 类别。因为音乐软件对音质要求比较高,所以在蓝牙情况下,会使用 A2DP 模式,使用 AVAudioSessionCategoryOptionAllowBluetoothA2DP。

配置设备硬件

使用音频会话属性,可以在运行时针对设备硬件优化应用程序的音频行为。这样做可以使我们的代码适应正在运行设备的特性,以及用户在应用程序运行时所做的更改(例如插入耳机或将设备对接)。

我们在配置设备硬件 ,可以通过 AVAudioSession 实现相应的属性配置:

  • 为采样率和 I / O 缓冲区持续时间指定首选的硬件设置。

  • 查询许多硬件特性,例如输入和输出延迟,输入和输出通道数,硬件采样率,硬件音量设置以及音频输入的可用性。

想要配置设备硬件,首先需要了解清楚硬件的详细情况,具体可以看下面的2张图,自行测试和查阅文档得出。

iPhone 硬件详情

iPad 硬件详情

问题排查

 音频可用性问题 

音频可用性问题通常指音频的采集和播放是否正常工作,那么会有哪些因素会影响音频的可用性呢?

  • 设备权限:无麦克风权限、没有配置音频后台权限。

  • 被其他声音抢占,如微信通话、打电话中断、siri 中断等。

  • 用户行为:接口调用 mute,修改 AVAudioSession 的 Category 等。

  • 机器故障:硬件启动失败。

为了应对音频问题的排查,我们新增了音频事件上报和音频回路检测功能。

 iOS 音频事件上报类型 

这里我们罗列几种常见的 iOS 音频事件上报的具体类型:

1 音频输入设备变更事件:上报设备名,如【 麦克风 (BuiltInMic)、普通耳机 (HeadsetMic)、蓝牙耳机 (BluetoothHFP)(一般指HFP)】

  • 示例:

    {"InputDeviceChange":"BuiltInMic"}

2 音频输出设备变更事件:上报设备名,如【 扬声器 (BuiltInSpeaker)、听筒 (BuiltInReceiver)、普通耳机 (Headphones)、蓝牙耳机 (BluetoothHFP)、蓝牙耳机 (BluetoothLE)、蓝牙耳机 (BluetoothA2DP)】

  • 示例:

    {"OutputDeviceChange":"BuiltInSpeaker"}

3 音频采集采样率变更事件:上报当前采集采样率

  • 示例:

    {"RecordSampleRateChange":"48000"}

4 音频播放采样率变更事件:上报当前播放采样率

  • 示例:

    {"PlayoutSampleRateChange":"48000"}

5 音频设备异常状态变更事件:上报当前异常状态

  • 示例:

    {"InitRecordingErr\StartRecordingErr\StopRecordingErr...":"-108"}

6 音频系统音量变更事件:上报当前系统音量

  • 示例:

    {"SystemVolumeChange":"70"}

7 音频播放故障检测变更事件:上报当前播放故障次数

  • 示例:

    {"PlayoutGlitch":"3"}

8 音频会话相关变更事件有以下8种情况:

音频打断开始事件  audioInterruptionBegin 0

音频打断结束事件  audioInterruptionEnd 1

音频媒体服务丢失事件  audioMediaServicesWereLost  2

音频媒体服务重置事件 audioMediaServicesWereReset  3

沉默辅助音频提示通知开始事件 audioSilenceSecondaryAudioHintBegin  4

沉默辅助音频提示通知结束事件 audioSilenceSecondaryAudioHintEnd 5

  • 示例:

    {"audioInterruptionBegin\audioInterruptionEnd\...":"0"}

AVAudioSession 相关的 Category 6

  • 示例:

    {"CategoryChange":"AVAudioSessionCategoryPlayAndRecord"}

AVAudioSession 相关的 CategoryOption 7

  • 示例:

    {"CategoryOptionChange":"37"}

AVAudioSession 相关的 Mode 8

  • 示例:

    {"ModeChange":"AVAudioSessionModeVoiceChat"}

 音频回路检测 

我们在使用过程中需要实时观察音频的回路工作状态,我们重点分析以下两种情况:

  • 当我们需要准确了解音频回路的实际工作状态,那么我们可以通过采集音频和播放音频对应的采样率以及单位时间内的音频采样 Samples 偏差,同时也能了解到它向NetEQ(即:音频 Buffer) 索要音频播放数据的节奏。

  • 当播放线程出现卡顿的时候,我们需要实时获取音频播放线程状态以及分析解码、混音等各个阶段的耗时,排查其他环节对于播放线程的影响。

未来展望

产品以及系统也在不断迭代升级,例如:

  • 麦克风的位置选择(Built-in 不可控,因为要完美处理回声问题)和麦克风的极性模式设置(极性模式定义了其对声音相对于声源方向的灵敏度)。

  • 从 iOS 14 和 iPadOS 14 开始,我们现在可以使用支持的设备上的内置麦克风来捕获立体声音频,从而获得非常有沉浸式的录音体验。

我们期望未来可以结合这些优势能力,在音频会话技术上深度挖掘,以提供更好的音频服务。

总结

本文介绍了基于 WebRTC 实现 iOS 音频会话以及管理。一个完整的系统,需要有预警各种异常、处理各种异常情况的能力。由于移动端设备的复杂性,移动端音频预警,自行恢复机制是一个比较核心的技术。

熟练掌握 AVAudioSession 的 Category、CategoryOption、Mode 的各个含义和了解 iPhone、iPad的硬件构造,对于理解 iOS 音频至关重要,上文如有不正确之处,欢迎指出,也欢迎交流。

聊聊​WebRTC之音频会话管理相关推荐

  1. WebRTC 系列之音频会话管理

    导读:WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音对话或视频对话的 API.W3C 和 IETF 在2021年1月26日共同宣布 WebRTC ...

  2. 网易云音乐App 音频会话管理解析

    点击"开发者技术前线",选择"星标????" 让一部分开发者看到未来 导读:WebRTC(Web Real-Time Communication)是一个支持网页 ...

  3. WebRTC 的音频处理流水线

    基于 RTC 场景下要解决的声音的问题,WebRTC 有一个大体如下图所示的音频处理流水线: WebRTC 的音频处理流水线,不是一次性建立起来的,而是分阶段分步骤建立的.整体而言,可以认为这个流水线 ...

  4. 【移动网络】5GC:5G核心网络的会话管理(Session Management)

    Session Management SMF的功能 基本的PDU会话连接 PDU会话建立 隧道与传输连接 PDUs Type SSC (Service and Session Continuity) ...

  5. SSH远程会话管理工具 - screen使用教程

    刚接触Linux时最怕的就是SSH远程登录Linux VPS编译安装程序时(比如安装lnmp)网络突然断开,或者其他情况导致不得不与远程SSH服务器链接断开,远程执行的命令也被迫停止,只能重新连接,重 ...

  6. linux会话管理,Linux 安装 screen 远程会话管理工具

    在使用景文互联的Linux 云服务器产品编译一些环境时,您可能需要花费不少的时间,如果编译时间过长,可能导致当前SSH会话超时,从而断开了SSH,也终止了环境编译的进程,这对用户使用体验非常不利,所以 ...

  7. 会话管理隐患与防御 总结

    什么是会话控制 SESSION COOKIE 服务器记录用户凭证的一个变量.是一个时域(从用户登录到注销的时间域) 指某些网站为了辨别用户身份.进行session跟踪而储存在用户本地终端上的数据(通常 ...

  8. 5G NGC — 会话管理模型 — PDU Session

    目录 文章目录 目录 5G 的会话管理模型 PDU Session PDU Session 的类型 Ethernet Type Unstructured Type DNN 的作用 UE IP 地址的分 ...

  9. 5G NGC — SMF 会话管理功能

    目录 文章目录 目录 SMF SMF 过载控制 NF Services Nsmf_PDUSession Service Create SM Context service operation Upda ...

最新文章

  1. 自动禁止ssh的root登陆
  2. 大神TP_英雄联盟:男枪瞬秒大龙,佐伊遍地TP,新版本BUG谁来监管?
  3. 第一阶段:Java基础之数组
  4. python文件路径操作及pathlib库
  5. x-lite for linux,Linux Lite 4.6正式发布:现基于Ubuntu 18.04.3 LTS
  6. 前端笔记-thymeleaf获取及回显input标签type=date
  7. 数据结构(一)快速排序
  8. 《软件测试技术大全:测试基础 流行工具 项目实战(第3版)》—第1章1.2节软件测试的发展...
  9. python imagedraw line_修复PIL.ImageDraw.Draw.宽线条线条线条
  10. boost::property_tree读取解析ini文件--推荐
  11. 根据主题不同,引用不同的资源文件
  12. 小米蓝牙耳机使用说明书
  13. 大神带你秒懂Modbus通信协议
  14. 使用certbot在nginx搭建HTTPS 以及 阿里云负载均衡HTTPS搭建
  15. python如何模拟键盘输入_用python代码模拟键盘输入
  16. C/C++动态内存申请与释放
  17. 数学脱式计算在线计算机,三年级数学脱式计算.doc
  18. 荒野行动为什么不能获取服务器信息,荒野行动卡在获取服务器信息上了怎么办?(附解决方法)...
  19. MAC、IP、ARP协议
  20. pod install报错 CDN: trunk Repo update failed...couldnt connect to server

热门文章

  1. 什么是linux网络驱动程序,什么是Linux网卡驱动程序?
  2. python爬虫知乎图片_python 爬取知乎图片
  3. 清华大学计算机陈蓓,2010年安徽高考状元文科陈蓓 理科张浩源刘梦醒郝姗姗
  4. 进程和线程的区别,进程间通信方式,怎么选择比较好
  5. 海康威视2017校园秋季招聘技术支持工程师面试经验
  6. 朴素贝叶斯(Naive Bayes model)
  7. matlab simulink 代数环问题解决
  8. GeoGebra 数列极限
  9. 工作八年,分享整合初中高级Java面试题合集附答案(2020年最新版)
  10. 树莓派 Install Home Assistant Core