摘要:音頻的增量解碼在瀏覽器中,提供了對音頻處理的對象。文件為實(shí)現(xiàn)文件的分割與重組,先了解音頻文件的組成文件說明。使用的即可進(jìn)行對數(shù)據(jù)的繪制。
在繪制大音頻波形的場景(目前只支持wav格式),急著用的同學(xué)點(diǎn)這里,如果有問題可以聯(lián)系我,我會(huì)盡快修復(fù)。github: https://github.com/CofeeWithR...
效果圖傳統(tǒng)的音波圖渲染流程是 ajax完整加載音頻,使用audioContext解碼完整的音頻, 下載解碼后的數(shù)據(jù)使用canvas繪制,這種方式當(dāng)音頻較小時(shí)是沒有問題,但遇到超大音頻(超過100M)時(shí)會(huì)出現(xiàn)從加載到渲染需要很長的時(shí)間(3~8)s。
我們是否能夠從下載到繪制逐步地進(jìn)行,從而做到既不會(huì)因占用大量的內(nèi)存與集中的大量數(shù)據(jù)繪制造成卡頓,又有快速的響應(yīng)(用戶可以看到加載繪制的過程)。下面主要從下載、解碼、繪制三個(gè)方面來研究其實(shí)現(xiàn)的可行性。
增量的數(shù)據(jù)下載XHR 與 fetch
XHR 有responseType屬性, 支持 "" | "arraybuffer" | "blob" | "document" | "json" | "text" 6種值,參照MDN若是 "arraybuffer"|"blob",在onprogress回調(diào)中獲取的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回調(diào)中,獲取到完整的數(shù)據(jù),不能增量的獲取數(shù)據(jù),達(dá)到我們增量的繪制目的。
fetch
fetch API支持對管道的管道操作與取消. 看下面的例子:
fetch("/source/test.wav").then( (val: Response) => { if(val.body){ // 從Response中獲取可讀流的reader,用于從管道中讀取數(shù)據(jù)。 const reader: ReadableStreamReader = val.body.getReader(); readData(reader); } }) function readData(reader: ReadableStreamReader){ // 從管道中讀取數(shù)據(jù)。 reader.read().then(data => { if(!data.done){ // data.value 為一個(gè)Uint8Array. console.log(data.value.byteLength); // 若還有數(shù)據(jù),繼續(xù)讀取。 readData(reader); } }) };
fetch 返回的 Promise中返回的是一個(gè)Response對象,最終我們可以在Response的body.getReader() 獲取到一個(gè)ReadableStreamReader ,通過該對象我們可以讀取網(wǎng)絡(luò)管道中的數(shù)據(jù)片段,以滿足我們增量渲染數(shù)據(jù)的需求。ReadableStreamReader 的read對象可以獲取一個(gè)返回值包含ArrayBuffer對象的Promise.
自此,就可以增量的從網(wǎng)絡(luò)管道中獲取數(shù)據(jù)。
在瀏覽器中,提供了對音頻處理的audioContext對象。它提供了一個(gè)解碼音頻的Api decodeAudioData, 但不幸的是它只支持完整音頻的解碼。所以解碼變成了完成增量渲染的核心部分。
為簡單,目前只對wav音頻做解碼支持。由于WAV格式的特殊性,實(shí)現(xiàn)的總體思想也相當(dāng)簡單:
1、wav文件分為文件頭部與數(shù)據(jù)部分,于是將wav文件的頭部取出,將數(shù)據(jù)部分分割為多段。
2、當(dāng)解碼時(shí),將文件頭稍作修改與數(shù)據(jù)片段組合成完整音頻,再使用decodeAudioData API進(jìn)行解碼。
wav文件為實(shí)現(xiàn)wav文件的分割與重組,先了解wav音頻文件的組成 wav文件說明。
在文檔中,給出了詳細(xì)的定義與說明,其中關(guān)鍵的部分做下介紹:
摘自http://soundfile.sapp.org/doc...
由wav文件的結(jié)構(gòu)可以看到,只需要對data塊的size進(jìn)行修改,就可以使用該頭部與數(shù)據(jù)部分進(jìn)行拼接,形成新的被切割后的文件。
繪制解碼后會(huì)得到AudioBuffer對象,可獲取的數(shù)據(jù)為 -1~1的浮點(diǎn)數(shù)。
使用canvas的Context.beginPath, 即可進(jìn)行對數(shù)據(jù)的繪制。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/109393.html
摘要:開源庫隨著支持功能的增多,音頻轉(zhuǎn)碼處理效率漸漸的跟不上需求了,近期抽時(shí)間對音頻轉(zhuǎn)碼部分進(jìn)行了升級優(yōu)化,以支持更多實(shí)用的功能?;谝陨蟽牲c(diǎn)問題,似乎只有多線程能夠解決。 Recorder H5 GitHub開源庫隨著支持功能的增多,音頻轉(zhuǎn)碼處理效率漸漸的跟不上需求了,近期抽時(shí)間對音頻轉(zhuǎn)碼部分進(jìn)行了升級優(yōu)化,以支持更多實(shí)用的功能。另外IOS的Hybrid App也完成了移植,Android...
摘要:格式文件中不包含頭部信息,播放器無法知道采樣率,聲道數(shù),采樣位數(shù),音頻數(shù)據(jù)大小等信息,導(dǎo)致無法播放。 本文記錄一點(diǎn)工作經(jīng)歷,探討音頻文件的格式更多訪問我的博客 前言 最近在整理音視頻編程的知識(shí),回憶起半年多,有一次需求是在后臺(tái)播放某來源的 pcm 文件,當(dāng)時(shí)處理方法用了點(diǎn)技巧,記錄下來 背景:業(yè)務(wù)需求,在web后臺(tái)里播放 pcm 文件,文件不大(約300KB,已知 pcm 的參數(shù)采樣...
摘要:編碼結(jié)束后,調(diào)用函數(shù),來銷毀和編碼器。調(diào)用函數(shù)對參數(shù)中的格式音頻數(shù)據(jù)幀進(jìn)行解碼,參數(shù)中存放解碼后的音頻數(shù)據(jù)幀。調(diào)用函數(shù)來銷毀和解碼器說重點(diǎn)當(dāng)做即時(shí)通信產(chǎn)品,像微信這種的手機(jī)端,它們接受到很有可能就是協(xié)議壓縮后的音頻文件。 showImg(https://segmentfault.com/img/bVbtzkh?w=1024&h=682); 這么牛逼的輪子,肯定要美圖鎮(zhèn)樓 Speex是一...
閱讀 3004·2021-10-12 10:12
閱讀 3051·2021-09-22 16:04
閱讀 3287·2019-08-30 15:54
閱讀 2601·2019-08-29 16:59
閱讀 2901·2019-08-29 16:08
閱讀 867·2019-08-29 11:20
閱讀 3491·2019-08-28 18:08
閱讀 647·2019-08-26 13:43