阿里云「飞天发布时刻」2024来啦!新产品、新特性、新能力、新方案,等你来探~ 了解详情
写点什么

云控平台的双向音频解决方案

  • 2020-03-04
  • 本文字数:4202 字

    阅读完需:约 14 分钟

云控平台的双向音频解决方案

1. 导读

随着移动互联网的发展,行业内衍生了基于移动平台的各类解决方案。其中,设备规模化管理的云控能力是各互联网公司在设备集群控制背景下的诉求。因此涌现了大批提供类似解决方案的平台。如:阿里系的阿里云 MQC、阿里无线和菜鸟 Nimitz 等,阿里之外的有 Testin、百度 MTC、腾讯 WeTest、华为、三星等等。


目前以上平台在云真机的使用上,都存在一个已知的短板 —— 声音。用户看的到画面,能够响应操作,但是涉及到声音播报、语音交互的场景时则无能为力。尤其对于音乐、视听、短视频、直播客户端等这类多媒体属性强的 App,在云真机的使用场景上是受限最大的。


现在回到我们自己的产品。高德地图车机/镜版(后面统称 Auto)。其中最常见的导航播报、与系统的多媒体混音交互、以及语音助手多轮对话的交互场景中,这些与声音相关的场景占比高达 25%以上。所以解决远程场景下的声音双向交互问题,是云真机要成为一个日常化的生产工具之前必须迈过的坎。


2. 挑战

在远程音频的双向通讯解决方案的背景下,满足基本用户体验的方面也存在以下挑战:


  • 能力:满足所有车载设备的声音场景的双向交互能力(因为车载设备在声音部分比手机具有更高的定制性,在覆盖车载场景后,手机基本可以无缝适配);

  • 延迟:传输延迟低于 500ms(基于一定的网络条件);

  • 体验:无明显卡顿、杂音问题。

3. 设想

首先通过下面的一张图来了解一下我们的需求是什么:



  • 将声音通过电脑传输到远端的车机设备(车机系统能正常解析处理);

  • 将车机通过喇叭播报出的声音传输到用户端。


而实现这两条链路,关键核心的两个因素是:


  • 如何获取和写入音频数据;

  • 如何实现实时的音频数据在车机和用户设备间的传输链路。

4. 音频获取和写入

4.1 Android 系统音频概要

在思考如何进行设备的音频获取前,我们先来了解下 Android 的音频系统架构:



上图描述了音频通信从应用层、Libraries、HAL、到 Driver,最后到硬件模块各层主要实现。而我们也需要从这条链路中去挖掘获取和写入音频数据的思路。


首先,我们考虑的是 Android 对应的音频链路中是否有成熟的支持双向音频的能力。即音频数据在 OS 内部获取到对外传输。

4.2 REMOTE_SUBMIX

API 19 新加的 MediaRecorder. AudioSource. REMOTE_SUBMIX,用于传输系统混音的音频流到远端(在 API 18 也存在,只是属于隐藏属性)。


由于要生效 REMOTE_SUBMIX,需要 Manifest. permission. CAPTURE_AUDIO_OUTPUT 权限,而该权限只有系统组件才具备。也就是如果第三方 App 需要的话,需要进行系统签名或者在烧写 OS 版本时就修改对应的权限。作为系统方是可以这么操作的,但显然对于要适配所有系统方的我们来说不适用。

4.3 软件 hook

考虑到我们拿到的车载设备中,root 比例高达 80%以上。因此我们想从在音频数据传输到底层硬件驱动前进行“截胡”。也就是 hook HAL 定义的往驱动写入和读取对应音频数据的方法,来达到音频数据的双向获取。

4.3.1 hook HAL hardware

hw hook 的是 struct audio_hw_device 的


音频输出:open_output_stream、close_output_stream


音频输入:open_input_stream、close_input_stream


system/lib/hw/audio.primary.*.so (不同的设备有后缀部分差异)

4.3.2 hook tinyalsa

