html5录音怎么保存到本地,详解HTML5 录音遇到的坑

本文恩主要介绍了详解HTML5 录音的踩坑之旅,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧,希望能帮助到大家。

说实话,一开始都没接触过 HTML5 的 Audio API,而且要基于在我们接手前的代码中进行优化。当然其中也踩了不少坑,这次也会围绕这几个坑来说说感受(会省略一些基本对象的初始化和获取,因为这些内容不是这次的重点,有兴趣的同学可以自行查找 MDN 上的文档):

调用 Audio API 的兼容性写法

获取录音声音的大小(应该是频率)

暂停录音的兼容性写法

获取当前录音时间

录音前的准备

开始录音前,要先获取当前设备是否支持 Audio API。早期的方法 navigator.getUserMedia 已经被 navigator.mediaDevices.getUserMedia 所代替。正常来说现在大部分的现代浏览器都已经支持 navigator.mediaDevices.getUserMedia 的用法了,当然 MDN 上也给出了兼容性的写法

const promisifiedOldGUM = function(constraints) {

// First get ahold of getUserMedia, if present

const getUserMedia =

navigator.getUserMedia ||

navigator.webkitGetUserMedia ||

navigator.mozGetUserMedia;

// Some browsers just don't implement it - return a rejected promise with an error

// to keep a consistent interface

if (!getUserMedia) {

return Promise.reject(

new Error('getUserMedia is not implemented in this browser')

);

}

// Otherwise, wrap the call to the old navigator.getUserMedia with a Promise

return new Promise(function(resolve, reject) {

getUserMedia.call(navigator, constraints, resolve, reject);

});

};

// Older browsers might not implement mediaDevices at all, so we set an empty object first

if (navigator.mediaDevices === undefined) {

navigator.mediaDevices = {};

}

// Some browsers partially implement mediaDevices. We can't just assign an object

// with getUserMedia as it would overwrite existing properties.

// Here, we will just add the getUserMedia property if it's missing.

if (navigator.mediaDevices.getUserMedia === undefined) {

navigator.mediaDevices.getUserMedia = promisifiedOldGUM;

}

因为这个方法是异步的,所以我们可以对无法兼容的设备进行友好的提示

navigator.mediaDevices.getUserMedia(constraints).then(

function(mediaStream) {

// 成功

},

function(error) {

// 失败

const { name } = error;

let errorMessage;

switch (name) {

// 用户拒绝

case 'NotAllowedError':

case 'PermissionDeniedError':

errorMessage = '用户已禁止网页调用录音设备';

break;

// 没接入录音设备

case 'NotFoundError':

case 'DevicesNotFoundError':

errorMessage = '录音设备未找到';

break;

// 其它错误

case 'NotSupportedError':

errorMessage = '不支持录音功能';

break;

default:

errorMessage = '录音调用错误';

window.console.log(error);

}

return errorMessage;

}

);

一切顺利的话,我们就可以进入下一步了。

(这里有对获取上下文的方法进行了省略,因为这不是这次的重点)

开始录音、暂停录音

这里有个比较特别的点,就是需要添加一个中间变量来标识是否当前是否在录音。因为在火狐浏览器上,我们发现一个问题,录音的流程都是正常的,但是点击暂停时却发现怎么也暂停不了,我们当时是使用 disconnect 方法。这种方式是不行的,这种方法是需要断开所有的连接才可以。后来发现,应该增加一个中间变量 this.isRecording 来判断当前是否正在录音,当点击开始时,将其设置为 true ,暂停时将其设置为 false 。

当我们开始录音时,会有一个录音监听的事件 onaudioprocess ,如果返回 true 则会将流写入,如果返回 false 则不会将其写入。因此判断 this.isRecording ,如果为 false 则直接 return

// 一些初始化

const audioContext = new AudioContext();

const sourceNode = audioContext.createMediaStreamSource(mediaStream);

const scriptNode = audioContext.createScriptProcessor(

BUFFER_SIZE,

INPUT_CHANNELS_NUM,

OUPUT_CHANNELS_NUM

);

sourceNode.connect(this.scriptNode);

scriptNode.connect(this.audioContext.destination);

// 监听录音的过程

