基于wavesurfer.js的超大音频的渐进式请求实现

 最近在对超大音频的渐进式请求实现上面消耗了不少时间,主要是因为一对音频的基本原理不太理解,二刚开始的时候太依赖插件,三网上这块的资料找不到只能靠自己摸索。由于交互复杂加上坑比较多,我怕描述不清,这里主要根据问题来做描述(前提你需要对wavesurfer.js有一定的了解)我的这篇博客有做说明:

未加载部分:

后端接口描述:

a、音频主要信息接口:获取总时长、字节数、总字节、音频格式等。

b、 分段请求接口:根据字节参数,传来对应段的音频。

1、如何设置容器的长度,及滚动条的设置?

html布局

<div class="wave-wrapper"  ref="waveWrapper" >       <div         class="wave-container"         :style="{width: waveContainerWidth=='100%'?'100%':waveContainerWidth+'px'}"         @click="containerClick($event)"       >         <div           id="waveform"           ref="waveform"           class="wave-form"           :style="{width: waveFormWidth=='100%'?'100%':waveFormWidth+'px',left: waveFormLeft+'px'}"           @click.stop         ></div>       </div>     </div>

waveform是wavesurfer渲染实际分段音频的容器,waveWrapper是音频的容器,这里追溯wavesurfer的源码,可以知道它对音频的解析是 **像素值=秒数*20**;因此从后端获取总时长后,设置waveContainerWidth即可。样式设置为overflow-y:auto

// 音频宽:防止音频过短,渲染不完 let dWidth = Math.round(that.duration * 20); that.waveContainerWidth = that.wrapperWidth > dWidth ? that.wrapperWidth : dWidth;               

2、音频分几段请求?

// 后台传入的音频信息存储 that.audioInfo = res;  // 音频时长  that.duration = parseInt(res.duration / 1000000);  // 如果音频的长度大于500s分段请求,每段100s // 1分钟的字节数[平均] = 比特率(bps) * 时长(s)  /  8 that.rangeBit =   that.duration > 500 ? (that.audioInfo.bitrate * that.rangeSecond) / 8 : that.audioInfo.size;   // 总段数 that.segNumbers = Math.ceil(that.audioInfo.size / that.rangeBit);

3、如何请求音频文件,如何实现预加载?

wavesurfer.js渲染音频的方式之一是根据WebAudio来渲染的。由于后端传给我的文件是arraybuffer的格式,那么这里就需要使用WebAudio读取和解析buffer文件的功能,这些wavesurfer.js内部已实现。只需要将文件传给它就可以了。这里我采用了预加载功能,即每加载一段音频就绘制当段的音频,但同时请求并缓存下一段音频。

    /**      * 获取音频片段      * @param segNumber 加载第几段      * @param justCache 仅仅缓存 true 仅缓存不加载      * @param initLoad 初始加载      */     getAudioSeg(segNumber, justCache, initLoad) {       let that = this;       let xhr = new XMLHttpRequest();       let reqUrl = location.origin;       xhr.open(         "GET",         `${reqUrl}/storage/api/audio/${this.audioInfo.code}`,         true       );       xhr.responseType = "arraybuffer";        let startBit = this.rangeBit * (segNumber - 1);       let endBit = this.rangeBit * segNumber;       xhr.setRequestHeader("Range", `bytes=${startBit}-${endBit}`);        xhr.onload = function() 

                    
                
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信