在实际的调研测试中,我们发现并不是每台设备都能通过 hook hw 来获取到对应的声音数据,尤其是车载设备。于是我们又调研了 ALSA(Advanced Linux Sound Architecture)高级 Linux 声音架构。根据官方的推荐,我们选择了具备 GPL-licensed 的 external/tinyalsa


hook tinyalsa.so


音频输出:pcm_open、pcm_close、pcm_write、pcm_mmap_write


音频输入:pcm_open、pcm_close、pcm_read、pcm_mmap_read


system/lib/libtinyalsa.so

4.3.3 问题

在实际摸底验证中,我们发现车机比手机还复杂的原因在于多了功放的概念,而部分车厂选择在设备的 DSP 模块去处理混音。带来的问题就是部分设备如果单纯的通过 hook 播报,对应听到的声音与设备真实通过喇叭播报的效果不同,这也导致我们对于该场景的还原并不真实。


因此,在于 root 设备覆盖不完全且部分设备存在硬件功放处理混音问题的情况下,软件 hook 的方案只能适用于部分设备。

4.3.4 成本

hook 自身也会带来一个问题,即针对不同的车机需要每台都进行 hook 处理,使得 hook 带来的成本过高。需要批量一键 hook 来解决这个问题。


分析到这里,我们回顾下音频传输的链路:



基于以上我们对音频获取的这条传输链路上的分析,现在理论上可行的获取途径,就只有硬件的对接或者具体的接收端(喇叭、蓝牙)。

4.4 usb 音频

硬件对接部分,在云控场景下,我们的设备通常是通过 USB 线束与我们的节点 PC 连接的。因此音频通过 USB 进行传输的链路,也是一个值得探索的方向。


我们知道,Android 设备在连接 usb 时有三种模式:Host、Development、Accessory Mode:


  • 主机模式:可以传输音频,但是 Android 设备作为主机,无法使用 adb 的能力;

  • 开发者模式:具备 adb 的能力,但是没有现成的 USB 音频能力;

  • 配件模式:既保留了 adb 的能力,在 Android4.1 后的配件模式下,Android 也能自动将其音频输出导向到 USB。


思路:通过实现 AOA 协议,作为主机角色的设备,必须具有能够将 Android 设备从开发模式切换到配件模式的主机控制能力,然后主机从适当的端点传输音频数据


该方案的局限性在于:1、单向传输;2、配件模式取决于设备硬件,但并非所有设备都支持。实测过程中,车机支持配件模式的比例很低,绝大多数都被“阉割”了。


综上,我们无法靠单纯的某种 USB 模式来实现音频的双向交互。但如果是手机集群的场景中,这个方案倒是可以作为单向音频传输的一个优选方案。

4.5 蓝牙接收

声音除了可以通过 usb 传输以外,常见的方式还有蓝牙耳机、有线耳机。(这里由于车载设备不存在 3.5mm 孔,所以我们先不讨论有线方式,具体可参考后面「硬件转发」的方案)。


关于蓝牙接收的基本思路就是 PC 端通过安装蓝牙接收器与车机通信。其中蓝牙接收器起到类似于蓝牙耳机的作用。然后对蓝牙接收器的收发数据在 PC 端进行编码处理。


蓝牙耳机:具备了可以听说的能力,也就是双向的音频通信。


摸底验证:部分车机对蓝牙驱动进行了定制,使得蓝牙设备只能作为从设备,无法接入蓝牙耳机功能。我们测试了 35 台,其中 5 台可以用,成功率 14%,收益太低,成本过高。这个方案如果是面向手机集群,倒是一个不错的选择,理论上成功率应该会大大高于车载设备。

4.6 硬件转发

上面提到的有线耳机的思路。在车载设备上,不存在 3.5mm 孔或者 type C 口,而是通过主机与功放、音箱外放装置进行连接。在车辆量产上市前的研发阶段,只是一个主机通过线束连接着喇叭的一个过渡状态。所以我们实际是通过将原本接到喇叭上的音频数据通过一种转换装置转接到 PC 上,在 PC 端进行音频编码处理。


