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 &amp; DHTML 实例编程(教程)(三)初级实例篇1—上传文件控件实例
Jun 02 Javascript
xml 封装与解析(javascript和C#中)
Jul 26 Javascript
HTML5使用DeviceOrientation实现摇一摇功能
Jun 05 Javascript
javascript插件开发的一些感想和心得
Feb 28 Javascript
解决vue-cli中stylus无法使用的问题方法
Jun 19 Javascript
Angular4表单验证代码详解
Sep 03 Javascript
vue和webpack安装命令详解
Jun 15 Javascript
详解create-react-app 2.0版本如何启用装饰器语法
Oct 23 Javascript
详解JavaScript栈内存与堆内存
Apr 04 Javascript
ElementUI中el-tree节点的操作的实现
Feb 27 Javascript
12 种使用Vue 的最佳做法
Mar 30 Javascript
解决VUE 在IE下出现ReferenceError: Promise未定义的问题
Nov 07 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
做了CDN获取用户真实IP的函数代码(PHP与Asp设置方式)
2013/04/13 PHP
Symfony2函数用法实例分析
2016/03/18 PHP
用js实现的一个Flash滚动轮换显示图片代码生成器
2007/03/14 Javascript
js 变量类型转换常用函数与代码[比较全]
2009/12/01 Javascript
js操作ajax返回的json的注意问题!
2010/02/23 Javascript
利用js实现选项卡的特别效果的实例
2013/03/03 Javascript
关于scrollLeft,scrollTop的浏览器兼容性测试
2013/03/19 Javascript
你必须知道的JavaScript 变量命名规则详解
2013/05/07 Javascript
js 中的switch表达式使用示例
2020/06/03 Javascript
在jquery中combobox多选的不兼容问题总结
2013/12/24 Javascript
js模拟C#中List的简单实例
2014/03/06 Javascript
javascript的创建多行字符串的7种方法
2014/04/29 Javascript
JavaScript小技巧整理篇(非常全)
2016/01/26 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
详解vue中localStorage的使用方法
2018/11/22 Javascript
vue使用localStorage保存登录信息 适用于移动端、PC端
2019/05/27 Javascript
微信小程序跨页面传递data数据方法解析
2019/12/13 Javascript
js实现登录时记住密码的方法分析
2020/04/05 Javascript
[47:46]完美世界DOTA2联赛 Magma vs GXR 第三场 11.07
2020/11/10 DOTA
详解Python多线程Selenium跨浏览器测试
2017/04/01 Python
Python闭包之返回函数的函数用法示例
2018/01/27 Python
Python 中的range(),以及列表切片方法
2018/07/02 Python
Python Threading 线程/互斥锁/死锁/GIL锁
2019/07/21 Python
python requests库爬取豆瓣电视剧数据并保存到本地详解
2019/08/10 Python
.dcm格式文件软件读取及python处理详解
2020/01/16 Python
matlab灰度图像调整及imadjust函数的用法详解
2020/02/27 Python
Eastbay官网:美国最大的运动鞋网络零售商
2016/07/27 全球购物
英国男士时尚网站:Dandy Fellow
2018/02/09 全球购物
FC-Moto西班牙:摩托车手最大的购物场所之一
2019/04/11 全球购物
澳大利亚领先的男装零售连锁店:Lowes
2020/08/07 全球购物
就业协议书怎么填
2014/04/11 职场文书
《鸟岛》教学反思
2014/04/26 职场文书
中学生旷课检讨书模板
2014/10/08 职场文书
大学生受助感言
2015/08/01 职场文书
使用Canvas绘制一个游戏人物属性图
2022/03/25 Javascript
MySQL 数据 data 基本操作
2022/05/04 MySQL