91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

HTML5中實現錄音的示例分析

發布時間:2021-06-04 13:59:49 來源:億速云 閱讀:187 作者:小新 欄目:web開發

這篇文章將為大家詳細講解有關HTML5中實現錄音的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

說實話,一開始都沒接觸過 HTML5 的 Audio API,而且要基于在我們接手前的代碼中進行優化。當然其中也踩了不少坑,這次也會圍繞這幾個坑來說說感受(會省略一些基本對象的初始化和獲取,因為這些內容不是這次的重點,有興趣的同學可以自行查找 MDN 上的文檔):

  1. 調用 Audio API 的兼容性寫法

  2. 獲取錄音聲音的大小(應該是頻率)

  3. 暫停錄音的兼容性寫法

  4. 獲取當前錄音時間

錄音前的準備

開始錄音前,要先獲取當前設備是否支持 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;
};

其它

  1. HTTPS:在 chrome 下需要全站有 HTTPS 才允許使用

  2. 微信:在微信內置的瀏覽器需要調用 JSSDK 才能使用

  3. 音頻格式轉換:音頻格式的方式也有很多了,能查到的大部分資料,大家基本上是互相 copy,當然還有一個音頻質量的問題,這里就不贅述了。

關于“HTML5中實現錄音的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

上栗县| 来安县| 普安县| 班戈县| 廉江市| 界首市| 临邑县| 寿光市| 大田县| 汤阴县| 海安县| 洛川县| 江西省| 正安县| 北宁市| 从化市| 涿鹿县| 永丰县| 安西县| 大宁县| 庐江县| 社旗县| 广东省| 黄陵县| 剑川县| 乌什县| 特克斯县| 宜城市| 马山县| 贡嘎县| 阿拉善盟| 界首市| 武强县| 屏东市| 紫阳县| 策勒县| 洛扎县| 广饶县| 通州市| 灵川县| 资讯|