大致的参考示意效果如下:



上述方案的优势在于:


  • 跨平台,不管是 Android、Linux、QNX 或者 iOS 的设备都适用;

  • 解决了混音问题,由于对接的是最终播报出的声音效果,就不存在软件 hook 可能还原不真实的问题;

  • 支持双向音频通信。


缺点:


  • 部分智能车镜设备,由于集成封装性太强,没有暴露出可对接的线束。这类设备不容易通过该方案覆盖;

  • 需要针对车机进行线束定制来实现整体的动态封装性;

  • 需要配套的硬件成本。


硬件转发方案中存在几个方面的问题需要注意,比如失真问题、声卡识别问题、usb 兼容上限、声卡与 ehci、xhci 的兼容性问题以及整体封装设计等等。

4.7 小结

综合以上音频传输的整条链路的所有方案,我们列举对比下这些方案的优劣(特指在车载场景下):


方案优势劣势覆盖率
REMOTE_SUBMIX1、现有API
2、同时利于音视频同步编码
3、无硬件成本
1、需要系统签名或root权限。
2、只有音频获取,无音频输入接口。
3、需要Android API 18以上
4、录音时本地无法播放声音,也就是不能同时本地和远程都有声音
软件hook1、无硬件成本。
2、同时利于音视频同步编码
3、满足目前所有车载的系统版本。
1、需要root权限。
2、需要适配不同版本的Android系统,成本较高。
3、开发难度较大。
4、存在混音
理论100%
实际摸底:真实还原的混音效果的占比52%
usb音频1、现有的技术方案
2、无硬件成本
1、只有音频输出,没有音频输入。
2、只有在配件模式下支持adb和音频通信。
3、车机大部分不支持配件模式。
蓝牙接收1、同时支持音频的输入和输出1、pc端需要加个usb hub接入多个蓝牙接收器,pc端需要开发蓝牙接收转发程序。
2、部分车机对蓝牙驱动进行了定制,使蓝牙设备只能作为从设备,无法接入蓝牙耳机功能。
硬件转发1、跨平台(Android、Linux、QNX)
2、同时支持输入和输出。
3、不存在混音还原的问题。
1、部分车镜设备,由于集成封装性太强,没有暴露出可对接的线束。这类设备无法覆盖。
2、需要针对车机进行线束定制来实现整体的动态封装性
3、需要配套的硬件成本
摸底
前装100%
后装 58%


基于上述情况,考虑到车载的应用场景。最终我们的选型是 「软件 hook」 +「硬件转发」的组合方案。

5. 音频编码传输

关于音频编码传输这部分的内容,行业中已经有较成熟的解决方案,因此,这部分不展开篇幅讨论,我们仅针对一些方案做选型评估:


推流方案音频格式丢包情况延迟情况问题
rmtpaac/mp3无丢包有叠加延迟,延迟高 2-5s
httpflvaac/mp3无丢包有叠加延迟,延迟高 2-5s
rtpaac/mp3存在丢包可能测试环境 vlc软件:
1s延迟为 vlc网络缓冲1s。
通过vlc设置 ctrl+p --> 全部 --> 输入/编解码器 --> 网络缓存(ms) 改为100, 太小容易卡顿
浏览器不支持
webrtcopus存在丢包可能500ms需要配合webrtc服务端
少数部分浏览器不兼容


综上,从我们的应用场景以及高实时性要求考虑,最终选取了 webRtc 的方案。

6. 最终选型

结合音频的获取和写入以及整体编码传输的方案,最终的技术方案选型图如下:



对应流程图中,也顺带涵盖了远程画面传输的视频流优化的参考链路。

7. 总结

通过软硬件组合的方案来实现音频数据读写的能力,是一种基于特定背景条件下解决方案。但其基本推演的思路和策略,也是适用于手机平台的。而其中硬件的解决方案,理论上是适用于 Android、iOS、Linux、QNX 等平台设备的。


