http://ask.dcloud.net.cn/article/841?item_id=10780
前言
最近有几个朋友一直在问语音文件怎么转base64字符串进行发送上传,base64字符串又如何转成文件,论坛中已经有多篇问题的帖子有介绍,这里只是稍微整理,方便大家可以更加方便的使用,首先看效果:
录音文件转成base64字符串
hello mui 演示app中im-chat.html有演示案例,通过hold和release控制录音的长度,即长按按钮开始录音,释放就停止录音,上拉取消发送录音。
html部分:
<button id="recorder" type="button" class="mui-btn mui-btn-blue mui-btn-block">录制语音文件转base64字符串</button>
js部分:
mui.init中首先需要配置手势事件:
mui.init({ gestureConfig: { tap: true, //默认为true doubletap: true, //默认为false longtap: true, //默认为false swipe: true, //默认为true drag: true, //默认为true hold: true, //默认为false,不监听 release: true //默认为false,不监听 }});
录音逻辑控制,按住按钮弹出录音提示框,并且对录音时长进行控制,录音时间太短取消操作,手指上划,取消发送。
var MIN_SOUND_TIME = 800;var recorder = null;var startTimestamp = null;var stopTimestamp = null;var stopTimer = null;var recordCancel = false;var soundAlert = document.getElementById("sound-alert");var audioTips = document.getElementById("audio-tips");// 控制录音弹出框是否播放var setSoundAlertVisable=function(show){ if(show){ soundAlert.style.display = 'block'; soundAlert.style.opacity = 1; }else{ soundAlert.style.opacity = 0; // 完成再真正隐藏 setTimeout(function(){ soundAlert.style.display = 'none'; },200); }};mui.plusReady(function () { /** * 录制语音文件转base64字符串 */ // 按住录音(长按开始录音) document.querySelector('#recorder').addEventListener('hold',function () { recordCancel = false; if(stopTimer)clearTimeout(stopTimer); audioTips.innerHTML = "手指上划,取消发送"; soundAlert.classList.remove('rprogress-sigh'); setSoundAlertVisable(true); // 获取当前设备的录音对象 recorder = plus.audio.getRecorder(); startTimestamp = (new Date()).getTime(); recorder.record({ filename:"_doc/audio/", format:"amr" //iOS平台支持"wav"、"aac"、"amr"格式,默认为"wav" }, function (path) { if (recordCancel) return; console.log("path:"+path); Audio2dataURL(path); }, function ( e ) { mui.toast("录音出现异常: " + e.message ); }); }) // 释放保存(松手保存) document.querySelector('#recorder').addEventListener('release',function () { if (audioTips.classList.contains("cancel")) { audioTips.classList.remove("cancel"); audioTips.innerHTML = "手指上划,取消发送"; } // 判断录音时间 stopTimestamp = (new Date()).getTime(); if (stopTimestamp - startTimestamp < 800) { audioTips.innerHTML = "录音时间太短"; soundAlert.classList.add('rprogress-sigh'); recordCancel = true; stopTimer=setTimeout(function(){ setSoundAlertVisable(false); },800); }else{ setSoundAlertVisable(false); } recorder.stop(); }) // 拖动屏幕(手指上划,取消发送) document.body.addEventListener('drag', function(event) { if (Math.abs(event.detail.deltaY) > 50) { if (!recordCancel) { recordCancel = true; if (!audioTips.classList.contains("cancel")) { audioTips.classList.add("cancel"); } audioTips.innerHTML = "松开手指,取消发送"; } } else { if (recordCancel) { recordCancel = false; if (audioTips.classList.contains("cancel")) { audioTips.classList.remove("cancel"); } audioTips.innerHTML = "手指上划,取消发送"; } } }, false);})
当录音成功后,我们可以将录音文件转成base64字符串,用于网络传输。
/** * 录音语音文件转base64字符串 * @param {Object} path */function Audio2dataURL (path) { plus.io.resolveLocalFileSystemURL(path, function(entry){ entry.file(function(file){ var reader = new plus.io.FileReader(); reader.onloadend = function (e) { console.log(e.target.result); }; reader.readAsDataURL(file); },function(e){ mui.toast("读写出现异常: " + e.message ); }) })}
至此我们完成了录音语音文件转base64字符串,反过来我们需要将base64字符串转成语音文件。
base64字符串转成语音文件
我们可以封装如下方法:
/** * base64字符串转成语音文件(参考http://ask.dcloud.net.cn/question/16935) * @param {Object} base64Str * @param {Object} callback */function dataURL2Audio (base64Str, callback) { var base64Str = base64Str.replace('data:audio/amr;base64,',''); var audioName = (new Date()).valueOf() + '.amr'; plus.io.requestFileSystem(plus.io.PRIVATE_DOC,function(fs){ fs.root.getFile(audioName,{create:true},function(entry){ // 获得平台绝对路径 var fullPath = entry.fullPath; if(mui.os.android){ // 读取音频 var Base64 = plus.android.importClass("android.util.Base64"); var FileOutputStream = plus.android.importClass("java.io.FileOutputStream"); try{ var out = new FileOutputStream(fullPath); var bytes = Base64.decode(base64Str, Base64.DEFAULT); out.write(bytes); out.close(); // 回调 callback && callback(entry); }catch(e){ console.log(e.message); } }else if(mui.os.ios){ var NSData = plus.ios.importClass('NSData'); var nsData = new NSData(); nsData = nsData.initWithBase64EncodedStringoptions(base64Str,0); if (nsData) { nsData.plusCallMethod({writeToFile: fullPath,atomically:true}); plus.ios.deleteObject(nsData); } // 回调 callback && callback(entry); } }) })}
调用方法如下:
html部分:
<button id="player" type="button" class="mui-btn mui-btn-blue mui-btn-block">base64字符串转成语音文件播放</button>
js部分:
/** * base64字符串转成语音文件播放 */document.querySelector('#player').addEventListener('tap',function () { // 语音文件Base64编码(由于编码过长影响阅读体验,请查看工程验证) var base64Str = ' ' // 转成.amr文件播放 dataURL2Audio(base64Str, function(entry){ var toURL = entry.toURL(); // 播放音频 playAudio(toURL); })})/** * 播放音频 * @param {Object} path */function playAudio (path) { var player = plus.audio.createPlayer(path); player.play(function(){ mui.toast("播放成功"); }, function(e) { mui.toast("播放失败"); }); }
写在后面
本文以语音文件为例说明5+中语音文件与Base64编码的相互转换,对于图片与Base64编码的转换方法请参考nativeObj Bitmap: 原生图片对象,可以通过loadBase64Data方法加载Base64编码格式图片到Bitmap对象,通过toBase64Data方法获取图片的Base64编码数据。对于一般性文件,建议使用h5 File API,详细可以参考我这篇文章:
JavaScript进阶学习(三)—— 基于html5 File API的文件操作
本文详细代码请查看附件工程。