vue使用recorder.js实现录音功能


Posted in Javascript onNovember 22, 2019

关于vue使用recorder.js录音功能,供大家参考,具体内容如下

**

1, 引入外部js文件

import { HZRecorder} from ‘…/…/utils/HZRecorder.js';

js文件内容

export function HZRecorder(stream, config) {
  config = config || {};
  config.sampleBits = config.sampleBits || 16;   //采样数位 8, 16
  config.sampleRate = config.sampleRate || 16000;  //采样率16khz

  var context = new (window.webkitAudioContext || window.AudioContext)();
  var audioInput = context.createMediaStreamSource(stream);
  var createScript = context.createScriptProcessor || context.createJavaScriptNode;
  var recorder = createScript.apply(context, [4096, 1, 1]);

  var audioData = {
    size: 0     //录音文件长度
    , buffer: []   //录音缓存
    , inputSampleRate: context.sampleRate  //输入采样率
    , inputSampleBits: 16    //输入采样数位 8, 16
    , outputSampleRate: config.sampleRate  //输出采样率
    , oututSampleBits: config.sampleBits    //输出采样数位 8, 16
    , input: function (data) {
      this.buffer.push(new Float32Array(data));
      this.size += data.length;
    }
    , compress: function () { //合并压缩
      //合并
      var data = new Float32Array(this.size);
      var offset = 0;
      for (var i = 0; i < this.buffer.length; i++) {
        data.set(this.buffer[i], offset);
        offset += this.buffer[i].length;
      }
      //压缩
      var compression = parseInt(this.inputSampleRate / this.outputSampleRate);
      var length = data.length / compression;
      var result = new Float32Array(length);
      var index = 0, j = 0;
      while (index < length) {
        result[index] = data[j];
        j += compression;
        index++;
      }
      return result;
    }
    , encodeWAV: function () {
      var sampleRate = Math.min(this.inputSampleRate, this.outputSampleRate);
      var sampleBits = Math.min(this.inputSampleBits, this.oututSampleBits);
      var bytes = this.compress();
      var dataLength = bytes.length * (sampleBits / 8);
      var buffer = new ArrayBuffer(44 + dataLength);
      var data = new DataView(buffer);

      var channelCount = 1;//单声道
      var offset = 0;

      var writeString = function (str) {
        for (var i = 0; i < str.length; i++) {
          data.setUint8(offset + i, str.charCodeAt(i));
        }
      }

      // 资源交换文件标识符 
      writeString('RIFF'); offset += 4;
      // 下个地址开始到文件尾总字节数,即文件大小-8 
      data.setUint32(offset, 36 + dataLength, true); offset += 4;
      // WAV文件标志
      writeString('WAVE'); offset += 4;
      // 波形格式标志 
      writeString('fmt '); offset += 4;
      // 过滤字节,一般为 0x10 = 16 
      data.setUint32(offset, 16, true); offset += 4;
      // 格式类别 (PCM形式采样数据) 
      data.setUint16(offset, 1, true); offset += 2;
      // 通道数 
      data.setUint16(offset, channelCount, true); offset += 2;
      // 采样率,每秒样本数,表示每个通道的播放速度 
      data.setUint32(offset, sampleRate, true); offset += 4;
      // 波形数据传输率 (每秒平均字节数) 单声道×每秒数据位数×每样本数据位/8 
      data.setUint32(offset, channelCount * sampleRate * (sampleBits / 8), true); offset += 4;
      // 快数据调整数 采样一次占用字节数 单声道×每样本的数据位数/8 
      data.setUint16(offset, channelCount * (sampleBits / 8), true); offset += 2;
      // 每样本数据位数 
      data.setUint16(offset, sampleBits, true); offset += 2;
      // 数据标识符 
      writeString('data'); offset += 4;
      // 采样数据总数,即数据总大小-44 
      data.setUint32(offset, dataLength, true); offset += 4;
      // 写入采样数据 
      if (sampleBits === 8) {
        for (var i = 0; i < bytes.length; i++, offset++) {
          var s = Math.max(-1, Math.min(1, bytes[i]));
          var val = s < 0 ? s * 0x8000 : s * 0x7FFF;
          val = parseInt(255 / (65535 / (val + 32768)));
          data.setInt8(offset, val, true);
        }
      } else {
        for (var i = 0; i < bytes.length; i++, offset += 2) {
          var s = Math.max(-1, Math.min(1, bytes[i]));
          data.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
        }
      }

      return new Blob([data], { type: 'audio/wav' });
    }
  };
  //开始录音
  this.start = function () {
    audioInput.connect(recorder);
    recorder.connect(context.destination);
  }

  //停止
  this.stop = function () {
    recorder.disconnect();
  }

  //获取音频文件
  this.getBlob = function () {
    this.stop();
    return audioData.encodeWAV();
  }

  //回放
  this.play = function (audio) {
   var blob=this.getBlob();
   // saveAs(blob, "F:/3.wav");
   audio.src = window.URL.createObjectURL(this.getBlob());
  }

  //上传
  this.upload = function () {
   return this.getBlob()
  }

  //音频采集
  recorder.onaudioprocess = function (e) {
    audioData.input(e.inputBuffer.getChannelData(0));
    //record(e.inputBuffer.getChannelData(0));
  }

}

2、vue组件的mount中初始化调用麦克风工具