相较来说,手机的硬件转发成本更低。而对于软件的方案,实际的播报效果上仍会有很多细节问题,比如播报声音太小,需要对应设备去调节播报音量比例;出现延迟的场景,可能需要修改采样率;或是需要 hook 的自动化来降低成本等等。最终落地到项目中时,还需要考虑各方面的适配成本,确保整体的投入产出比。


2020-03-04 14:481375

评论

发布
暂无评论
发现更多内容

没能进入大数据领域

escray

面试 面经

区块链溯源平台优势,区块链溯源系统解决方案

13530558032

APICloud AVM 多端开发 |外卖 app 开发案例源码教程(上)

YonBuilder低代码开发平台

Vue 大前端 Web Worker 移动终端

2021 云原生走向何处?

云原生实验室

盘点 2020 | 10 天开发前台系统技术系列

老魚

CSS 大前端 全栈 js 盘点2020

PostgreSQL 13 RPM中有哪些新功能?

PostgreSQLChina

数据库 postgresql 开源

软件测试必须掌握的http网络协议知识

测试人生路

软件测试

Demo分享丨看ModelArts与HiLens是如何让车自己跑起来的

华为云开发者联盟

人工智能 智能车 hilens

一个企业用电有多浪费?90后开发者大显身手,让每度电从此更“聪明”!

华为云开发者联盟

AI 物联网 智慧园区

用一把吃鸡的时间,免费上云搭建网站应用

华为云开发者联盟

服务 建站

Java岗四面字节跳动成功之前,我都刷了那些面试题以及做了那些准备!

Java架构之路

Java 程序员 架构 面试 编程语言

姐夫半夜不睡觉,竟躲在厕所看这“57道Redis面试题”?

Java架构之路

Java 程序员 架构 面试 编程语言

扒开 SqlSession 的外衣

田维常

mybatis

一线大厂开源三份JDK+Spring+Mybatis源码笔记

Java架构追梦

Java spring 源码 jdk mybatis

智慧社区综合管理平台搭建,智慧平安城市建设

13530558032

面试必问的 Redis:主从复制

Java架构师迁哥

字节二面跪拜“Redis源码”后,面试官直接推荐这份笔记!真是NB

比伯

Java 编程 架构 面试 程序人生

二十多岁的年纪是怎么成功四面字节跳动,最终拿到offer的?

Java架构之路

Java 程序员 架构 面试 编程语言

高空立体云防控系统搭建,智能化平安小区建设方案

t13823115967

平安小区 智慧平安社区建设

应急指挥中心平台搭建,移动可视化指挥解决方案

t13823115967

可视化数据分析搭建 应急指挥

K8S 资源可视化利器:Kubectl-Graph

郭旭东

Kubernetes Kubernetes Plugin

Flash Player终将成为历史,HTML5正站在舞台的中央

葡萄城技术团队

GitHub标星力推!我掏空了各大搜索引擎,给你整理了188道Java面试题,满满干货记得收藏

Java架构之路

Java 程序员 架构 面试 编程语言

周立齐出任电动车联合创始人:网红经济背后的病态消费心理

石头IT视角

微服务架构思考 - 理清楚,管起来

jorden wang

为什么香港云服务器更适合放新网站

德胜网络-阳

加密猫MIMI系统APP开发|加密猫MIMI软件开发

系统开发

如何通过 Serverless 轻松识别验证码?

Serverless Devs

人工智能 Serverless 云原生

限时!字节Java程序性能优化宝典开源,原来这才叫性能优化

996小迁

程序员 面试 性能优化 笔记

云上可靠性测试:让我们一起给开发找点事儿

华为云开发者联盟

安全 云服务 可靠性

速来围观!阿里P8大牛写出的JDK源码剖析及大型网站技术架构与业务架构融合之道

Java架构之路

Java 程序员 架构 面试 编程语言

云控平台的双向音频解决方案_文化 & 方法_高德技术_InfoQ精选文章