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操作Select 简单方便 一个js插件搞定
Nov 12 Javascript
table行随鼠标移动变色示例
May 07 Javascript
JavaScript实现的in_array函数
Aug 27 Javascript
2014 年最热门的21款JavaScript框架推荐
Dec 25 Javascript
JavaScript 学习笔记之语句
Jan 14 Javascript
JQuery插件jcarousellite的参数中文说明
May 11 Javascript
jquery预加载图片的方法
May 27 Javascript
jQuery实现仿百度帖吧头部固定导航效果
Aug 07 Javascript
jQuery解析与处理服务器端返回xml格式数据的方法详解
Jul 04 Javascript
JS获取url参数、主域名的方法实例分析
Aug 03 Javascript
vue通过v-html指令渲染的富文本无法修改样式的解决方案
May 20 Javascript
小程序实现列表展开收起效果
Jul 29 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语法(3)
2006/10/09 PHP
解决php使用异步调用获取数据时出现(错误c00ce56e导致此项操作无法完成)
2013/07/03 PHP
PHP使用ODBC连接数据库的方法
2015/07/18 PHP
在Laravel5.6中使用Swoole的协程数据库查询
2018/06/15 PHP
Laravel模糊查询区分大小写的实例
2019/09/29 PHP
php 使用html5 XHR2实现上传文件与进度显示功能示例
2020/03/03 PHP
javascript之锁定表格栏位
2007/06/29 Javascript
js正确获取元素样式详解
2009/08/07 Javascript
js展开闭合效果演示代码
2013/07/24 Javascript
javascript运行机制之this详细介绍
2014/02/07 Javascript
jquery 显示*天*时*分*秒实现时间计时器
2014/05/07 Javascript
每天一篇javascript学习小结(属性定义方法)
2015/11/19 Javascript
js仿支付宝多方框输入支付密码效果
2016/09/27 Javascript
浅谈js键盘事件全面控制
2016/12/01 Javascript
Bootstrap的popover(弹出框)在append后弹不出(失效)
2017/02/27 Javascript
微信小程序传值以及获取值方法的详解
2019/04/29 Javascript
javascript设计模式 ? 适配器模式原理与应用实例分析
2020/04/13 Javascript
vue自定义指令和动态路由实现权限控制
2020/08/28 Javascript
vuecli项目构建SSR服务端渲染的实现
2020/10/30 Javascript
vue el-upload上传文件的示例代码
2020/12/21 Vue.js
[06:57]DOTA2-DPC中国联赛 正赛 Ehome vs PSG.LGD 选手采访
2021/03/11 DOTA
python进阶教程之异常处理
2014/08/30 Python
python使用BeautifulSoup分页网页中超链接的方法
2015/04/04 Python
Python多线程编程(五):死锁的形成
2015/04/05 Python
python 数据清洗之数据合并、转换、过滤、排序
2017/02/12 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
Python实现动态添加属性和方法操作示例
2018/07/25 Python
如何基于pythonnet调用halcon脚本
2020/01/20 Python
Python列表操作方法详解
2020/02/09 Python
中专生自我鉴定范文
2013/12/19 职场文书
违纪检讨书2000字
2014/02/08 职场文书
2014年大班元旦活动方案
2014/02/26 职场文书
教学质量评估实施方案
2014/03/17 职场文书
2014国庆节标语口号
2014/09/19 职场文书
Pytest中skip和skipif的具体使用方法
2021/06/30 Python
PostgreSQL 插入INSERT、删除DELETE、更新UPDATE、事务transaction
2022/04/12 PostgreSQL