scriptNode.onaudioprocess = event => {

if (!this.isRecording) return; // 判断是否正则录音

this.buffers.push(event.inputBuffer.getChannelData(0)); // 获取当前频道的数据,并写入数组

};

当然这里也会有个坑,就是无法再使用,自带获取当前录音时长的方法了,因为实际上并不是真正的暂停,而是没有将流写入罢了。于是我们还需要获取一下当前录音的时长,需要通过一个公式进行获取

const getDuration = () => {

return (4096 * this.buffers.length) / this.audioContext.sampleRate // 4096为一个流的长度,sampleRate 为采样率

}

这样就能够获取正确的录音时长了。

结束录音

结束录音的方式,我采用的是先暂停,之后需要试听或者其它的操作先执行,然后再将存储流的数组长度置为 0。

获取频率

getVoiceSize = analyser => {

const dataArray = new Uint8Array(analyser.frequencyBinCount);

analyser.getByteFrequencyData(dataArray);

const data = dataArray.slice(100, 1000);

const sum = data.reduce((a, b) => a + b);

return sum;

};

其它

HTTPS:在 chrome 下需要全站有 HTTPS 才允许使用

微信:在微信内置的浏览器需要调用 JSSDK 才能使用

音频格式转换:音频格式的方式也有很多了,能查到的大部分资料,大家基本上是互相 copy,当然还有一个音频质量的问题,这里就不赘述了。

结语

这次遇到的大部分问题都是兼容性的问题,因此在上面踩了不少坑,尤其是移动端的问题,一开始还有出现因为获取录音时长写法错误的问题,导致直接卡死的情况。这次的经历也弥补了 HTML5 API 上的一些空白,当然最重要的还是要提醒一下大家,这种原生的 API 文档还是直接查看 MDN 来的简单粗暴!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/521479.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c++检测输入是否为数字_Go64 for Mac(检测应用是否为64位)

“一种快速的方法来全面了解您的64位应用程序兼容性,并在安装macOS Catalina之前避免意外。”Go64 可以帮你检测出你的应用是否 64 位,以及软件版本号,开发商以及官网,甚至可以为你计算出软件升级所需要花费的金额。应用介绍从 ma…

阿里云DDoS高防 - 访问与攻击日志实时分析(二)

摘要: 本文介绍了如何配置DDoS日志分析功能,结合实际场景详细介绍了如何使用日志对DDoS访问与攻击日志进行分析与图形化操作。概述本文介绍了如何配置DDoS日志分析功能,结合实际场景详细介绍了如何使用日志对DDoS访问与攻击日志进行分析与图形…

【面试妥了】史上最全Spark面试题

戳蓝字“CSDN云计算”关注我们哦!作者 | 游骑小兵责编 | 阿秃Spark问题精华Q:什么是Spark?A:简单理解,Spark是在Hadoop基础上的改进,是UC Berkeley AMP lab所开源的类Hadoop MapReduce的通用的并行计算框架…

RabbitMQ的5种队列_订阅模式_入门试炼_第7篇

解读: 1、1个生产者,多个消费者 2、每一个消费者都有自己的一个队列 3、生产者没有将消息直接发送到队列,而是发送到了交换机 4、每个队列都要绑定到交换机 5、生产者发送的消息,经过交换机,到达队列,实现&…

python定期自动运行_干货分享 | 适合 Python 入门的 8 款强大工具,不会就你还不知道吧!...

点击上方“人工智能Corner”,“星标或置顶公众号”干货分享,第一时间送达Python是一种开源的编程语言,可用于Web编程、数据科学、人工智能以及许多科学应用。学习Python可以让程序员专注于解决问题,而不是语法。由于Python相对较小…

用计算机写文章 单元备课,信息技术第一单元单元备课精要.doc

第一2.了解计算机系统的组成,知道计算机的主要部件。3.了解计算机的工作过程。4.掌握鼠标的移动、单击、拖曳、双击四种操作方法,并能将这些操作灵活运用于计算机操作中。5、了解键盘的构造和布局。6、掌握使用键盘上一些常用键的功能和作用,…

python 两个数据框合并计算_一文掌握Excel、SQL、Python【数据合并】大法!

