移动端实现HTML5 mp3录音踩坑指南:系统播放音量变小、一些机型录音断断续续 之 MediaRecorder和AudioWorklet的终极对决
H5录音见坑填坑
在2022-06-19那天,Recorder H5录音开源库(https://github.com/xiangyuecn/Recorder)群里有用户反馈手机上录音有bug,前后反馈过来几段测试过程完整录像;分析后初步发现在他那个手机上表现确实是断断续续的,从而音质非常差;此版本的Recorder采用的浏览器AudioContext.createScriptProcessor 或 AudioWorklet 接口对getUserMedia返回的音频流进行音频采集,在线测试地址:https://xiangyuecn.gitee.io/recorder/。
但用另外一个录音库 collab-project/videojs-record 录制的却没有这个问题,当时初步分析了下一,发现collab-project在手机上使用的是MediaStreamRecorder来录制webm格式音频,底层使用的是浏览器的MediaRecorder接口对getUserMedia返回的音频流进行音频采集。

采用MediaRecorder采集音频
已经知道了浏览器的MediaRecorder接口录制出来的音频不会有ScriptProcessor 或 AudioWorklet 接口录制出来的那种断断续续现象;并且后面两个除了在移动端外,在PC端录制出来的音频也会有爆音的现象,只不过要间隔比较久才偶尔出现,对音质影响不明显,这些问题MediaRecorder统统没有!
因此很有必要使用MediaRecorder来进行录音,来获得更好的音质;ScriptProcessor 和 AudioWorklet 靠边站。
音频格式:WebM和PCM
MediaRecorder一般录制出来的是WebM格式的音视频文件,可通过MediaRecorder.isTypeSupported方法判断支持的格式:
[ //胡乱拼接一些类型 不同浏览器支持的不同
'audio/webm; codecs=opus' //都支持的格式
,'audio/webm; codecs=pcm' //Chrome/Safari支持
,'audio/pcm'
,'audio/webm; codecs=wav'
,'audio/wav'
,'audio/webm; codecs=ogg'
,'audio/ogg' //FireFox支持
].forEach(v=>console.log( MediaRecorder.isTypeSupported(v) +" : "+ v ))
可以看到MediaRecorder对opus编码的WebM格式支持的最好;pcm编码的WebM在Chrome/Safari里得到了支持;wav、ogg不做参考。
Recorder只想得到浏览器采集到的PCM音频数据(易于转换成其他格式,比如mp3、wav),或者能简单的解码得到PCM也行,opus编码的WebM对我们需要实现的录音功能帮助不大;好在还有pcm编码的WebM支持,简单的从WebM容器中提取出PCM即可,目前能支持在Chrome/Safari浏览器上运行就能解决绝大部分用户终端的适配。
从WebM封装容器中提取PCM数据
MediaRecorder录制了audio/webm; codecs=pcm数据后,会根据设定的时长间隔,将音频片段通过回调传给js;好在WebM容器格式简单,很好的做到实时的提取PCM数据。
WebM格式(.webm、.weba)和常见的 .mkv 视频格式都使用的:Matroska开源多媒体容器标准;Matroska封装格式官方文档:https://www.matroska.org/index.html。
学习一下Matroska文档,就很容易提取出WebM中包含的音频轨道数据了,PCM编码的WebM中的音频轨道中的数据一般为32位浮点数pcm数据。
我写了一段解析和提取WebM音频的代码,代码注释里面详细介绍了WebM格式分解过程,源代码在这里 (可以直接测试运行)。
录音的兼容性
MediaRecorder只支持在Chrome/Safari里对getUserMedia返回的音频流录制成audio/webm; codecs=pcm格式,其他浏览器FireFox不支持此编码的录制,需要降级使用 ScriptProcessor 或 AudioWorklet 来对getUserMedia音频流的采集录制。
好在这些功能在Recorder H5录音开源库都是支持的,升级加一个MediaRecorder支持也用不了多少代码,不管是MediaRecorder还是ScriptProcessor 或 AudioWorklet,Recorder统统实时的返回16位PCM数据;有了PCM数据后:实时转码、实时上传、语音识别、音频可视化等等功能均可实现。
所有已正常支持getUserMedia的浏览器均能录音,录音音质根据浏览器支持情况自动优先采用最佳音频采集方案;支持的包括但不限于:Chrome、Firefox、Safari、iOS 14.3+、Android WebView、腾讯Android X5内核(QQ、微信、小程序WebView)、大部分2021年后更新的Android手机自带浏览器。
困扰已久的H5录音时系统播放音量变小的问题
从Recorder开源之初就发现了这个问题,手机上只要打开了录音,同时播放音频的时候,系统声音会非常的小,甚至跑到了听筒播放,但有时又正常 毫无规律,几年一直束手无策,根本没有文档有这方面的描述或文章参考。
在本次Recorder升级支持MediaRecorder的时候,由于需要getUserMedia参数里面设置audio的采样率sampleRate,顺手就把noiseSuppression降噪、echoCancellation回声消除都默认设成了false,没想到测试的时候再也没有系统播放声音变小的现象。
降噪、回声消除这两个参数很早以前就在测试页面中提供了设置选项,不过之前默认是未配置状态,以前也经常设为false进行测试,竟然没有发现这些参数能解决系统音量变小。
最后经过反复测试,只有noiseSuppression+echoCancellation同时生效时,打开录音后再播放音频,系统音量一定会变小,很惨的是getUserMedia只要你没有配置这两个参数,默认就是同时开启的;只要你给这两参数任意一个设为false,或者都设为false,就不会影响手机系统音量。
目前Recorder已默认禁用了noiseSuppression和echoCancellation,使用原声录制(高音甜、中音准、低音沉,总之一句话就是通透 --- 陈永仁(梁朝伟 饰))。
Recorder H5录音开源库:https://github.com/xiangyuecn/Recorder
Recorder H5在线测试页:https://xiangyuecn.gitee.io/recorder/
【完】
移动端实现HTML5 mp3录音踩坑指南:系统播放音量变小、一些机型录音断断续续 之 MediaRecorder和AudioWorklet的终极对决的更多相关文章
- C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式
C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...
- Spring WebSocket踩坑指南
Spring WebSocket踩坑指南 本次公司项目中需要在后台与安卓App间建立一个长连接,这里采用了Spring的WebSocket,协议为Stomp. 关于Stomp协议这里就不多介绍了,网上 ...
- Nuxt.js的踩坑指南(常见问题汇总)
本文会不定期更新在nuxt.js中遇到的问题进行汇总.转发请注明出处,尊重作者,谢谢! 强烈推荐作者文档版踩坑指南,点击跳转踩坑指南 在Nuxt的官方文档中,中文文档和英文文档都存在着不小的差异. 1 ...
- 树莓派4B踩坑指南 - (15)搭建在线python IDE
今天想在树莓派上自己搭一个在线的python IDE,于是找到了一篇教程--Fred913大神的从头开始制作OJ-在线IDE的搭建 自己尝试动手做了一下, 还是发现不少细节需要注意, 记录在此 如果不 ...
- 正则表达式 test 踩坑指南
正则表达式 test 踩坑指南 test 只能使用一次,第二次返回的是错误结果! reg = /edg|edge/g; /edg|edge/g reg.test(`edg`) true reg.tes ...
- Taro 开发踩坑指南 (小程序,H5, RN)
Taro 开发踩坑指南 (小程序,H5, RN) css taro 如何展示多行文本省略号 https://www.cnblogs.com/xgqfrms/p/12569057.html UI 设计稿 ...
- 小程序 & taro 踩坑指南
小程序 & taro 踩坑指南 微信开发者工具, 不支持 react bug https://github.com/NervJS/taro/issues/5042 solution just ...
- Java 热更新 Groovy 实践及踩坑指南
Groovy 是什么? Apache的Groovy是Java平台上设计的面向对象编程语言.这门动态语言拥有类似Python.Ruby和Smalltalk中的一些特性,可以作为Java平台的脚本语言使用 ...
- react基础学习和react服务端渲染框架next.js踩坑
说明 React作为Facebook 内部开发 Instagram 的项目中,是一个用来构建用户界面的优秀 JS 库,于 2013 年 5 月开源.作为前端的三大框架之一,React的应用可以说是非常 ...
随机推荐
- DML数据操作语言
DML数据操作语言 用来对数据库中表的数据记录进行更新.(增删改) 插入insert -- insert into 表(列名1,列名2,列名3...) values (值1,值2,值3...):向表中 ...
- Jmeter之测试片段--include控制器进行接口测试以及管理测试用例
1.线程组--右键添加--测试片段--测试片段 2.在测试片段中进行添加测试用例如下图: 3.通过include控制器进行调用测试片段 (通常使用全局) 选择线程组--右键添加--逻辑控制器--Inc ...
- 且看这个Node全栈框架,实现了个Cli终端引擎,可无限扩充命令集
背景介绍 一般而言,大多数框架都会提供Cli终端工具,用于通过命令行执行一些工具类脚本 CabloyJS提供的Cli终端工具却与众不同.更确切的说,CabloyJS提供的是Cli终端引擎,由一套Cli ...
- np.r_、np.c_、np.concatenate和np.append
np.r_是按行连接两个矩阵,就是把两矩阵上下相加,要求列数相等,最终结果的行数为两个矩阵行数和. np.c_是按列连接两个矩阵,就是把两矩阵左右相加,要求行数相等,最终结果的列数等于两矩阵的列数和. ...
- 前端环境搭建nodejs%VScode
nodejs:https://blog.csdn.net/antma/article/details/86104068VScode:https://code.visualstudio.com/Down ...
- NET架构师的基本职责
NET架构师的基本职责1 职责 对本公司大健康平台提出技术研究及可行性报告; 结合需求设计高扩展性.高性能.安全.稳定.可靠的技术系统; 可以通过配置实现业务需求的变化,跟踪并研究***并应用于产品; ...
- 【万字长文】从零配置一个vue组件库
简介 本文会从零开始配置一个monorepo类型的组件库,包括规范化配置.打包配置.组件库文档配置及开发一些提升效率的脚本等,monorepo 不熟悉的话这里一句话介绍一下,就是在一个git仓库里包含 ...
- 用python随随便便做一个二维码叭~~~
Python是目前最好的编程语言之一.由于其可读性和对初学者的友好性,已被广泛使用. 那么要想学会并掌握Python,可以实战的练习项目是必不可少的. 接下来,我将给大家介绍非常实用的Python项目 ...
- HDFS存储目录分析
一.介绍 HDFS metadata以树状结构存储整个HDFS上的文件和目录,以及相应的权限.配额和副本因子(replication factor)等.本文基于Hadoop2.6版本介绍HDFS Na ...
- 从零开始实现lmax-Disruptor队列(四)多线程生产者MultiProducerSequencer原理解析
MyDisruptor V4版本介绍 在v3版本的MyDisruptor实现多线程消费者后.按照计划,v4版本的MyDisruptor需要支持线程安全的多线程生产者功能. 由于该文属于系列博客的一部分 ...