录音很简单,没有用apicloud自带的录音,它只能录制amr格式,所以用了一个叫“recMp3”的模块,它可以录mp3格式,代码如下:
//录音 var recMp3 = api.require('recMp3'); recMp3.start(function(ret, err) { if (ret) { if(ret.db!=undefined){ } } else { func.msg(err.message); } }); //停止录音 var that = this; var recMp3 = api.require('recMp3'); recMp3.stop(function(ret,err) { if(ret){ var duration = ret.duration; //得到fs://格式的录音地址 var path = ret.path; } });将mp3格式音乐转成base64也简单:
let fileReader = new FileReader(); fileReader.readAsDataURL(mp3文件) fileReader.onload = function (e){ //得到mp3文件的base64 var base64Data = e.target.result; };最关键的来了,这个mp3文件如何得到,recMp3录音成功后,只返回了一个fs://格式的地址,而fileReader.readAsDataURL传地址是不行的。
首先就想到了<input type="file" />的方法获取,但是这种方法不行,因为它必须要用户点击,然后弹窗,然后选择文件才可以。而浏览器也出于安全,是不会让开发者在避开用户的情况下,轻易得到本地文件。那只能另辟蹊径。于是想到了ajax,ajax可以用来下载文件,并且返回此文件的blob格式,只要在responseType设置为blob就行了,于是,我爱模板网写了下面的代码:
//通过原生ajax获取网络音乐,并转为base64 var xhr = new XMLHttpRequest(); xhr.open('GET', 'http://www.5imoban.net/view/demomusic/niliuchenghe.mp3'); xhr.responseType = 'blob'; xhr.send(); xhr.onload = function() { let fileReader = new FileReader(); fileReader.readAsDataURL(xhr.response) fileReader.onload = function (e){ //下面的代码成功得到了mp3格式文件的base64格式 console.log(e.target.result); }; };上面代码成功了!因为是apicloud项目,不用考虑跨域问题。现在的问题就变成了,请求fs或者widget格式的路径行不行。结果打脸了,这个ajax是js原生的,肯定不识别fs或者widget,因为那是app的路径。而apicloud提供的ajax又不支持返回blob。于是又换成相对路径试下,因为js原生应该是别相对路径,发现成功了:
//通过相对地址获取本地文件,并转为base64 var xhr = new XMLHttpRequest(); xhr.open('GET', '../../js/api.js'); xhr.responseType = 'blob'; xhr.send(); xhr.onload = function() { let fileReader = new FileReader(); fileReader.readAsDataURL(xhr.response) fileReader.onload = function (e){ //下面的代码成功得到了api.js的base64格式 console.log(e.target.result); }; };现在的问题就是如何将录音的fs协议的地址转换成相对地址了,可以先将fs地址的文件用fs模块,剪切到项目根目录,然后就可以用相对路径了,代码如下:
var pathArr = path.split("/"); //这里的path是录音得到的fs协议的路径 var mp3Name = pathArr[pathArr.length-1]; var fs = api.require('fs'); fs.moveTo({ oldPath : path, //这里的path是录音得到的fs协议的路径 newPath : 'widget://mp3/' }, function(ret, err) { that.mp3Src = '../../mp3/'+mp3Name; //将mp3移动到widget以便于得到相对路径 });通过上面的方法得到的mp3Src就是这个录音文件相对于当前文件的相对地址了(当前文件在widget://html/street,而移动后的mp3录音文件在widget://mp3/目录),再此使用上面的方法,就成功得到了!!耗费了一个多小时的时间终于解决了!下面是包含录音、转换base64等的完整代码:
//开始录音 startRecord(){ var recMp3 = api.require('recMp3'); recMp3.start(function(ret, err) { if (ret) { console.log('录音开始'); } else { func.msg(err.message); } }); }, //结束录音 stopRecord(){ var that = this; var recMp3 = api.require('recMp3'); recMp3.stop(function(ret,err) { if(ret){ var duration = ret.duration; var path = ret.path; //得到mp3的名字 var pathArr = path.split("/"); var mp3Name = pathArr[pathArr.length-1]; if(duration>1){ var fs = api.require('fs'); //将mp3移动到widget以便于得到相对路径,只有相对路径才能进行本地ajax请求 fs.moveTo({ oldPath : path, newPath : 'widget://mp3/' }, function(ret, err) { that.mp32Base64('../../mp3/'+mp3Name); }); }else{ func.msg('录音时间太短,请重新录制!'); } clearInterval(that.timer); that.howLong = 0; that.recordState = 3; } }); }, //mp3转base64 mp32Base64:function(path){ var that = this; var xhr = new XMLHttpRequest(); xhr.open('GET', path); xhr.responseType = 'blob'; xhr.send(); xhr.onload = function() { let fileReader = new FileReader(); fileReader.readAsDataURL(xhr.response) fileReader.onload = function (e){ console.log(e.target.result); //最终得到mp3的base64 that.mp3Base64 = e.target.result; }; }; },至此完成了!此方法不仅仅适用于apicloud,web端也可以。另外,如果不是因为外网被禁,我肯定直接传给后台转base64了,转完了,再发回来。
此外,其实虽然使用ajax成功读取了本地文件,但是仅限于当前项目,如果想用ajax读取项目之外的文件,还是不好弄!