校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃

主頁 > 知識庫 > 詳解HTML5 錄音的踩坑之旅

詳解HTML5 錄音的踩坑之旅

熱門標簽:電銷機器人電話用什么卡 當涂高德地圖標注 南寧點撥外呼系統哪家公司做的好 云南大理400電話申請官方 四川點撥外呼系統 黃島區地圖標注 鎮江智能外呼系統有效果嗎 成都智能外呼系統平臺 江蘇智能電銷機器人哪家好

開篇閑扯

前一段時間的一個案子是開發一個有聲課件,大致就是通過導入文檔、圖片等資源后,頁面變為類似 PPT 的布局,然后選中一張圖片,可以插入音頻,有單頁編輯和全局編輯兩種模式。其中音頻的導入方式有兩種,一種是從資源庫中導入,還有一種就是要提到的錄音。

說實話,一開始都沒接觸過 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;
};

具體可以參考 https://developer.mozilla.org/zh-CN/docs/Web/API/AnalyserNode/frequencyBinCount

其它

  1. HTTPS:在 chrome 下需要全站有 HTTPS 才允許使用
  2. 微信:在微信內置的瀏覽器需要調用 JSSDK 才能使用
  3. 音頻格式轉換:音頻格式的方式也有很多了,能查到的大部分資料,大家基本上是互相 copy,當然還有一個音頻質量的問題,這里就不贅述了。

結語

這次遇到的大部分問題都是兼容性的問題,因此在上面踩了不少坑,尤其是移動端的問題,一開始還有出現因為獲取錄音時長寫法錯誤的問題,導致直接卡死的情況。這次的經歷也彌補了 HTML5 API 上的一些空白,當然最重要的還是要提醒一下大家,這種原生的 API 文檔還是直接查看 MDN 來的簡單粗暴!

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

標簽:十堰 咸寧 佳木斯 酒泉 南京 淮安 廣西 西寧

