Vue网页录音,js录音mp3

3 篇文章 0 订阅

在网上找到关于HTML5的录音教程,但是发现转成Vue的时候报错了。所以写一下解决方法。

HTML5录音链接(点击跳转)

本文是在此文的基础上进行修改的,使用了recorder.js和worker.js。同时因为Vue找不到worker.js文件,所以修改了部分源码,最终实现。其中坑多多,各位注意踩坑。

首先是Vue的文件。
进行说明:recordercopy为修改后的recorder.js,由于是父子组件关系,所以按钮是通过isStart的true和false来实现触发点击事件的。limit 是限制加载时候直接进入导致报错。同时,返回blobx文件到父组件。

<template>
    <div>
       
    </div>
</template>
<script>
import Recorder from '../../js/recordercopy'
export default {
    name: "audioState",
    props: {
        isStart: {
            type: Boolean,
            default: false,
        },
    },
    data() {
        return {
           recorder: {},
           limit: 0
        };
    },
    methods: {  
       github() {   
        if (this.recorder.start) {
            let blobx = {}
            if(this.isStart){
                this.recorder.start()
                this.limit = 1
            }else{
                if(this.limit == 0) return
                
                this.recorder.stop()
                
                new Promise((resolve, reject) => {
                    // 一段耗时的异步操作
                    this.recorder.getBlob(function (blob) {
                        blobx = blob
                        let download = document.createElement("a");
                        download.href = URL.createObjectURL(blob);
                        download.download = `视频对话录音.mp3`;
                        download.click();
                        console.log('打印结束:',blobx)
                            resolve(blobx) // 数据处理完成
                    });
                    // reject('失败') // 数据处理出错
                }
                ).then(
                (res) => {
                    this.$emit("wavHref", res);
                },  // 成功
                (err) => {console.log(err)} // 失败
                )
            }
          
        }else{
            this.github()
        }
       }
    },
    watch: {
        isStart(x) {
            this.github();
        },
    },
    mounted() {
        this.recorder = new Recorder({
            sampleRate: 44100, //采样频率,默认为44100Hz(标准MP3采样率)
            bitRate: 128, //比特率,默认为128kbps(标准MP3质量)
            success: function () { //成功回调函数
            },
            error: function (msg) { //失败回调函数
                alert(msg);
            },
            fix: function (msg) { //不支持H5录音回调函数
                alert(msg);
            }
        })
        this.github();
    },
};
</script>
<style scoped>
</style>

父组件调用:
在这里插入图片描述

根据这个修改了方法:
在这里插入图片描述

