macOS采集/录制系统音频数据-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

macOS采集/录制系统音频数据

简介:   PC端音视频相关应用往往会涉及到系统音频采集相关需求。例如音视频通信应用在屏幕共享场景下,用户除了共享屏幕内容之外,往往需要共享音频数据。目前macOS没有系统API可以直接获取输出到播放设备的音频数据,这就需要通过别的办法来采集系统音频。由于macOS开发相关资料较少,完成这个需求也花了点时间,在这里将思路做个分享,希望能帮助到有这方面需求的朋友。 技术背景 macOS音频设

 

PC端音视频相关应用往往会涉及到系统音频采集相关需求。例如音视频通信应用在屏幕共享场景下,用户除了共享屏幕内容之外,往往需要共享音频数据。目前macOS没有系统API可以直接获取输出到播放设备的音频数据,这就需要通过别的办法来采集系统音频。由于macOS开发相关资料较少,完成这个需求也花了点时间,在这里将思路做个分享,希望能帮助到有这方面需求的朋友。

技术背景

macOS音频设备管理

macOS支持管理多个音频输入输出设备,可以使用“音频 MIDI 设置”来设置如麦克风和多声道音频接口。

音频 MIDI 设置”界面如上图所示,左侧列表展示了所有音频输入输出设备,例如内建麦克风、扬声器、AirPods、通过数据线连接端iPhone设备,右侧界面支持调节设备端具体参数,例如音量等。

我们可以通过右键选择设备,将其设为系统默认的输入输出设备。设为默认设备后,设备列表上会有一个小图标显示,同时,系统会默认在对应的设备上采集、播放音频数据。当然,应用也依然可以选择特定设备采集、播放音频,例如Abode公司的Audition中可以通过设置选择输入输出设备。

switchaudio-osx

switchaudio-osx是一款开源项目,支持命令行设置macOS默认输入输出音频设备。这个开源项目为我们通过代码切换系统音频设备提供了极大帮助。

项目地址:https://github.com/deweller/switchaudio-osx

KEXT内核扩展

KEXT是macOS的内核扩展程序,通常用于系统驱动程序。内核扩展运行于内核态,支持动态加载。

我们可以在Xcode中选择“general kernel extension”创建内核扩展,基于IOKit接口实现驱动程序,生成的产物以kext作为后缀名。

加载驱动需要首先将kext文件拷贝到系统目录(需要管理员权限):

/Library/Extensions 

加载驱动:

sudo kextload /path/to/kext.kext

卸载驱动:

sudo kextunload /path/to/kext.kext

Soundflower

Soundflower是mac端开源的kext内核扩展程序,它虚拟了一套音频采集、播放设备驱动,直接将播放数据传给采集设备,实现音频数据环路。通过将系统默认输入输出设备设置为Soundflower,就可以采集到系统播放的音频数据。

项目地址:https://github.com/RogueAmoeba/Soundflower-Original

 

方案实现

介绍完以上的技术背景,其实就可以设计出macOS系统音频数据采集方案:

如上图所示,用户App通过mac系统播放音频。

我们可以在启动系统音频采集功能时将系统音频播放设备设置为Soundflower虚拟扬声器,同时在App中将输入设为Soundflower虚拟麦克风和硬件麦克风,将混音后的音频数据输出到硬件扬声器。关闭系统音频采集功能将系统设置还原。理论上,这就已经可以满足我们的需求了。

 

关键调用流程

为了实现以上方案,有以下关键调用流程:

  1. 第一次调用内录接口时,请求管理员权限,将Soundflower.kext内核扩展拷贝到系统目录
  2. 调用kextload命令加载Soundflower.kext
  3. 将系统默认音频播放设备设置为Soundflower虚拟扬声器
  4. App中将音频采集设备设置为Soundflower虚拟麦克风
  5. App中如果有硬件麦克风采集需求,则另起一路硬件麦克风采集
  6. App中将音频播放设备设置为硬件扬声器

需要关闭该功能时,需要执行如下调用流程:

  1. 将系统默认输入输出设备还原
  2. 卸载Soundflower.kext

 

以上调用流程并不复杂,关键代码都可以从以上介绍的开源项目中找到参考,需要注意一下几点:

加载/卸载kext需要系统提权,macOS提权可以选择AuthorizationRef或者苹果官方推荐的SMJobBless

切换系统默认音频设备代码实现可以参考switchaudio-osx项目中audio_switch.c相关代码

至于mac端音频采集播放的代码实现就相对比较复杂了,不过幸运的是,谷歌WebRTC项目中audio_device_mac.cc已经有了一套实现

 

总结

文本提供了macOS采集/录制系统音频数据的一种实现思路。具体代码实现过程中,还是有很多工作需要做的,例如系统提权如果要做的比较友好就需要用到SMJobBless启动守护进程来实现。当然,这属于另外一个话题了,在此不再赘述。

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章