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 相关文章推荐
JS限制Textarea文本域字符个数的具体实现
Aug 02 Javascript
angularJS提交表单(form)
Feb 09 Javascript
jQuery实现图片预加载效果
Nov 27 Javascript
js实现页面跳转的五种方法推荐
Mar 10 Javascript
图文详解Heap Sort堆排序算法及JavaScript的代码实现
May 04 Javascript
js实现无缝循环滚动
Jun 23 Javascript
使用PBFunc在Powerbuilder中支付宝当面付款功能
Oct 01 Javascript
javascript创建对象的3种方法
Nov 02 Javascript
vue2.0 与 bootstrap datetimepicker的结合使用实例
May 22 Javascript
jqueryUI tab标签页代码分享
Oct 09 jQuery
vue中多路由表头吸顶实现的几种布局方式
Apr 12 Javascript
vue学习笔记之过滤器的基本使用方法实例分析
Feb 01 Javascript
微信小程序开发摇一摇功能
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对mongodb的扩展(初出茅庐)
2012/11/11 PHP
php实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
php通过sort()函数给数组排序的方法
2015/03/18 PHP
Laravel Memcached缓存驱动的配置与应用方法分析
2016/10/08 PHP
浅谈php和js中json的编码和解码
2016/10/24 PHP
PHP实现正则匹配所有括号中的内容
2018/06/22 PHP
用javascript获取textarea中的光标位置
2008/05/06 Javascript
javascript 设为首页与加入收藏兼容多浏览器代码
2011/01/11 Javascript
js模拟点击事件实现代码
2012/11/06 Javascript
JS+CSS实现弹出全屏灰黑色透明遮罩效果的方法
2014/12/20 Javascript
jQuery超酷平面式时钟效果代码分享
2020/03/30 Javascript
基于dropdown.js实现的两款美观大气的二级导航菜单
2015/09/02 Javascript
jquery带有索引按钮且自动轮播切换特效代码分享
2015/09/15 Javascript
JavaScript中对DOM节点的访问、创建、修改、删除
2015/11/16 Javascript
JavaScript从0开始构思表情插件
2016/07/26 Javascript
BootStrap实现带有增删改查功能的表格(DEMO详解)
2016/10/26 Javascript
vuex实现简易计数器
2016/10/27 Javascript
JavaScript验证知识整理
2017/03/24 Javascript
实例分析JS与Node.js中的事件循环
2017/12/12 Javascript
详解关于微信setData回调函数中的坑
2019/02/18 Javascript
关于vue-cli 3配置打包优化要点(推荐)
2019/04/22 Javascript
vue.js中ref和$refs的使用及示例讲解
2019/08/14 Javascript
解决layui的radio属性或别的属性没显示出来的问题
2019/09/26 Javascript
Python合并多个装饰器小技巧
2015/04/28 Python
Python 模拟员工信息数据库操作的实例
2017/10/23 Python
Python管理Windows服务小脚本
2018/03/12 Python
Python 调用 zabbix api的方法示例
2019/01/06 Python
Python 在OpenCV里实现仿射变换—坐标变换效果
2019/08/30 Python
关于Python3 lambda函数的深入浅出
2019/11/27 Python
python 使用建议与技巧分享(四)
2020/08/18 Python
Python 里最强的地图绘制神器
2021/03/01 Python
h5封装下拉刷新
2020/08/25 HTML / CSS
台湾最大网路书店:博客来
2018/03/18 全球购物
沙特阿拉伯电子产品和家用电器购物网站:Black Box
2019/07/24 全球购物
2014年售后服务工作总结
2014/11/18 职场文书
党员证明信
2015/06/19 职场文书