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 相关文章推荐
符合W3C网页标准的iframe标签的使用方法
Jul 19 Javascript
Extjs学习笔记之六 面版
Jan 08 Javascript
prettify 代码高亮着色器google出品
Dec 28 Javascript
js操作CheckBoxList实现全选/反选(在客服端完成)
Feb 02 Javascript
Javascript 构造函数详解
Oct 22 Javascript
jquery实现浮动在网页右下角的彩票开奖公告窗口代码
Sep 04 Javascript
JavaScript中的Number数字类型学习笔记
May 26 Javascript
浅谈javascript中new操作符的原理
Jun 07 Javascript
基于JavaScript实现淘宝商品广告效果
Aug 10 Javascript
JavaScript实现职责链模式概述
Jan 25 Javascript
深入理解Vue router的部分高级用法
Aug 15 Javascript
解决vant中 tab栏遇到的坑 van-tabs
Nov 04 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 得到根目录的 __FILE__ 常量
2008/07/23 PHP
PHP CURL模拟GET及POST函数代码
2010/04/25 PHP
php-cli简介(不会Shell语言一样用Shell)
2013/06/03 PHP
浅谈laravel 5.6 安装 windows上使用composer的安装过程
2019/10/18 PHP
简单的JS多重继承示例
2008/03/13 Javascript
超轻量级的基于jquery的三级展开列表
2011/04/26 Javascript
用js正确判断用户名cookie是否存在的方法
2014/01/28 Javascript
基于jquery和svg实现超炫酷的动画特效
2014/12/09 Javascript
javascript的日期对象、数组对象、二维数组使用说明
2014/12/22 Javascript
js格式化时间的简单实例
2016/11/27 Javascript
nodejs redis 发布订阅机制封装实现方法及实例代码
2016/12/15 NodeJs
JavaScript函数表达式详解及实例
2017/05/05 Javascript
JavaScript中Hoisting详解 (变量提升与函数声明提升)
2017/08/18 Javascript
VueJs 搭建Axios接口请求工具
2017/11/20 Javascript
JS 使用 window对象的print方法实现分页打印功能
2018/05/16 Javascript
layer关闭当前窗口页面以及确认取消按钮的方法
2019/09/09 Javascript
微信小程序自定义底部弹出框功能
2020/11/18 Javascript
Python Trie树实现字典排序
2014/03/28 Python
Win7下搭建python开发环境图文教程(安装Python、pip、解释器)
2016/05/17 Python
Python中read()、readline()和readlines()三者间的区别和用法
2017/07/30 Python
Python基于机器学习方法实现的电影推荐系统实例详解
2019/06/25 Python
python GUI库图形界面开发之PyQt5信号与槽机制、自定义信号基础介绍
2020/02/25 Python
东南亚冒险旅行与活动:Adventoro
2019/10/16 全球购物
护理专业个人求职简历的自我评价
2013/10/13 职场文书
手工社团活动方案
2014/02/17 职场文书
交通事故赔偿协议书范本
2014/04/15 职场文书
网吧消防安全责任书
2014/07/29 职场文书
八荣八耻的活动方案
2014/08/16 职场文书
超市周年庆活动方案
2014/08/16 职场文书
个人批评与自我批评发言稿
2014/09/28 职场文书
青岛导游词
2015/02/12 职场文书
毕业生个人总结
2015/02/28 职场文书
运动员入场前导词
2015/07/20 职场文书
2016年秋季运动会广播稿
2015/12/21 职场文书
班级班风口号大全
2015/12/25 职场文书
python图像处理 PIL Image操作实例
2022/04/09 Python