修改后的recorder.js文件。

    // var MyWorker = new Worker(require("./my.worker.js"));
    var blobx = new Blob([document.querySelector('#MyWorker').textContent]);
    var url = window.URL.createObjectURL(blobx);
    var MyWorker = new Worker(url);
    console.log(MyWorker)
    
    //公共方法
    var localMediaStream
    var Util = {
        //初始化
        init: function() {
            navigator.getUserMedia = navigator.getUserMedia ||
                navigator.webkitGetUserMedia ||
                navigator.mozGetUserMedia ||
                navigator.msGetUserMedia;

            window.AudioContext = window.AudioContext ||
                window.webkitAudioContext;
        },
        //日志
        log: function() {
            console.log.apply(console, arguments);
        }
    };
    //构造函数
    var Recorder = function(config) {
        var _this = this;
        config = config || {}; //初始化配置对象
        config.sampleRate = config.sampleRate || 44100; //采样频率,默认为44100Hz(标准MP3采样率)
        config.bitRate = config.bitRate || 128; //比特率,默认为128kbps(标准MP3质量)

        Util.init();

        if (navigator.getUserMedia) {
            navigator.getUserMedia({
                    audio: true //配置对象
                },
                function(stream) { //成功回调
                    localMediaStream = stream.getTracks()[0]
                    var context = new AudioContext(),
                        microphone = context.createMediaStreamSource(stream), //媒体流音频源
                        processor = context.createScriptProcessor(16384, 1, 1), //js音频处理器
                        successCallback, errorCallback;

                    config.sampleRate = context.sampleRate;

                    processor.onaudioprocess = function(event) {
                        //监听音频录制过程
                        var array = event.inputBuffer.getChannelData(0);
                        realTimeWorker.postMessage({ cmd: 'encode', buf: array });
                    };
                    
                    // var realTimeWorker = new Worker('./my.worker.js'); //开启后台线程
                    var realTimeWorker = MyWorker; //开启后台线程
                    realTimeWorker.onmessage = function(e) { //主线程监听后台线程,实时通信
                        console.log('进来这边')
                        console.log(e.data.cmd)
                        switch (e.data.cmd) {
                            case 'init':
                                Util.log('初始化成功');
                                if (config.success) {
                                    config.success();
                                }
                                break;
                            case 'end':
                                if (successCallback) {
                                    console.log('执行recorder')
                                    var blob = new Blob(e.data.buf, { type: 'audio/mp3' });
                                    successCallback(blob);
                                    Util.log('MP3大小:' + blob.size + '%cB', 'color:#0000EE');
                                }
                                break;
                            case 'error':
                                Util.log('错误信息:' + e.data.error);
                                if (errorCallback) {
                                    errorCallback(e.data.error);
                                }
                                break;
                            default:
                                Util.log('未知信息:' + e.data);
                        }
                    };
                    //接口列表
                    //开始录音
                    _this.start = function() {
                        if (processor && microphone) {
                            microphone.connect(processor);
                            processor.connect(context.destination);
                            Util.log('开始录音');
                        }
                    };
                    //结束录音
                    _this.stop = function() {
                        if (processor && microphone) {
                            microphone.disconnect();
                            processor.disconnect();
                            localMediaStream.stop()
                            Util.log('录音结束');
                        }
                    };
                    //获取blob格式录音文件
                    _this.getBlob = function(onSuccess, onError) {
                        successCallback = onSuccess;
                        errorCallback = onError;
                        console.log('这是blob')
                        realTimeWorker.postMessage({ cmd: 'finish' });
                    };

                    realTimeWorker.postMessage({
                        cmd: 'init',
                        config: {
                            sampleRate: config.sampleRate,
                            bitRate: config.bitRate
                        }
                    });
                },
                function(error) { //失败回调
                    var msg;
                    switch (error.code || error.name) {
                        case 'PermissionDeniedError':
                        case 'PERMISSION_DENIED':
                        case 'NotAllowedError':
                            msg = '用户拒绝访问麦克风';
                            break;
                        case 'NOT_SUPPORTED_ERROR':
                        case 'NotSupportedError':
                            msg = '浏览器不支持麦克风';
                            break;
                        case 'MANDATORY_UNSATISFIED_ERROR':
                        case 'MandatoryUnsatisfiedError':
                            msg = '找不到麦克风设备';
                            break;
                        default:
                            msg = '无法打开麦克风,异常信息:' + (error.code || error.name);
                            break;
                    }
                    Util.log(msg);
                    if (config.error) {
                        config.error(msg);
                    }
                });
        } else {
            Util.log('当前浏览器不支持录音功能');
            if (config.fix) {
                config.fix('当前浏览器不支持录音功能');
            }
        }

    };
    //模块接口
    export default Recorder;


// import a from './worker'

修改后的worker.js,采用放到了全局,作为一个属性方法,MyWorker。

<!-- 视频监控 - 录制声音 需要的方法,其他没办法录入耳机里的声音,只录入了麦克风的声音,采用这种方法进行 -->
    <!-- 这种方法的弊端是导致lamejs方法引入不了,导致只能直接放源码来引入lame,如果有更好的办法,请直接改进 -->
     <script id="MyWorker" type="app/worker">

        console.log('worker123')

        var mp3Encoder, maxSamples = 1152, samplesMono, lame, config, dataBuffer;
    
        var clearBuffer = function(){
            dataBuffer = [];
        };
    
        var appendToBuffer = function(mp3Buf){
            dataBuffer.push(new Int8Array(mp3Buf));
        };
    
        var init = function(prefConfig){
            console.log('初')
            config = prefConfig || {};
            console.log('lamejs:', lamejs)
            lame = new lamejs();
            mp3Encoder = new lame.Mp3Encoder(1, config.sampleRate || 44100, config.bitRate || 128);
            clearBuffer();
            self.postMessage({
                cmd: 'init'
            });
            console.log('消息')
        };
    
        var floatTo16BitPCM = function(input, output){
            for(var i = 0; i < input.length; i++){
                var s = Math.max(-1, Math.min(1, input[i]));
                output[i] = (s < 0 ? s * 0x8000 : s * 0x7FFF);
            }
        };
    
        var convertBuffer = function(arrayBuffer){
            var data = new Float32Array(arrayBuffer);
            var out = new Int16Array(arrayBuffer.length);
            floatTo16BitPCM(data, out);
            return out;
        };
    
        var encode = function(arrayBuffer){
            samplesMono = convertBuffer(arrayBuffer);
            var remaining = samplesMono.length;
            for(var i = 0; remaining >= 0; i += maxSamples){
                var left = samplesMono.subarray(i, i + maxSamples);
                var mp3buf = mp3Encoder.encodeBuffer(left);
                appendToBuffer(mp3buf);
                remaining -= maxSamples;
            }
        };
    
        var finish = function(){
            console.log('worker-end')
            appendToBuffer(mp3Encoder.flush());
            self.postMessage({
                cmd: 'end',
                buf: dataBuffer
            });
            clearBuffer();
        };
    
        self.onmessage = function(e){
            switch(e.data.cmd){
                case 'init':
                    init(e.data.config);
                    break;
                case 'encode':
                    encode(e.data.buf);
                    break;
                case 'finish':
                    finish();
                    break;
            }
        };

 function lamejs(){
 //这边放lamejs的源码
 }
      </script>