巨人網絡通訊聲明:本文標題《詳解HTML5 錄音的踩坑之旅》,本文關鍵詞  詳解,HTML5,錄音,的,踩坑,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《詳解HTML5 錄音的踩坑之旅》相關的同類信息!
  • 本頁收集關于詳解HTML5 錄音的踩坑之旅的相關信息資訊供網民參考!
  • 推薦文章
    校园春色亚洲色图_亚洲视频分类_中文字幕精品一区二区精品_麻豆一区区三区四区产品精品蜜桃
    欧美日韩免费观看一区三区| 国产在线精品视频| 欧美日韩在线综合| 视频在线在亚洲| 欧美tk—视频vk| 精品一区中文字幕| 欧美韩国日本不卡| 91免费版在线| 性做久久久久久免费观看欧美| 欧洲精品中文字幕| 五月天精品一区二区三区| 日韩亚洲欧美一区| 国产一区二区按摩在线观看| 国产免费观看久久| 色哟哟一区二区| 日韩精品成人一区二区在线| 久久精品日韩一区二区三区| 成人av免费在线| 亚洲亚洲精品在线观看| 日韩欧美中文字幕精品| 国产99久久久国产精品免费看 | 蜜桃av一区二区三区| 欧美精品一区二区三区四区 | 国产精品萝li| 欧美日韩亚洲综合在线 | 精品少妇一区二区三区日产乱码| 麻豆视频观看网址久久| 国产精品视频线看| 91在线播放网址| 午夜精彩视频在线观看不卡| 日韩欧美你懂的| 丁香激情综合五月| 亚洲精品一二三| 欧美高清视频一二三区| 久久国产日韩欧美精品| 国产色91在线| 欧美日韩精品一区二区三区四区| 日本大胆欧美人术艺术动态| 26uuu另类欧美亚洲曰本| 久久精品国产亚洲aⅴ| 日韩欧美另类在线| 色偷偷久久人人79超碰人人澡 | 欧美无乱码久久久免费午夜一区| 奇米四色…亚洲| 国产精品高清亚洲| 欧美精品国产精品| 成人午夜又粗又硬又大| 亚洲成人1区2区| 中文字幕第一区二区| 91视频一区二区| 男女男精品视频| 亚洲六月丁香色婷婷综合久久| 日韩欧美色综合| 一本到三区不卡视频| 精品一区二区三区在线视频| 久久亚洲一级片| 在线区一区二视频| 五月激情综合网| 中文字幕一区二区三区在线观看 | 制服丝袜在线91| 成a人片国产精品| 久久精品国产第一区二区三区| 亚洲色图视频网| 久久婷婷色综合| 欧美日韩一区二区不卡| 国产高清无密码一区二区三区| 天天影视涩香欲综合网| 国产精品理论在线观看| 欧美va亚洲va国产综合| 欧美视频一区在线观看| 国内久久婷婷综合| 国产精品成人免费精品自在线观看| 久久久精品综合| 欧美一二三四区在线| 欧美中文一区二区三区| 9色porny自拍视频一区二区| 蜜乳av一区二区| 亚洲国产精品一区二区尤物区| 国产精品国产三级国产aⅴ无密码 国产精品国产三级国产aⅴ原创 | 国产一区在线视频| 亚洲免费资源在线播放| 国产精品青草综合久久久久99| 91精品国产91久久综合桃花| 欧美日韩国产精品成人| 91久久精品一区二区| av亚洲产国偷v产偷v自拍| 国产精品88av| 国产一区在线不卡| 美女视频免费一区| 日韩高清在线不卡| 午夜精品福利视频网站| 亚洲va欧美va人人爽午夜| 亚洲激情男女视频| 亚洲男女毛片无遮挡| 亚洲视频中文字幕| 国产欧美中文在线| 久久精品亚洲精品国产欧美kt∨| 久久综合一区二区| 久久蜜桃一区二区| 国产无一区二区| 国产精品日日摸夜夜摸av| 中文字幕 久热精品 视频在线| 国产精品情趣视频| 国产亚洲精品资源在线26u| 亚洲国产成人在线| 亚洲视频1区2区| 一区二区三区免费| 亚洲国产欧美日韩另类综合| 午夜欧美电影在线观看| 日韩国产欧美三级| 久久国产精品无码网站| 国精产品一区一区三区mba桃花| 国产不卡一区视频| 色综合久久99| 欧美久久一二区| 欧美午夜精品一区| 欧美精品乱码久久久久久| 精品精品国产高清一毛片一天堂| 久久精品一级爱片| 亚洲精品第一国产综合野| 五月天亚洲婷婷| 美女高潮久久久| 国产成人激情av| 欧美性生活大片视频| 6080午夜不卡| 日韩欧美激情在线| 国产精品视频一二三区| 亚洲国产裸拍裸体视频在线观看乱了| 男女男精品网站| 99九九99九九九视频精品| 欧美三级日韩三级国产三级| 日韩美女视频在线| 中文字幕一区二区三区乱码在线| 午夜精品久久久久久久99水蜜桃| 激情小说欧美图片| 国产在线精品不卡| 欧美日韩精品欧美日韩精品| 国产午夜精品在线观看| 亚洲国产一区视频| 国产成人av一区二区| 欧美日韩亚州综合| 国产日韩欧美高清在线| 午夜电影一区二区| 不卡电影免费在线播放一区| 欧美伊人久久久久久久久影院| 精品福利一二区| 亚洲电影第三页| av爱爱亚洲一区| 日韩免费电影网站| 亚洲精品伦理在线| 国产成人亚洲精品青草天美| 欧美卡1卡2卡| 一区二区三区在线免费视频| 麻豆精品在线观看| 欧美情侣在线播放| 成人免费在线播放视频| 国产一区二区主播在线| 欧美精品少妇一区二区三区| 亚洲婷婷国产精品电影人久久| 国产乱码精品一区二区三区五月婷 | 欧美综合一区二区| 国产精品丝袜一区| 精品亚洲国产成人av制服丝袜| 欧美视频一区二区三区| 欧美第一区第二区| 久久99久久99精品免视看婷婷| 欧美日韩精品欧美日韩精品| 亚洲精品美腿丝袜| 成人免费不卡视频| 久久久久久久久蜜桃| 精油按摩中文字幕久久| 9191精品国产综合久久久久久| 一区二区三区四区亚洲| 成人av在线影院| 国产欧美日韩视频在线观看| 国内精品嫩模私拍在线| 日韩欧美中文字幕公布| 日本中文字幕一区| 欧美伦理电影网| 日本一道高清亚洲日美韩| 91黄色免费网站| 亚洲一区在线观看免费观看电影高清 | 一区二区三区波多野结衣在线观看| 国产一区二区免费看| 久久中文字幕电影| 国产乱码字幕精品高清av| 欧美精品一区二区蜜臀亚洲| 久久99热国产| 日韩视频在线永久播放| 国产一区欧美二区| 欧美国产精品专区| 国产成人在线免费| 国产精品五月天| 91年精品国产| 亚洲高清免费观看 | 亚洲柠檬福利资源导航| 国产精品99久| 亚洲特级片在线| 欧美性一级生活| 日韩成人av影视|