前言
最近有几个朋友一直在问语音文件怎么转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的文件操作
本文详细代码请查看附件工程。