参考 :

http://air.ghost.io/recording-to-an-audio-file-using-html5-and-js/ (html5 基础)

https://github.com/muaz-khan/RecordRTC

https://github.com/webpack-contrib/worker-loader

https://github.com/webpack-contrib/file-loader

https://github.com/muaz-khan/RecordRTC/issues/31 (wav 太大的解决方案)

https://github.com/muaz-khan/Ffmpeg.js/blob/master/wav-to-ogg.html#L209 ( ftmpeg wav to ogg 压缩方案 )

http://audior.ec/blog/recording-mp3-using-only-html5-and-javascript-recordmp3-js/ (wav to mp3 压缩方案, 超小, 声音也差.., 可以使用 lamejs 比较新)

使用插件

npm install recordrtc
npm install --save-dev file-loader
npm install --save-dev worker-loader

要使用 file,worker loading 需要在 tsconfig.app.json 加上 "node"
  "compilerOptions": {"types": ["node"]},

import * as RecordRTC from 'recordrtc';
startRecord() {navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {let recordRTC = RecordRTC(stream, {type: 'audio',recorderType: RecordRTC.StereoAudioRecorder,disableLogs: true //leftChannel: true,//numberOfAudioChannels: 1 // or leftChannel:true
    });recordRTC.startRecording();this.recordRTC = recordRTC;this.stream = stream;}).catch(() => {console.log('user no allow');});
}

通过 html5 的 navigator.mediaDevices.getUserMedia 获取用户的 permission, 然后就可以获取到声音了

通过 RecordRTC 来做录制. 如果是要 to mp3 的话, 可以选择单声道 (不过我试过 to mp3 效果声音效果不好, 所以最好用了 .ogg)

 stop() {let recordRTC = this.recordRTC;recordRTC.stopRecording(() => {    // 关闭 html5 navigator.mediaDevices.getUserMediavar track = this.stream.getTracks()[0]; // 0 是因为我们只有一个 track, 是可以 track 2 个的, 声音和影像
      track.stop();// ff 可以 skip 掉 fileReader, 直接拿 recordRTC.blob new File 也可以, 因为 ff 返回的就是 ogg 了 // 下面是针对 chrome 返回的是 wav, 很大, 所以使用 ffmpeg 压缩去 ogg let fileReader = new FileReader();fileReader.onload = () => {recordRTC.clearRecordedData(); // reader 读出来后就可以释放 recordRTC 了. //压缩是很慢的, 所以要另开一个线程var WorkerConstructor = require("worker-loader!./worker2.js"); var worker = new WorkerConstructor();worker.onmessage = (e) => {var result = e.data[0];// edge 不可以跑哦, 只有 chrome and ff ok var blob = new File([result.data], 'whatever.ogg', {type: 'audio/ogg'});let formData = new FormData();formData.append('uploadFile', blob, 'whatever.ogg');// 上传this.http.post('/api/uploadFile', formData).subscribe(() => {console.log('done');});// 做成 audio let audio = new Audio();audio.controls = true;let url = window.URL.createObjectURL(blob);audio.src = url;let recordMp3Container = document.getElementById('recordmp3-container');recordMp3Container.appendChild(audio);audio.play();// 关闭 worker
          worker.terminate(); };worker.postMessage(fileReader.result);};fileReader.readAsArrayBuffer(recordRTC.blob); });}

worker2.js

let url = require("file-loader!./ffmpeg_asm.js");  self.importScripts(url);let print = () => { };
self.onmessage = (event) => {let blob = event.data;let result = ffmpeg_run({print: print,printErr: print,files: [{data: new Uint8Array(blob),name: "whatever.wav"}],arguments: '-i whatever.wav -c:a vorbis -b:a 4800k -strict experimental output.ogg'.split(' ')});self.postMessage(result);
};

关键就是调用了 ffmpeg_run

https://archive.org/download/ffmpeg_asm/ffmpeg_asm.js

这个转换器 18mb 非常大哦. 不过只要下载一次, 所以 ok 啦.

wav to mp3

步骤和上面一下, 使用单声道.

然后 worker 用下面这个

//var url = require("file-loader!./lame.all.js");
var url = require("file-loader!lamejs/lame.all.js");  self.importScripts(url);self.onmessage = function (e) {let stream = e.data.stream;let streamArray = new Int16Array(stream);streamArray = streamArray.slice(50); //去掉一开始的杂音let buffer = [];let mp3encoder = new lamejs.Mp3Encoder(1, 44100, 128);let mp3Data = mp3encoder.encodeBuffer(streamArray);buffer.push(mp3Data);mp3Data = mp3encoder.flush(); //获取最后一个 part
    buffer.push(mp3Data);let blob = new Blob(buffer, { type: 'audio/mp3' });var workerResult = {stream: blob};self.postMessage(workerResult);
}

调用 lamejs 去压缩.

最后想说的是... RecordRTC 这个 plugin 是使用原生 MediaRecorder 接口来实现的

