录音文件与Base64编码相互转换的方法

前言

最近有几个朋友一直在问语音文件怎么转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的文件操作

本文详细代码请查看附件工程。


阅读更多
换一批

没有更多推荐了,返回首页