备注:要放入lamejs的文件

Html5网页纯JavaScript录制MP3音频 <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Html5网页JavaScript录制MP3音频</title> <meta charset="utf-8" /> </head> <body> Html5网页JavaScript录制MP3音频 录制 停止 上传 调试信息: [removed][removed] [removed] var recorder = new MP3Recorder({ debug:true, funOk: function () { btnStart.disabled = false; log('初始化成功'); }, funCancel: function (msg) { log(msg); recorder = null; } }); var mp3Blob; function funStart(button) { btnStart.disabled = true; btnStop.disabled = false; btnUpload.disabled = true; log('录音开始...'); recorder.start(); } function funStop(button) { recorder.stop(); btnStart.disabled = false; btnStop.disabled = true; btnUpload.disabled = false; log('录音结束,MP3导出中...'); recorder.getMp3Blob(function (blob) { log('MP3导出成功'); mp3Blob = blob; var url = URL.createObjectURL(mp3Blob); var div = document.createElement('div'); var au = document.createElement('audio'); var hf = document.createElement('a'); au.controls = true; au.src = url; hf.href = url; hf.download = new Date().toISOString() + '.mp3'; hf[removed] = hf.download; div.appendChild(au); div.appendChild(hf); recordingslist.appendChild(div); }); } function log(str) { recordingslist[removed] += str + ''; } function funUpload() { var fd = new FormData(); var mp3Name = encodeURIComponent('audio_recording_' + new Date().getTime() + '.mp3'); fd.append('mp3Name', mp3Name); fd.append('file', mp3Blob); var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { recordingslist[removed] += '上传成功:' + mp3Name + ''; } }; xhr.open('POST', 'upload.ashx'); xhr.send(fd); } [removed] </body> </html> [javascript] view plain copy 在CODE上查看代码片派生到我的代码片 (function (exports) { var MP3Recorder = function (config) { var recorder = this; config = config || {}; config.sampleRate = config.sampleRate || 44100; config.bitRate = config.bitRate || 128; navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia; if (navigator.getUserMedia) { navigator.getUserMedia({ audio: true }, function (stream) { var context = new AudioContext(), microphone = context.createMediaStreamSource(stream), processor = context.createScriptProcessor(16384, 1, 1),//bufferSize大小,输入channel数,输出channel数 mp3ReceiveSuccess, currentErrorCallback; config.sampleRate = context.sampleRate; processor.onaudioprocess = function (event) { //边录音边转换 var array = event.inputBuffer.getChannelData(0); realTimeWorker.postMessage({ cmd: 'encode', buf: array }); }; var realTimeWorker = new Worker('js/worker-realtime.js'); realTimeWorker.onmessage = function (e) { switch (e.data.cmd) { case 'init': log('初始化成功'); if (config.funOk) { config.funOk(); } break; case 'end': log('MP3大小:', e.data.buf.length); if (mp3ReceiveSuccess) { mp3ReceiveSuccess(new Blob(e.data.buf, { type: 'audio/mp3' })); } break; case 'error': log('错误信息:' + e.data.error); if (currentErrorCallback) { currentErrorCallback(e.data.error); } break; default: log('未知信息:', e.data); } }; recorder.getMp3Blob = function (onSuccess, onError) { currentErrorCallback = onError; mp3ReceiveSuccess = onSuccess; realTimeWorker.postMessage({ cmd: 'finish' }); }; recorder.start = function () { if (processor && microphone) { microphone.connect(processor); processor.connect(context.destination); log('开始录音'); } } recorder.stop = function () { if (processor && microphone) { microphone.disconnect(); processor.disconnect(); log('录音结束'); } } realTimeWorker.postMessage({ cmd: 'init', config: { sampleRate: config.sampleRate, bitRate: config.bitRate } }); }, function (error) { var msg; switch (error.code || error.name) { case 'PERMISSION_DENIED': case 'PermissionDeniedError': msg = '用户拒绝访问麦客风'; break; case 'NOT_SUPPORTED_ERROR': case 'NotSupportedError': msg = '浏览器不支持麦客风'; break; case 'MANDATORY_UNSATISFIED_ERROR': case 'MandatoryUnsatisfiedError': msg = '找不到麦客风设备'; break; default: msg = '无法打开麦克风,异常信息:' + (error.code || error.name); break; } if (config.funCancel) { config.funCancel(msg); } }); } else { if (config.funCancel) { config.funCancel('当前浏览器不支持录音功能'); } } function log(str) { if (config.debug) { console.log(str); } } } exports.MP3Recorder = MP3Recorder; })(window);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值