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 相关文章推荐
克隆javascript对象的三个方法小结
Jan 12 Javascript
对javascript的一点点认识总结《javascript高级程序设计》读书笔记
Nov 30 Javascript
使用JavaScript获取电池状态的方法
May 03 Javascript
在JavaScript的AngularJS库中进行单元测试的方法
Jun 23 Javascript
BootstrapTable与KnockoutJS相结合实现增删改查功能【一】
May 10 Javascript
jQuery hover事件简单实现同时绑定2个方法
Jun 07 Javascript
微信公众平台开发教程(四) 实例入门:机器人回复(附源码)
Dec 02 Javascript
微信小程序 this和that详解及简单实例
Feb 13 Javascript
vue.js $refs和$emit 父子组件交互的方法
Dec 20 Javascript
使用apifm-wxapi模块中的问题及解决方法
Aug 05 Javascript
Vue父组件向子组件传值以及data和props的区别详解
Mar 02 Javascript
JS Html转义和反转义(html编码和解码)的实现与使用方法总结
Mar 10 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
关于查看MSSQL 数据库 用户每个表 占用的空间大小
2013/06/21 PHP
php mysql_real_escape_string函数用法与实例教程
2013/09/30 PHP
Android AsyncTack 异步任务实例详解
2016/11/02 PHP
PHP实现的简单对称加密与解密方法实例小结
2017/08/28 PHP
利用PHP判断是手机移动端还是PC端访问的函数示例
2017/12/14 PHP
php微信公众号开发之关键词回复
2018/10/20 PHP
利用javascript中的call实现继承
2007/01/22 Javascript
javascript之querySelector和querySelectorAll使用介绍
2011/12/20 Javascript
DOM和XMLHttpRequest对象的属性和方法整理
2012/01/04 Javascript
Javascript毫秒数用法实例
2015/02/05 Javascript
JavaScript简单判断复选框是否选中及取出值的方法
2015/08/13 Javascript
JSON简介以及用法汇总
2016/02/21 Javascript
AngularJS使用angular.bootstrap完成模块手动加载的方法分析
2017/01/19 Javascript
socket.io学习教程之基础介绍(一)
2017/04/29 Javascript
Vue组件的使用教程详解
2018/01/05 Javascript
vue2.0+vue-router构建一个简单的列表页的示例代码
2019/02/13 Javascript
javascript for循环性能测试示例
2019/08/07 Javascript
JavaScript中this函数使用实例解析
2020/02/21 Javascript
Vue移动端用淘宝弹性布局lib-flexible插件做适配的方法
2020/05/26 Javascript
微信h5静默和非静默授权获取用户openId的方法和步骤
2020/06/08 Javascript
利用Python的装饰器解决Bottle框架中用户验证问题
2015/04/24 Python
python基于pyDes库实现des加密的方法
2017/04/29 Python
Python简单计算文件MD5值的方法示例
2018/04/11 Python
Python文本统计功能之西游记用字统计操作示例
2018/05/07 Python
Flask-WTF表单的使用方法
2019/07/12 Python
django使用django-apscheduler 实现定时任务的例子
2019/07/20 Python
Python 离线工作环境搭建的方法步骤
2019/07/29 Python
python_mask_array的用法
2020/02/18 Python
Django跨域资源共享问题(推荐)
2020/03/09 Python
pandas实现导出数据的四种方式
2020/12/13 Python
CSS3中的transform属性进行2D和3D变换的基本用法
2016/05/12 HTML / CSS
泰国第一在线超市:Tops
2021/02/13 全球购物
大学毕业生管理学求职信
2014/09/01 职场文书
2015元旦家电促销活动策划方案
2014/12/09 职场文书
2015年前台接待工作总结
2015/05/04 职场文书
Spring Data JPA框架的核心概念和Repository接口
2022/04/28 Java/Android