HTML5原生是提供了音頻錄音的支持的,用到的是這個API--getUserMedia,然而……感人的是,iOS Safari & Safari 直接不支持,面對着龐大的水果系用戶,這個方案顯然行不通。值得慶幸的是微信的JSSDK提供了音頻接口的支持,因此要在微信的H5頁面中實現錄音等功能,直接使用微信的API便可,兼容性也是妥妥的。下面說說在微信中使用錄音接口的具體實現和其中的一些坑。javascript
用過微信JSSDK的童鞋都應該知道,使用它須要先在公衆號上綁定安全域名、而且實現權限驗證邏輯,具體細節能夠參閱官方文檔。作好了上述準備工做,在咱們的頁面中引入SDK的js,而且部署到安全域名下,便可調用API。css
開始錄音接口html
wx.startRecord();
中止錄音接口java
wx.stopRecord({ success: function (res) { var localId = res.localId; } });
監聽錄音自動中止接口ajax
wx.onVoiceRecordEnd({ // 錄音時間超過一分鐘沒有中止的時候會執行 complete 回調 complete: function (res) { var localId = res.localId; } });
播放語音接口json
wx.playVoice({ localId: '' // 須要播放的音頻的本地ID,由stopRecord接口得到 });
暫停播放接口後端
wx.pauseVoice({ localId: '' // 須要暫停的音頻的本地ID,由stopRecord接口得到 });
中止播放接口api
wx.stopVoice({ localId: '' // 須要中止的音頻的本地ID,由stopRecord接口得到 });
監聽語音播放完畢接口安全
wx.onVoicePlayEnd({ success: function (res) { var localId = res.localId; // 返回音頻的本地ID } });
上傳語音接口服務器
wx.uploadVoice({ localId: '', // 須要上傳的音頻的本地ID,由stopRecord接口得到 isShowProgressTips: 1, // 默認爲1,顯示進度提示 success: function (res) { var serverId = res.serverId; // 返回音頻的服務器端ID } });
備註:上傳語音有效期3天,可用微信多媒體接口下載語音到本身的服務器,此處得到的 serverId 即 media_id,參考文檔 https://mp.weixin.qq.com/wiki... 目前多媒體文件下載接口的頻率限制爲10000次/天,如須要調高頻率,請郵件weixin-open@qq.com,郵件主題爲【申請多媒體接口調用量】,請對你的項目進行簡單描述,附上產品體驗連接,並對用戶量和使用量進行說明。
下載語音接口
wx.downloadVoice({ serverId: '', // 須要下載的音頻的服務器端ID,由uploadVoice接口得到 isShowProgressTips: 1, // 默認爲1,顯示進度提示 success: function (res) { var localId = res.localId; // 返回音頻的本地ID } });
長按錄音的關鍵代碼:
var btnRecord = $('#record'); btnRecord.on('touchstart', function(event) { event.preventDefault(); btnRecord.addClass('hold'); startTime = new Date().getTime(); // 延時後錄音,避免誤操做 recordTimer = setTimeout(function() { wx.startRecord({ success: function() { }, cancel: function() { alert('用戶拒絕受權錄音'); } }); }, 300); }).on('touchend', function(event) { event.preventDefault(); btnRecord.removeClass('hold'); // 間隔過短 if (new Date().getTime() - startTime < 300) { startTime = 0; // 不錄音 clearTimeout(recordTimer); } else { // 鬆手結束錄音 wx.stopRecord({ success: function(res) { localId = res.localId; // 上傳到服務器 uploadVoice(); }, fail: function(res) { alert(JSON.stringify(res)); } }); } });
上傳錄音的關鍵代碼:
//上傳錄音 function uploadVoice(){ //調用微信的上傳錄音接口把本地錄音先上傳到微信的服務器 //不過,微信只保留3天,而咱們須要長期保存,咱們須要把資源從微信服務器下載到本身的服務器 wx.uploadVoice({ localId: voice.localId, // 須要上傳的音頻的本地ID,由stopRecord接口得到 isShowProgressTips: 1, // 默認爲1,顯示進度提示 success: function (res) { //把錄音在微信服務器上的id(res.serverId)發送到本身的服務器供下載。 $.ajax({ url: '後端處理上傳錄音的接口', type: 'post', data: JSON.stringify(res), dataType: "json", success: function (data) { alert('文件已經保存到本身的服務器'); }, error: function (xhr, errorType, error) { console.log(error); } }); } }); }
微信的錄音只能經過localId上傳到微信服務器,而後經過localId從微信服務器上進行下載,文件只會在服務器上保存3天,格式是arm格式,因此通常還須要經過本身的服務器將文件下載下來保存轉碼,具體細節查閱文檔。
咱們在作例如錄音賀卡等H5頁面時,就須要在本身的服務器下載錄音轉碼成mp3,而後收到賀卡的用戶是經過在咱們的服務器中獲取mp3路徑來收聽錄音的。
阻止默認事件
按鈕的touch事件記得加 event.preventDefault();
防止長按文字被選中出現複製框
使用css設置按鈕 user-select:none;
避免受權彈窗致使touchend事件沒法觸發,一直不能結束錄音
用戶第一次觸發錄音時,會彈出受權窗口,這時會致使沒法觸發touchend事件,致使錄音一直沒法中斷。解決的辦法是,進入頁面時自動觸發一次錄音彈出受權,以後真正錄音時就不須要受權了。
// 用localStorage進行記錄,以前沒有受權的話,先觸發錄音受權,避免影響後 續交互 if (!localStorage.allowRecord || localStorage.allowRecord !== 'true') { wx.startRecord({ success: function() { localStorage.allowRecord = 'true'; // 僅僅爲了受權,因此馬上停掉 wx.stopRecord(); }, cancel: function() { alert('用戶拒絕受權錄音'); } }); }
是否能利用錄音接口實現相似「八分音符」這種麥克風遊戲呢?目前微信的錄音api更適合作錄音類,像「八分音符」這種須要實時獲取當前聲音數據的交互還實現不了,由於咱們僅僅能得到一個音頻的id,不像原生H5接口那樣能拿到音頻的數據信息。