首頁 web前端 H5教程 詳解HTML5 錄音遇到的坑

詳解HTML5 錄音遇到的坑

May 17, 2018 pm 02:25 PM
h5 html5 遇到

本文恩主要介紹了詳解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 API 上的一些空白,當然最重要的還是要提醒一下大家,這種原生的 API 文件還是直接查看 MDN 來的簡單粗暴!

相關推薦:

關於錄音的10篇文章推薦

微信開發之錄音功能

詳解HTML5網頁錄音與壓縮的範例程式碼

#

以上是詳解HTML5 錄音遇到的坑的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

HTML 中的表格邊框 HTML 中的表格邊框 Sep 04, 2024 pm 04:49 PM

HTML 表格邊框指南。在這裡,我們以 HTML 中的表格邊框為例,討論定義表格邊框的多種方法。

HTML 中的巢狀表 HTML 中的巢狀表 Sep 04, 2024 pm 04:49 PM

這是 HTML 中巢狀表的指南。這裡我們討論如何在表中建立表格以及對應的範例。

HTML 左邊距 HTML 左邊距 Sep 04, 2024 pm 04:48 PM

HTML 左邊距指南。在這裡,我們討論 HTML margin-left 的簡要概述及其範例及其程式碼實作。

HTML 表格佈局 HTML 表格佈局 Sep 04, 2024 pm 04:54 PM

HTML 表格佈局指南。在這裡,我們詳細討論 HTML 表格佈局的值以及範例和輸出。

HTML 輸入佔位符 HTML 輸入佔位符 Sep 04, 2024 pm 04:54 PM

HTML 輸入佔位符指南。在這裡,我們討論 HTML 輸入佔位符的範例以及程式碼和輸出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在這裡我們也分別討論了 HTML 有序列表和類型的介紹以及它們的範例

HTML onclick 按鈕 HTML onclick 按鈕 Sep 04, 2024 pm 04:49 PM

HTML onclick 按鈕指南。這裡我們分別討論它們的介紹、工作原理、範例以及各個事件中的onclick事件。

在 HTML 中移動文字 在 HTML 中移動文字 Sep 04, 2024 pm 04:45 PM

HTML 中的文字移動指南。在這裡我們討論一下marquee標籤如何使用語法和實作範例。

See all articles