文章最后有录制的讲解视频,如果看文章不舒服的话,可以直接滑到文末看视频,希望你能喜欢~在工作中,会经常遇到将多张表合并为一张表的需求;在面试的时候,有时也会被面试官问到左连接、右连接、内连接的区别。…

图解 Python 算法

普通程序员,不学算法,也可以成为大神吗?对不起,这个,绝对不可以。可是算法好难啊~~看两页书就想睡觉……所以就不学了吗?就一直当普通程序员吗?如果有一本算法书,看着很轻松……又有…

阿里技术人的第一节课

摘要: 本期的分享我们邀请到了阿里巴巴研发效能事业部的董越老师,他是阿里巴巴内部培训百年技术课堂的著名讲师,他讲的《百技课程-代码服务》是每一位入职技术童鞋必修的一门课,我们也将这种阿里内训技术首次面向业界公开&#xf…

RabbitMQ的5种队列_路由模式_入门试炼_第8篇

生产者 5.8.3.费者1(前台系统) 消费2(搜索系统)

ios安装python的步骤_如何利用 Python 爬虫实现给微信群发新闻早报?(详细)

点击上方“AirPython”,选择“加为星标”第一时间关注 Python 技术干货!1. 场景经常有小伙伴在交流群问我,每天的早报新闻是怎么获取的?其实,早期使用的方案,是利用爬虫获取到一些新闻网站的标题&#xff0…

阿里云AI如何助攻世界杯?视频集锦背后的技术实践

摘要: 本届世界杯互联网直播的顺利进行,离不开各大云计算厂商的支持。在这其中,阿里云是当之无愧的“C位“,除了优酷外,阿里云还支撑了CNTV、CCTV5客户端,为全网70%的世界杯直播流量保驾护航。 对于世界杯这…

二本 计算机专业2017分数线,2017年二本心理学专业大学排名及分数线

【www.chinawenwang.com--阅读答案】大家知道心理学专业有哪些大学比较好吗?下面是小编搜集的2017年二本心理学专业大学排名及分数线,欢迎大家阅读参考,希望能帮助到大家。2017心理学专业大学排名录取分数线名次一级学科学科专业星级学科专业层次学校名…

h3c交换机划分vlan配置_华为、H3C、锐捷三家交换机配置命令详解

一、华为交换机基础配置命令1、创建vlan://用户视图,也就是在Quidway模式下运行命令。system-view //进入配置视图 [Quidway] vlan 10 //创建vlan 10,并进入vlan10配置视图,如果vlan10存在就直接进入vlan10配置视图 [Q…

程序员怎么悄无声息迈过36岁大槛?

戳蓝字“CSDN云计算”关注我们哦!作者 | 陈树义责编 | 阿秃我们很多时候经常会迷茫、焦虑,总是在想 35 岁的中年危机怎么办?很多时候与其焦虑,还不如想想看应该怎么办。很幸运的是,我在知道上遇到了一位年过中年还从事…

【开源】Tsar——灵活的系统和应用采集软件

摘要: 在开源人的盛会LinuxCon ContainerCon CloudOpen中国(简称LC3)大会上,阿里云CDN团队的空见(花名),为大家分享了开源的系统和应用采集软件Tsar的背景、设计思路和用法、模块开发以及未来…

pythondjango网页开发_Python-Web开发 Django 简介

Python 另一个 Web 开发框架 Django,它是一个基于 Python 定制的开源 Web 应用框架,最早源于一个在线新闻 Web 网站,后于2005年开源。Django 框架Django 采用了 MVC (即模型M,视图V和控制器C)构造的 Web 框架,但由于控…

看不见的战斗——阿里云护航世界杯直播容灾实践

摘要: 1978年,中国人开始在电视机上看到世界杯, 中央电视台对阿根廷队参加的半决赛以及阿根廷和荷兰的决赛进行了录播。1982年世界杯,宋世雄坐在一家香港宾馆的小电视前进行解说,然后央视再把香港这家电视台提供的画面…

树莓派安装python3.5_树莓派 | 04 安装基于python3.5的tensorflow,解决python版本不匹配问题...

创建日期:2019-03-03 系列文章 安装流程 在终端中依次执行 sudo apt install libatlas-base-dev pip3 install tensorflow(安装python3的CPU版本tensorflow,目前是不可能正常使用的,因为树莓派自带的Python3是3.5,而用…