Android平台远程声音播放及采集方案

1. 远程声音播放方案简介

目前终端常见的声音输出方式可以有喇叭、耳机、蓝牙,并且具备声音输出通道自动切换能力,比如:连接蓝牙耳机,声音切到蓝牙,喇叭静音,断开蓝牙,声音切回喇叭。本方案试着使用TCP/IP技术替代蓝牙传输,实现一种类似于蓝牙音乐的远程声音播放方案。

1.1 应用场景

比如:用户观看电视节目,当手机app连接电视,用户选择手机发声,那么电视机的喇叭自动静音,而将声音转到手机上输出。

1.2 交互简图

2 现有 Android Audio 框架分析

2.1 Audio 架构

Android Audio 框架的核心在 AudioServer,AudioServer 主要由 AudioFlinger 和 AudioPolicyService 组成,其中 AudioFlinger 负责播放及录制,AudioPolicyService 负责多外设之间的调度与切换。

每类音频外设模块(HW Module)会实现一份 Audio HAL,AudioServer 将处理后的音频流发送至 Audio HAL,Audio HAL 再将音频流转发至对应的驱动或外设实现播放。声音录制流程则正好相反。

2.2 AudioServer 启动过程

AudioServer 由 Linux init 进程启动,AudioServer 启动主要做下面几件事:

  1. 创建 AudioFlinger 和 AudioPolicyService。
  2. 解析 Audio Config 文件(audio_policy_configuration.xml),获取支持的音频外设列表及各输入输出通路详细参数。
  3. 根据解析得到的外设列表,加载所有的 Audio HAL 库。
  4. 为所有 output 设备打开 outputStream 并创建 PlaybackThread 线程。
  5. 为所有 input 设备打开 inputStream 并创建 RecordThread 线程。

2.3 AudioTrack 播放过程

Android 声音播放都是通过 AudioTrack 进行,包括 MediaPlayer 最终也是创建 AudioTrack 来播放的。通过 AudioTrack 播放声音主要包括下面几步:

  1. 创建 AudioTrack。
  2. 调用 AudioTrack 的 play() 方法。
  3. 调用 AudioTrack 的 write() 方法写入音频数据。

创建 AudioTrack 时重点是通过 AudioPolicyManager 分配了音频路由通路,同时通知服务端 AudioFlinger 创建对应的 Track,用于接收音频数据。

调用 play() 方法主要是将创建的 Track 加到 mActiveTracks 并激活沉睡的 PlaybackThread 线程。

调用 write() 方法通过共享内存将数据写入服务端 AudioFlinger,PlaybackThread 收到数据激活线程,将数据进行混音等处理再写入对应的 Audio HAL,Audio HAL 再将数据写入驱动或其它外设。

2.4 多 Audio 设备架构及调度

Android 平台允许多种 Audio 设备共存,它们统一由 audio_policy_configuration.xml 配置文件进行描述,AudioServer 启动时会解析此配置文件,并根据描述信息加载对应的 Audio HAL 库,同时为每个输出通路创建 PlaybackThread,为每个输入通路创建 RecordThread 线程。

声音播放时具体选择由何通路输出,由 AudioPolicyService 根据一系列路由策略来切换,例如:当蓝牙耳机连接时,声音切到蓝牙通路输出。当 USB 喇叭连接时,声音切到 USB 通路输出。

3 如何实现声音远程播放及采集

3.1 扩展 IP Sound 声卡

根据 Android 平台的多 Audio 设备架构,我们可以轻松的扩展出任意 Audio 设备。

回到本方案,我们需要实现声音远程播放(包括局域网与广域网),我们选定的通信方式为 TCP/IP 技术,数据通过 TCP/IP 传输不是本方案的关注重点,这里主要讲如何将音频数据截获并通过 TCP/IP 转发至远程终端。

按照以下架构扩展名为 IP Sound Card 的声卡,AudioPolicyService 增加新的策略用于切换到 IP Sound Card 通路,实现 IP Sound Card HAL,HAL 中将收到音频数据,收到数据后通过提前建立好的 TCP/IP 连接发送到远程终端。

3.2 远程声音采集

远程声音采集将远程终端做为麦克风,实现远程声音录制,其数据流程跟播放恰好相反,这里不再赘述。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容

  • 1、电脑开机的那段时间所释放出来的辐射值是最高的,所以按完开机键,请站起来走开,避免接受辐射。而在使用电脑的时候,...
    小杰_327a阅读 296评论 0 0
  • 大扫除,规划3月计划与奖励,还做了个美容,心情美美哒,三月,整装待发(๑>؂<๑)
    漫话时光阅读 192评论 0 3
  • 第一步:先写tableview两个代理 UITableViewDataSource 和 UITableViewDe...
    张入铭阅读 236评论 0 0
  • CSS浮动 首先了解两个概念正常文档流:将窗体自上而下分成一行一行。块元素独占一行;相邻行内元素在每行中按从左到右...
    belly_0阅读 148评论 0 0
  • 著名作家蒋丹说过: "人来世上是个偶然,而走向死亡是个必 然。” 所以,只要我们活一天, 我们就应该用心去感悟生命...
    旖旎i阅读 252评论 2 6