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 相关文章推荐
基于jQuery架构javascript基础体系
Jan 01 Javascript
JS实现下拉框的动态添加(附效果)
Apr 03 Javascript
js实现无需数据库的县级以上联动行政区域下拉控件
Aug 14 Javascript
浅析JavaScript中的typeof运算符
Nov 30 Javascript
JavaScript 事件对内存和性能的影响
Jan 22 Javascript
Bootstrap table简单使用总结
Feb 15 Javascript
Node.js对MongoDB数据库实现模糊查询的方法
May 03 Javascript
微信小程序 刷新上拉下拉不会断详细介绍
May 11 Javascript
JS实现多级菜单中当前菜单不随页面跳转样式而发生变化
May 30 Javascript
jQuery+Ajax实现用户名重名实时检测
Jun 01 jQuery
JS实现的全选、全不选及反选功能【案例】
Feb 19 Javascript
解决layui表格内文本超出隐藏的问题
Sep 12 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 采集获取指定网址的内容
2010/01/05 PHP
php中数据库连接方式pdo和mysqli对比分析
2015/02/25 PHP
php微信浏览器分享设置以及回调详解
2016/08/01 PHP
JavaScript入门教程(7) History历史对象
2009/01/31 Javascript
详谈 Jquery Ajax异步处理Json数据.
2011/09/09 Javascript
javascript 另一种图片滚动切换效果思路
2012/04/20 Javascript
JS返回上一页实例代码通过图片和按钮分别实现
2013/08/16 Javascript
Js base64 加密解密介绍
2013/10/11 Javascript
javascript自定义startWith()和endWith()的两种方法
2013/11/11 Javascript
jquery基础教程之deferred对象使用方法
2014/01/22 Javascript
php析构函数的具体用法小结
2014/03/11 Javascript
JS实现文档加载完成后执行代码
2015/07/09 Javascript
详解JavaScript中数组的相关知识
2015/07/29 Javascript
整理AngularJS框架使用过程当中的一些性能优化要点
2016/03/05 Javascript
jQuery移动端图片上传组件
2016/06/12 Javascript
AngularJS 入门教程之事件处理器详解
2016/08/19 Javascript
jQuery使用siblings获取某元素所有同辈(兄弟姐妹)元素用法示例
2017/01/30 Javascript
BOM之navigator对象和用户代理检测
2017/02/10 Javascript
Angular2 自定义validators的实现方法
2017/07/05 Javascript
JS实现自定义状态栏动画文字效果示例
2017/10/12 Javascript
Node.js 使用request模块下载文件的实例
2018/09/05 Javascript
详解webpack 热更新优化
2018/09/13 Javascript
JS无限级导航菜单实现方法
2019/01/05 Javascript
使用localStorage替代cookie做本地存储
2019/09/25 Javascript
[06:43]DAC2018 4.5 SOLO赛 Maybe vs Paparazi
2018/04/06 DOTA
[00:23]魔方之谜解锁款式
2018/12/20 DOTA
Python中pygal绘制雷达图代码分享
2017/12/07 Python
TensorFlow实现RNN循环神经网络
2018/02/28 Python
python3模块smtplib实现发送邮件功能
2018/05/22 Python
python 实现得到当前时间偏移day天后的日期方法
2018/12/31 Python
在python image 中安装中文字体的实现方法
2019/08/22 Python
python爬虫添加请求头代码实例
2019/12/28 Python
Python实现EM算法实例代码
2020/10/04 Python
python安装mysql的依赖包mysql-python操作
2021/01/01 Python
就业意向书
2014/07/29 职场文书
javaScript Array api梳理
2021/03/31 Javascript