MediaRecorder 只有 chrome and firefox 支持.  chrome 输出的格式是 webm, firefox 则是 ogg, RecordRTC 做了些修改输出的是 wav

以上 3 种格式 ios safari 都不支持, 它只支持 mp3... 伤感...

recordRTC

import { HttpClient } from '@angular/common/http';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import * as RecordRTC from 'recordrtc';declare let MediaRecorder: any;function invokeSaveAsDialog(file, fileName) {if (!file) {throw 'Blob object is required.';}if (!file.type) {try {file.type = 'video/webm';} catch (e) { }}var fileExtension = (file.type || 'video/webm').split('/')[1];if (fileName && fileName.indexOf('.') !== -1) {var splitted = fileName.split('.');fileName = splitted[0];fileExtension = splitted[1];}var fileFullName = (fileName || (Math.round(Math.random() * 9999999999) + 888888888)) + '.' + fileExtension;if (typeof navigator.msSaveOrOpenBlob !== 'undefined') {return navigator.msSaveOrOpenBlob(file, fileFullName);} else if (typeof navigator.msSaveBlob !== 'undefined') {return navigator.msSaveBlob(file, fileFullName);}var hyperlink = document.createElement('a');hyperlink.href = URL.createObjectURL(file);hyperlink.download = fileFullName;(document.body || document.documentElement).appendChild(hyperlink);if (typeof hyperlink.click === 'function') {hyperlink.click();} else {hyperlink.target = '_blank';hyperlink.dispatchEvent(new MouseEvent('click', {view: window,bubbles: true,cancelable: true}));}URL.revokeObjectURL(hyperlink.href);
}
let mp3 = true;@Component({selector: 'app-root',templateUrl: './app.component.html',styleUrls: ['./app.component.css'],changeDetection: ChangeDetectionStrategy.OnPush
})
export class AppComponent {constructor(private http: HttpClient) { }title = 'app';recordRTC: any;stop() {let recordRTC = this.recordRTC;recordRTC.stopRecording(() => {// 关闭 html5 navigator.mediaDevices.getUserMediavar track = this.stream.getTracks()[0]; // 0 是因为我们只有一个 track, 是可以 track 2 个的, 声音和影像
      track.stop();// ff 可以 skip 掉 fileReader, 直接拿 recordRTC.blob new File 也可以, 因为 ff 返回的就是 ogg 了 // 下面是针对 chrome 返回的是 wav, 很大, 所以使用 ffmpeg 压缩去 ogg let fileReader = new FileReader();fileReader.onload = () => {recordRTC.clearRecordedData(); // reader 读出来后就可以释放 recordRTC 了. if (mp3) {//压缩是很慢的, 所以要另开一个线程        var WorkerConstructor = require("worker-loader!./worker.js");var worker = new WorkerConstructor();}else {//压缩是很慢的, 所以要另开一个线程        var WorkerConstructor = require("worker-loader!./worker2.js");var worker = new WorkerConstructor();}worker.onmessage = (e) => {if (mp3) {console.log(e);var result = e.data.stream;        invokeSaveAsDialog(result, 'output.mp3');// recordRTC.save('dadad');
          }else {var result = e.data[0];// edge 不可以跑哦, 只有 chrome and ff ok var blob = new File([result.data], 'output.ogg', {type: 'audio/ogg'});let formData = new FormData();formData.append('uploadFile', blob, 'output.ogg');// 上传// this.http.post('/api/uploadFile', formData).subscribe(() => {//   console.log('done');// });
invokeSaveAsDialog(blob, 'output.ogg');// 做成 audio let audio = new Audio();audio.controls = true;let url = window.URL.createObjectURL(blob);audio.src = url;let recordMp3Container = document.getElementById('recordmp3-container');recordMp3Container.appendChild(audio);audio.play();// 关闭 worker
            worker.terminate();}};worker.postMessage(fileReader.result);};fileReader.readAsArrayBuffer(recordRTC.blob);});}stream: anygo() {navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {let obj = {type: 'audio',recorderType: RecordRTC.StereoAudioRecorder,disableLogs: true,// numberOfAudioChannels: 1 // or leftChannel:true
      }if(mp3) obj['leftChannel'] = true;let recordRTC = RecordRTC(stream,obj);recordRTC.startRecording();this.recordRTC = recordRTC;this.stream = stream;}).catch(() => {console.log('user no allow');});}
}

View Code

mp3

//var url = require("file-loader!./lame.all.js");
var url = require("file-loader!lamejs/lame.all.js");self.importScripts(url);self.onmessage = function (e) {let stream = e.data;let streamArray = new Int16Array(stream);streamArray = streamArray.slice(50); //去掉一开始的杂音let buffer = [];let mp3encoder = new lamejs.Mp3Encoder(1, 44100, 128);let mp3Data = mp3encoder.encodeBuffer(streamArray);buffer.push(mp3Data);mp3Data = mp3encoder.flush(); //获取最后一个 part
    buffer.push(mp3Data);let blob = new Blob(buffer, { type: 'audio/mp3' });var workerResult = {stream: blob};self.postMessage(workerResult);
}

