摘要:音频的增量解码在浏览器中,提供了对音频处理的对象。文件为实现文件的分割与重组,先了解音频文件的组成文件说明。使用的即可进行对数据的绘制。
在绘制大音频波形的场景(目前只支持wav格式),急着用的同学点这里,如果有问题可以联系我,我会尽快修复。github: https://github.com/CofeeWithR...
效果图传统的音波图渲染流程是 ajax完整加载音频,使用audioContext解码完整的音频, 下载解码后的数据使用canvas绘制,这种方式当音频较小时是没有问题,但遇到超大音频(超过100M)时会出现从加载到渲染需要很长的时间(3~8)s。
我们是否能够从下载到绘制逐步地进行,从而做到既不会因占用大量的内存与集中的大量数据绘制造成卡顿,又有快速的响应(用户可以看到加载绘制的过程)。下面主要从下载、解码、绘制三个方面来研究其实现的可行性。
增量的数据下载XHR 与 fetch
XHR 有responseType属性, 支持 "" | "arraybuffer" | "blob" | "document" | "json" | "text" 6种值,参照MDN若是 "arraybuffer"|"blob",在onprogress回调中获取的response的值为nul, 这样就不能下下载过程中边下载,边绘制。
参照下面代码:
const xhr = new XMLHttpRequest(); xhr.responseType = "arraybuffer"; xhr.onprogress = data => { console.log( "data: ",data ); console.log("onprogress response: ", xhr.response && xhr.response.byteLength); } xhr.onloadend = data => { console.log("load end.."); } xhr.open("get","/source/test.wav" ); xhr.send();
以上是使用xhr获取音频文件,只有在最后一次的onprogress回调中,获取到完整的数据,不能增量的获取数据,达到我们增量的绘制目的。
fetch
fetch API支持对管道的管道操作与取消. 看下面的例子:
fetch("/source/test.wav").then( (val: Response) => { if(val.body){ // 从Response中获取可读流的reader,用于从管道中读取数据。 const reader: ReadableStreamReader = val.body.getReader(); readData(reader); } }) function readData(reader: ReadableStreamReader){ // 从管道中读取数据。 reader.read().then(data => { if(!data.done){ // data.value 为一个Uint8Array. console.log(data.value.byteLength); // 若还有数据,继续读取。 readData(reader); } }) };
fetch 返回的 Promise中返回的是一个Response对象,最终我们可以在Response的body.getReader() 获取到一个ReadableStreamReader ,通过该对象我们可以读取网络管道中的数据片段,以满足我们增量渲染数据的需求。ReadableStreamReader 的read对象可以获取一个返回值包含ArrayBuffer对象的Promise.
自此,就可以增量的从网络管道中获取数据。
在浏览器中,提供了对音频处理的audioContext对象。它提供了一个解码音频的Api decodeAudioData, 但不幸的是它只支持完整音频的解码。所以解码变成了完成增量渲染的核心部分。
为简单,目前只对wav音频做解码支持。由于WAV格式的特殊性,实现的总体思想也相当简单:
1、wav文件分为文件头部与数据部分,于是将wav文件的头部取出,将数据部分分割为多段。
2、当解码时,将文件头稍作修改与数据片段组合成完整音频,再使用decodeAudioData API进行解码。
wav文件为实现wav文件的分割与重组,先了解wav音频文件的组成 wav文件说明。
在文档中,给出了详细的定义与说明,其中关键的部分做下介绍:
摘自http://soundfile.sapp.org/doc...
由wav文件的结构可以看到,只需要对data块的size进行修改,就可以使用该头部与数据部分进行拼接,形成新的被切割后的文件。
绘制解码后会得到AudioBuffer对象,可获取的数据为 -1~1的浮点数。
使用canvas的Context.beginPath, 即可进行对数据的绘制。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/109393.html
摘要:开源库随着支持功能的增多,音频转码处理效率渐渐的跟不上需求了,近期抽时间对音频转码部分进行了升级优化,以支持更多实用的功能。基于以上两点问题,似乎只有多线程能够解决。 Recorder H5 GitHub开源库随着支持功能的增多,音频转码处理效率渐渐的跟不上需求了,近期抽时间对音频转码部分进行了升级优化,以支持更多实用的功能。另外IOS的Hybrid App也完成了移植,Android...
摘要:格式文件中不包含头部信息,播放器无法知道采样率,声道数,采样位数,音频数据大小等信息,导致无法播放。 本文记录一点工作经历,探讨音频文件的格式更多访问我的博客 前言 最近在整理音视频编程的知识,回忆起半年多,有一次需求是在后台播放某来源的 pcm 文件,当时处理方法用了点技巧,记录下来 背景:业务需求,在web后台里播放 pcm 文件,文件不大(约300KB,已知 pcm 的参数采样...
摘要:编码结束后,调用函数,来销毁和编码器。调用函数对参数中的格式音频数据帧进行解码,参数中存放解码后的音频数据帧。调用函数来销毁和解码器说重点当做即时通信产品,像微信这种的手机端,它们接受到很有可能就是协议压缩后的音频文件。 showImg(https://segmentfault.com/img/bVbtzkh?w=1024&h=682); 这么牛逼的轮子,肯定要美图镇楼 Speex是一...
阅读 3004·2021-10-12 10:12
阅读 3050·2021-09-22 16:04
阅读 3287·2019-08-30 15:54
阅读 2601·2019-08-29 16:59
阅读 2901·2019-08-29 16:08
阅读 865·2019-08-29 11:20
阅读 3491·2019-08-28 18:08
阅读 646·2019-08-26 13:43