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接口那样能拿到音频的数据信息。