mounted() {
 this.$nextTick(() => {
 try {
 <!-- 检查是否能够调用麦克风 -->
 window.AudioContext = window.AudioContext || window.webkitAudioContext;
 navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia;
 window.URL = window.URL || window.webkitURL;
 
 audio_context = new AudioContext;
 console.log('navigator.getUserMedia ' + (navigator.getUserMedia ? 'available.' : 'not present!'));
 } catch (e) {
 alert('No web audio support in this browser!');
 }
 
 navigator.getUserMedia({audio: true}, function (stream) {
  recorder = new HZRecorder(stream)
  console.log('初始化完成');
  }, function(e) {
  console.log('No live audio input: ' + e);
 });
 })
},

3、methods 调用

readyOriginal () {
  if (!this.isVoice) {
  <!-- 开启录音 -->
  recorder && recorder.start();
  this.isVoice = true
  } else {
  this.isVoice = false
  <!-- 结束录音 -->
  recorder && recorder.stop();
  setTimeout(()=> {
   <!-- 录音上传 -->
   var mp3Blob = recorder.upload();
   var fd = new FormData();
   fd.append('audio', mp3Blob);
   this.$http({
   header: ({
    'Content-Type': 'application/x-www-form-urlencodeed'
   }),
   method: 'POST',
   url: 'url',
   data: fd,
   withCredentials: true,
   }).then((res) => { 
   // 这里做登录拦截
   if (res.data.isLogin === false) {
    router.replace('/login');
   } else {
    if (res.data.status === 200) {
    console.log('保存成功')
    } else {
    this.returnmsg = '上传失败'
    }
   }
   })
  },1000)
  }
 },

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Prototype Class对象学习
Jul 19 Javascript
使用apply方法处理数组的三个技巧[译]
Sep 20 Javascript
node.js中的fs.unlinkSync方法使用说明
Dec 15 Javascript
JS设置网页图片vspace和hspace属性的方法
Apr 01 Javascript
jQuery解析Json实例详解
Nov 24 Javascript
JS实现字符串转日期并比较大小实例分析
Dec 09 Javascript
js绘制购物车抛物线动画
Nov 18 Javascript
简单了解JavaScript异步
May 23 Javascript
微信小程序用户授权、位置授权及获取微信绑定手机号
Jul 18 Javascript
OpenLayers3实现地图显示功能
Sep 25 Javascript
JavaScript对象访问器Getter及Setter原理解析
Dec 08 Javascript
如何在Vue项目中添加接口监听遮罩
Jan 25 Vue.js
微信小程序开发摇一摇功能
Nov 22 #Javascript
js实现录音上传功能
Nov 22 #Javascript
解决vue自定义全局消息框组件问题
Nov 22 #Javascript
JavaScript实现省市联动效果
Nov 22 #Javascript
Vue混入mixins滚动触底的方法
Nov 22 #Javascript
超简单的微信小程序轮播图
Nov 22 #Javascript
微信小程序实现Swiper轮播图效果
Nov 22 #Javascript
You might like
PHP无限分类(树形类)的深入分析
2013/06/02 PHP
div li的多行多列 无刷新分页示例代码
2013/10/16 PHP
Array.prototype 的泛型应用分析
2010/04/30 Javascript
kmock javascript 单元测试代码
2011/02/06 Javascript
js 自动播放的实例代码
2013/11/19 Javascript
浅析jQuery1.8的几个小变化
2013/12/10 Javascript
ext中store.load跟store.reload的区别示例介绍
2014/06/17 Javascript
JavaScript中的ParseInt(&quot;08&quot;)和“09”返回0的原因分析及解决办法
2016/05/19 Javascript
html+js+highcharts绘制圆饼图表的简单实例
2016/08/04 Javascript
AngularJS入门教程之Cookies读写操作示例
2016/11/02 Javascript
jquery 实现复选框的全选操作实例代码
2017/01/24 Javascript
vue element项目引入icon图标的方法
2018/06/06 Javascript
vue构建动态表单的方法示例
2018/09/22 Javascript
一次微信小程序内地图的使用实战记录
2019/09/09 Javascript
Vue的属性、方法、生命周期实例代码详解
2019/09/17 Javascript
Vue退出登录时清空缓存的实现
2019/11/12 Javascript
JavaScript实现动态生成表格
2020/08/02 Javascript
[00:43]TI7不朽珍藏III——幽鬼不朽展示
2017/07/15 DOTA
Python实现批量修改文件名实例
2015/07/08 Python
Python列表切片用法示例
2017/04/19 Python
Python基于递归实现电话号码映射功能示例
2018/04/13 Python
Appium+python自动化之连接模拟器并启动淘宝APP(超详解)
2019/06/17 Python
python实现两个dict合并与计算操作示例
2019/07/01 Python
python os模块常用的29种方法使用详解
2020/06/02 Python
详解pandas apply 并行处理的几种方法
2021/02/24 Python
python抢购软件/插件/脚本附完整源码
2021/03/04 Python
Canvas 文本转粒子效果的实现代码
2019/02/14 HTML / CSS
HTML5中新标签和常用标签详解
2014/03/07 HTML / CSS
德国受欢迎的旅游和休闲网站:lastminute.de
2019/09/23 全球购物
《乌塔》教学反思
2014/02/17 职场文书
升学宴主持词
2014/04/02 职场文书
协议书与合同的区别
2014/04/18 职场文书
安康杯竞赛活动总结
2014/05/05 职场文书
《改造我们的学习》心得体会
2014/11/07 职场文书
继承权公证书范本
2015/01/23 职场文书
Vue实现导入Excel功能步骤详解
2021/07/03 Vue.js