View Code

ogg

let url = require("file-loader!./ffmpeg_asm.js");self.importScripts(url);let print = (text) => {console.log(text);};
self.onmessage = (event) => {console.log('worker e ', event);console.log('worker e.data ', event.data);let blob = event.data;let result = ffmpeg_run({print: print,printErr: print,files: [{data: new Uint8Array(blob),name: "whatever.wav"}],arguments: '-i whatever.wav -c:a vorbis -b:a 4800k -strict experimental output.ogg'.split(' ')});self.postMessage(result);
};

View Code

.


转载于:https://www.cnblogs.com/keatkeat/p/7497227.html

录音 voice record相关推荐

  1. linux录音命令,安装Linux 录音软件 Record Audio

    Record Audio 录音机可以录制系统声效卡声音和麦克风声音,现在还有一个先进的功能:自动录制Skype通话记录. audio-recorder Record Audio功能: 录制系统的声卡, ...

  2. iOS音频开发相关(二)录音 `AVAudioRecorder`

    录音 AVAudioRecorder 初始化方法 AVFormatIDKey AVSampleRateKey AVNumberOfChannelsKey linear PCM keys AVLinea ...

  3. 网页录音,html5录音

    转载至:http://blog.csdn.net/hardgirls/article/details/53997001 网页在线录音并上传 前段时间接了一个外包项目,有一个功能是网页在线录音并上传云服 ...

  4. 网页上面嵌入录音插件,可以录音,播放

    网页在线录音并上传 前段时间接了一个外包项目,有一个功能是网页在线录音并上传云服务器的需求,之前没有接触过,想着Google了一下找个demo改改: 找到三个,基本能满足需求: https://git ...

  5. 用计算机唱歌弹奏china,如何用电脑进行吉它弹唱录音!

    相信这里许多朋友都喜欢有自已录制好的歌曲,但若是用普通录机录的话音质会较差,到录音棚的话花费又非常大,因些推荐大家用电脑录音,下面只是我的一点点经验,高手就免看了. 电脑要求: 硬件:CPU 奔三 1 ...

  6. 手机所有录音功能失效_录音机录音功能失效,录音机怎么恢复录音-

    录音机现在很少人使用,因为它的体积比较的大,携带不方便有点累赘. 但是也有很多人是喜欢使用录音机收听广播和录音的,有一些人喜欢玩录音和收听别人的录音. 电脑现在也是有录音机功能的,而且功能比较的强大, ...

  7. 语音识别—前端录音传给后台语音识别

    实现前端录音,将音频blob传给服务器,然后在服务器端使用百度AI语音识别将结果返回给前端 上一篇文章是将百度AI语音识别Nodejs SDK版的进行了一遍演示加识别结果返回给前端显示,这里是完整的进 ...

  8. ios android mid音频文件,iOS 录音 音频 视频 控制中心

    录音 最近项目中需要录音功能,为此在写了一个录音的小模块. 首先需要添加AVFoundation.framework lame.h 帮助链接 下面直接上代码 #import #import #impo ...

  9. OCiOS开发:录音与音效

    录音 AVAudioRecorder是AVFoundation中的类,提供了简单的录音功能. 常用方法 初始化方法 - (id)initWithURL:(NSURL *)url settings:(N ...

最新文章

  1. 转android项目开发 工作日志 2011.10.8--onConfigurationChanged屏幕改变事件
  2. 破windows xp登陆密码
  3. 安卓平分位置layout_weight学习记录
  4. php html 转xml,用PHP生成XML文档(转义字符)
  5. shell字段拼接日期_shell 脚本字符串拼接
  6. Maven下载Sql Server 2008的驱动包
  7. Android之自定义ViewGroup
  8. SQLServer导入excel报错因缺少插件
  9. ASP.NET Session 的详细解释
  10. ReactNative从零到完整项目-Flexbox使用
  11. C语言静态链表常用吗,C语言实现静态链表
  12. gitbook 插件 图片查看
  13. sql if语句实例
  14. mac安装教程 sqlyog_Mac开发环境配置:Homebrew的安装
  15. 【微信小程序】数据绑定
  16. 2021 Java面试真题集锦
  17. movie起居类分类词汇
  18. 学习第1天:认识Linux系统和红帽认证
  19. The Picture of Dorian Gray——17
  20. 基于python随机产生英文单词,句子,段落

热门文章

  1. 为什么电流PI调节器输出的是电压?为什么转速PI调节器输出的就是电流?(双闭环FOC)
  2. 查看当前服务器登录的docker用户名和密码
  3. SentinelDashboard-Nacos动态数据源-SpringCloudGateway
  4. nginx: [emerg] cannot load certificate SSL: error:0200100D:system library:fopen:Permission denied:fo
  5. day03-JavaScript入门
  6. 笔记本如何读取台式机的硬盘?
  7. 好用的前端组件-大数据看板
  8. CVM 单节点集群配置
  9. 神经网络与深度学习作业8:RNN - 简单循环网络
  10. matlab stereo,matlab stereo_gui立体标定