1 Star 0 Fork 1

ant/microphone-recorder-utils

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
index.js 25.29 KB
一键复制 编辑 原始数据 按行查看 历史
“lishisheng” 提交于 2022-12-13 17:24 +08:00 . update test
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/ var __webpack_modules__ = ({
/***/ "./src/browser/browser.ts":
/*!********************************!*\
!*** ./src/browser/browser.ts ***!
\********************************/
/***/ ((__unused_webpack_module, exports) => {
eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nconst win = window.navigator;\r\nclass Browser {\r\n /**\r\n * 获取浏览器类型\r\n * @returns\r\n */\r\n static getBrowserType() {\r\n // 获取浏览器 userAgent\r\n var ua = navigator.userAgent;\r\n // 是否为 Opera\r\n var isOpera = ua.indexOf('Opera') > -1;\r\n // 返回结果\r\n if (isOpera) {\r\n return 'Opera';\r\n }\r\n // 是否为 IE\r\n var isIE = (ua.indexOf('compatible') > -1) && (ua.indexOf('MSIE') > -1) && !isOpera;\r\n var isIE11 = (ua.indexOf('Trident') > -1) && (ua.indexOf(\"rv:11.0\") > -1);\r\n // 返回结果\r\n if (isIE11) {\r\n return 'IE11';\r\n }\r\n else if (isIE) {\r\n // 检测是否匹配\r\n var re = new RegExp('MSIE (\\\\d+\\\\.\\\\d+);');\r\n re.test(ua);\r\n // 获取版本\r\n var ver = parseFloat(RegExp[\"$1\"]);\r\n if (ver == 7) {\r\n return 'IE7';\r\n }\r\n else if (ver == 8) {\r\n return 'IE8';\r\n }\r\n else if (ver == 9) {\r\n return 'IE9';\r\n }\r\n else if (ver == 10) {\r\n return 'IE10';\r\n }\r\n else {\r\n return \"IE\";\r\n }\r\n }\r\n var isEdge = ua.indexOf(\"Edge\") > -1;\r\n if (isEdge) {\r\n return 'Edge';\r\n }\r\n var isFirefox = ua.indexOf(\"Firefox\") > -1;\r\n if (isFirefox) {\r\n return 'Firefox';\r\n }\r\n var isSafari = (ua.indexOf(\"Safari\") > -1) && (ua.indexOf(\"Chrome\") == -1);\r\n if (isSafari) {\r\n return \"Safari\";\r\n }\r\n var isChrome = (ua.indexOf(\"Chrome\") > -1) && (ua.indexOf(\"Safari\") > -1) && (ua.indexOf(\"Edge\") == -1);\r\n if (isChrome) {\r\n return 'Chrome';\r\n }\r\n var isUC = ua.indexOf(\"UBrowser\") > -1;\r\n if (isUC) {\r\n return 'UC';\r\n }\r\n var isQQ = ua.indexOf(\"QQBrowser\") > -1;\r\n if (isQQ) {\r\n return 'QQ';\r\n }\r\n return '';\r\n }\r\n /**\r\n * 设置 getUserMedia 版本兼容( navigator.getUserMedia 或 window.navigator.mediaDevices.getUserMedia)\r\n */\r\n static initUserMedia() {\r\n if (win.mediaDevices === undefined) {\r\n win.mediaDevices = {};\r\n }\r\n if (win.mediaDevices.getUserMedia === undefined) {\r\n win.mediaDevices.getUserMedia = function (constraints) {\r\n let getUserMedia = win.getUserMedia || win.webkitGetUserMedia || win.mozGetUserMedia;\r\n if (!getUserMedia) {\r\n return Promise.reject(new Error(Browser.getBrowserType() + '浏览器不支持 getUserMedia'));\r\n }\r\n return new Promise(function (resolve, reject) {\r\n getUserMedia.call(win, constraints, resolve, reject);\r\n });\r\n };\r\n }\r\n }\r\n /**\r\n * 判断是否为小端字节序\r\n * @returns\r\n */\r\n static isLittleEdian() {\r\n // 判断端字节序\r\n return (function () {\r\n let buffer = new ArrayBuffer(2);\r\n new DataView(buffer).setInt16(0, 256, true);\r\n return new Int16Array(buffer)[0] === 256;\r\n })();\r\n }\r\n}\r\nexports[\"default\"] = Browser;\r\n\n\n//# sourceURL=webpack://microphone-recorder-utils/./src/browser/browser.ts?");
/***/ }),
/***/ "./src/handler/audio_handler.ts":
/*!**************************************!*\
!*** ./src/handler/audio_handler.ts ***!
\**************************************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.AudioHandler = void 0;\r\nconst browser_1 = __webpack_require__(/*! ../browser/browser */ \"./src/browser/browser.ts\");\r\nconst transform_1 = __webpack_require__(/*! ../transform/transform */ \"./src/transform/transform.ts\");\r\n//音频内部数据\r\nclass AudioInfo {\r\n constructor() {\r\n this.outSampleRate = 0; // 采样率\r\n this.outSampleBits = 0; // 采样位数\r\n this.lBuffer = []; // pcm音频数据搜集器(左声道)\r\n this.rBuffer = []; // pcm音频数据搜集器(右声道)\r\n this.leftRealTimeBuffer = []; // 分包后的实时数据(右声道)\r\n this.rightRealTimeBuffer = []; // 分包后的实时数据(右声道)\r\n this.realTimeTotalSize = 0; //实时每次的总包大小\r\n this.maxVol = 0; //当前最大音量\r\n this.vol = 0; //当前音量\r\n this.realTimeAudioData = new DataView(new ArrayBuffer(0)); //实时的音频总数据\r\n this.totalData = new DataView(new ArrayBuffer(0)); //录音开始到结束的总数据\r\n this.totalDuration = 0; //录音总时长\r\n this.totalSize = 0; // 录音文件总长度\r\n this.littleEdian = false; // 是否是小端字节序\r\n this.fileByteTotalSize = 0; // 录音总大小,byte为单位(需要totalSize计算)\r\n this.fileByteTotalRealTimeSize = 0; // 实时录音总大小,byte为单位(需要totalSize计算)\r\n }\r\n}\r\nclass AudioHandler extends AudioInfo {\r\n /**\r\n * 构造默认数据\r\n * @param audioHandlerConfig\r\n */\r\n constructor(audioHandlerConfig) {\r\n super();\r\n this.needRecord = true; // 由于safari问题,导致使用该方案代替disconnect/connect方案\r\n //设置 getUserMedia 版本兼容\r\n browser_1.default.initUserMedia();\r\n //判断当前的客户端 端字节序\r\n this.littleEdian = browser_1.default.isLittleEdian();\r\n //设置处理音频数据的默认配置\r\n let chunkSize = audioHandlerConfig.package == undefined ? 0 : audioHandlerConfig.package.chunkSize;\r\n this.audioHandlerConfig = {\r\n //解析器的临时存储空间大小\r\n analyerFftSize: ~[0, 1024, 2048, 4096, 8192].indexOf(audioHandlerConfig.analyerFftSize) ? chunkSize : 0,\r\n // 输出采样数位 8, 16\r\n outSampleBits: ~[8, 16].indexOf(audioHandlerConfig.outSampleBits) ? audioHandlerConfig.outSampleBits : 16,\r\n // 输出采样率\r\n outSampleRate: ~[8000, 11025, 16000, 22050, 24000, 44100, 48000].indexOf(audioHandlerConfig.outSampleRate) ? audioHandlerConfig.outSampleRate : 0,\r\n // 声道数,1或2\r\n numberOfInputChannels: ~[1].indexOf(audioHandlerConfig.numberOfInputChannels) ? audioHandlerConfig.numberOfInputChannels : 1,\r\n numberOfOutputChannels: ~[1].indexOf(audioHandlerConfig.numberOfOutputChannels) ? audioHandlerConfig.numberOfOutputChannels : 1,\r\n //实时数据 分包配置\r\n package: {\r\n chunkCount: audioHandlerConfig.package == undefined ? 0 : audioHandlerConfig.package.chunkCount,\r\n chunkSize: ~[0, 1024, 2048, 4096, 8192].indexOf(chunkSize) ? chunkSize : 0,\r\n }\r\n };\r\n }\r\n realTime2DconvertTo1D(leftBuffer, rightBuffer) {\r\n let lData = new Float32Array(0), rData = new Float32Array(0), offset = 0; //offset一维的偏移量\r\n if (this.audioHandlerConfig.numberOfOutputChannels && this.audioHandlerConfig.numberOfOutputChannels == 1) {\r\n lData = new Float32Array(this.realTimeTotalSize / 2);\r\n for (let index = 0; index < this.leftRealTimeBuffer.length; index++) {\r\n let tmpData = this.leftRealTimeBuffer[index];\r\n lData.set(tmpData, offset);\r\n offset += tmpData.length;\r\n }\r\n }\r\n offset = 0;\r\n if (this.audioHandlerConfig.numberOfOutputChannels && this.audioHandlerConfig.numberOfOutputChannels > 1) {\r\n rData = new Float32Array(this.realTimeTotalSize / 2);\r\n for (let index = 0; index < this.rightRealTimeBuffer.length; index++) {\r\n let tmpData = this.rightRealTimeBuffer[index];\r\n rData.set(tmpData, offset);\r\n offset += tmpData.length;\r\n }\r\n }\r\n return { left: lData, right: rData };\r\n }\r\n startRecord() {\r\n //检查当前是否已经开启了录音,如果是,则提示录音已经开启\r\n if (this.audioContext) {\r\n return Promise.reject(new Error('录音已经被开启,不需要重复开启'));\r\n }\r\n /*初始化录音*/\r\n //实例化音频上下文\r\n this.audioContext = new (window.AudioContext || window.webkitAudioContext)();\r\n //实例化音频解析器(音频数据过程处理器)\r\n this.analyer = this.audioContext.createAnalyser();\r\n //实例化二阶滤波器(音频数据过程处理器)\r\n this.biquadFilter = this.audioContext.createBiquadFilter();\r\n //实例化增益节点(音频数据过程处理器)\r\n this.gainNode = this.audioContext.createGain();\r\n //创建一个对音频数据进行采样的处理器\r\n let createScript = this.audioContext.createScriptProcessor || this.audioContext.createJavaScriptNode;\r\n //[param1,param2,param3]。\r\n //第一个参数表示音频数据采集大小。只有当前音频数据大小到达这个参数大小,才会触发回调方法 onaudioprocess\r\n //第二第三参数分别表示输入的声道数和输出的声道数\r\n this.recorder = createScript.apply(this.audioContext, [this.audioHandlerConfig.package.chunkSize,\r\n this.audioHandlerConfig.numberOfInputChannels, this.audioHandlerConfig.numberOfOutputChannels]);\r\n this.recorder.onaudioprocess = (e) => {\r\n let leftData = null, rightData = null, maxVol = 0, vol = 0;\r\n //只有一个输出声道\r\n if (this.audioHandlerConfig.numberOfOutputChannels && this.audioHandlerConfig.numberOfOutputChannels == 1) {\r\n //左声道数据\r\n leftData = e.inputBuffer.getChannelData(0);\r\n //累计左声道数据(pcm格式)\r\n this.lBuffer.push(new Float32Array(leftData));\r\n //实时性的数据(pcm格式)\r\n this.leftRealTimeBuffer = new Array(new Float32Array(leftData));\r\n //总音频大小\r\n this.totalSize += leftData.length;\r\n this.realTimeTotalSize += leftData.length;\r\n }\r\n //存在多个输出声道\r\n if (this.audioHandlerConfig.numberOfOutputChannels && this.audioHandlerConfig.numberOfOutputChannels >= 2) {\r\n //右声道数据\r\n rightData = e.inputBuffer.getChannelData(1);\r\n //累计右声道数据(pcm格式)\r\n this.rBuffer.push(new Float32Array(rightData));\r\n //实时性的数据(pcm格式)\r\n this.rightRealTimeBuffer = new Array(new Float32Array(rightData));\r\n //总音频大小\r\n this.totalSize += rightData.length;\r\n this.realTimeTotalSize += rightData.length;\r\n }\r\n //计算总字节录音大小\r\n this.fileByteTotalSize = Math.floor(this.totalSize / Math.max(this.audioContext.sampleRate / this.audioHandlerConfig.outSampleRate, 1))\r\n * (this.audioHandlerConfig.outSampleBits / 8);\r\n //计算实时数据总数据大小\r\n this.fileByteTotalSize = Math.floor(this.realTimeTotalSize / Math.max(this.audioContext.sampleRate / this.audioHandlerConfig.outSampleRate, 1))\r\n * (this.audioHandlerConfig.outSampleBits / 8);\r\n //计算音频百分比\r\n if (leftData) {\r\n this.vol = Math.max(Math.max.apply(Math, leftData) * 100, this.vol);\r\n }\r\n if (rightData) {\r\n this.vol = Math.max(Math.max.apply(Math, rightData) * 100, this.vol);\r\n }\r\n //计算录音总时长\r\n this.totalDuration += this.audioHandlerConfig.package.chunkSize / this.audioContext.sampleRate;\r\n //实时数据总大小 等于分包数据预期大小 就设置回调接口的入参\r\n let expectedRealTimeTotalSize = this.audioHandlerConfig.package.chunkCount * this.audioHandlerConfig.package.chunkSize;\r\n if (this.realTimeTotalSize == expectedRealTimeTotalSize) {\r\n let realTimeData = this.realTime2DconvertTo1D(this.leftRealTimeBuffer, this.rightRealTimeBuffer);\r\n let realTimeCompressData = (0, transform_1.compress)(realTimeData, this.audioContext.sampleRate, this.audioHandlerConfig.outSampleRate);\r\n // 按采样位数重新编码\r\n this.realTimeAudioData = (0, transform_1.encodePCM)(realTimeCompressData, this.audioHandlerConfig.outSampleBits, this.littleEdian);\r\n //设置回调函数的入参数据\r\n this.onProgress(this);\r\n //清空实时数据大小记录值\r\n this.realTimeTotalSize = 0;\r\n }\r\n };\r\n //开启麦克风\r\n const constraints = {\r\n audio: {\r\n echoCancellation: false,\r\n autoGainControl: false,\r\n noiseCancellation: false\r\n },\r\n video: false\r\n };\r\n const userMedia = navigator.mediaDevices.getUserMedia(constraints)\r\n .then((stream) => {\r\n // audioInput表示音频源节点 将stream转换为音频输入源节点\r\n this.audioInput = this.audioContext.createMediaStreamSource(stream);\r\n this.audioStream = stream;\r\n }, // 报错丢给外部使用者catch,后期可在此处增加建议性提示\r\n // 报错丢给外部使用者catch,后期可在此处增加建议性提示\r\n error => {\r\n // 抛出异常\r\n new Error(error.name + \" : \" + error.message);\r\n }).then(() => {\r\n //音频节点的连接\r\n this.audioInput.connect(this.analyer);\r\n this.analyer.connect(this.gainNode);\r\n this.gainNode.connect(this.biquadFilter);\r\n this.biquadFilter.connect(this.recorder);\r\n this.recorder.connect(this.audioContext.destination);\r\n });\r\n return userMedia;\r\n }\r\n stopRecord() {\r\n this.audioInput && this.audioInput.disconnect();\r\n this.analyer && this.analyer.disconnect();\r\n this.recorder && this.recorder.disconnect();\r\n this.gainNode && this.gainNode.disconnect();\r\n this.biquadFilter && this.biquadFilter.disconnect();\r\n this.audioContext = undefined;\r\n }\r\n pause() {\r\n this.audioContext && this.audioContext.suspend();\r\n }\r\n resume() {\r\n this.audioContext && this.audioContext.resume();\r\n }\r\n playTotalRecord() {\r\n throw new Error(\"Method not implemented.\");\r\n }\r\n playNRecord(seconds) {\r\n throw new Error(\"Method not implemented.\");\r\n }\r\n exportTotalRecord(format) {\r\n throw new Error(\"Method not implemented.\");\r\n }\r\n exportNRecord(format, seconds) {\r\n throw new Error(\"Method not implemented.\");\r\n }\r\n destroyAudioHandlerInstance() {\r\n throw new Error(\"Method not implemented.\");\r\n }\r\n}\r\nexports.AudioHandler = AudioHandler;\r\n\n\n//# sourceURL=webpack://microphone-recorder-utils/./src/handler/audio_handler.ts?");
/***/ }),
/***/ "./src/index.ts":
/*!**********************!*\
!*** ./src/index.ts ***!
\**********************/
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.AudioHandler = void 0;\r\nconst audio_handler_1 = __webpack_require__(/*! ./handler/audio_handler */ \"./src/handler/audio_handler.ts\");\r\nObject.defineProperty(exports, \"AudioHandler\", ({ enumerable: true, get: function () { return audio_handler_1.AudioHandler; } }));\r\n\n\n//# sourceURL=webpack://microphone-recorder-utils/./src/index.ts?");
/***/ }),
/***/ "./src/transform/transform.ts":
/*!************************************!*\
!*** ./src/transform/transform.ts ***!
\************************************/
/***/ ((__unused_webpack_module, exports) => {
eval("\r\nObject.defineProperty(exports, \"__esModule\", ({ value: true }));\r\nexports.encodeWAV = exports.encodePCM = exports.compress = void 0;\r\n/**\r\n * 在data中的offset位置开始写入str字符串\r\n * @param {TypedArrays} data 二进制数据\r\n * @param {Number} offset 偏移量\r\n * @param {String} str 字符串\r\n */\r\nfunction writeString(data, offset, str) {\r\n for (let i = 0; i < str.length; i++) {\r\n data.setUint8(offset + i, str.charCodeAt(i));\r\n }\r\n}\r\n/**\r\n * 数据合并压缩\r\n * 根据输入和输出的采样率压缩数据,\r\n * 比如输入的采样率是48k的,我们需要的是(输出)的是16k的,由于48k与16k是3倍关系,\r\n * 所以输入数据中每隔3取1位\r\n *\r\n * @param {float32array} data [-1, 1]的pcm数据\r\n * @param {number} inputSampleRate 输入采样率\r\n * @param {number} outputSampleRate 输出采样率\r\n * @returns {float32array} 压缩处理后的二进制数据\r\n */\r\nfunction compress(data, inputSampleRate, outputSampleRate) {\r\n // 压缩,根据采样率进行压缩\r\n let rate = inputSampleRate / outputSampleRate, compression = Math.max(rate, 1), lData = data.left, rData = data.right, length = Math.floor((lData.length + rData.length) / rate), result = new Float32Array(length), index = 0, j = 0;\r\n // 循环间隔 compression 位取一位数据\r\n while (index < length) {\r\n // 取整是因为存在比例compression不是整数的情况\r\n let temp = Math.floor(j);\r\n result[index] = lData[temp];\r\n index++;\r\n if (rData.length) {\r\n /*\r\n * 双声道处理\r\n * e.inputBuffer.getChannelData(0)得到了左声道4096个样本数据,1是右声道的数据,\r\n * 此处需要组和成LRLRLR这种格式,才能正常播放,所以要处理下\r\n */\r\n result[index] = rData[temp];\r\n index++;\r\n }\r\n j += compression;\r\n }\r\n // 返回压缩后的一维数据\r\n return result;\r\n}\r\nexports.compress = compress;\r\n/**\r\n * 转换到我们需要的对应格式的编码\r\n *\r\n * @param {float32array} bytes pcm二进制数据\r\n * @param {number} sampleBits 采样位数\r\n * @param {boolean} littleEdian 是否是小端字节序\r\n * @returns {dataview} pcm二进制数据\r\n */\r\nfunction encodePCM(bytes, sampleBits, littleEdian = true) {\r\n let offset = 0, dataLength = bytes.length * (sampleBits / 8), buffer = new ArrayBuffer(dataLength), data = new DataView(buffer);\r\n // 写入采样数据\r\n if (sampleBits === 8) {\r\n for (let i = 0; i < bytes.length; i++, offset++) {\r\n // 范围[-1, 1]\r\n let s = Math.max(-1, Math.min(1, bytes[i]));\r\n // 8位采样位划分成2^8=256份,它的范围是0-255;\r\n // 对于8位的话,负数*128,正数*127,然后整体向上平移128(+128),即可得到[0,255]范围的数据。\r\n let val = s < 0 ? s * 128 : s * 127;\r\n val = +val + 128;\r\n data.setInt8(offset, val);\r\n }\r\n }\r\n else {\r\n for (let i = 0; i < bytes.length; i++, offset += 2) {\r\n let s = Math.max(-1, Math.min(1, bytes[i]));\r\n // 16位的划分的是2^16=65536份,范围是-32768到32767\r\n // 因为我们收集的数据范围在[-1,1],那么你想转换成16位的话,只需要对负数*32768,对正数*32767,即可得到范围在[-32768,32767]的数据。\r\n data.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, littleEdian);\r\n }\r\n }\r\n return data;\r\n}\r\nexports.encodePCM = encodePCM;\r\n/**\r\n * 编码wav,一般wav格式是在pcm文件前增加44个字节的文件头,\r\n * 所以,此处只需要在pcm数据前增加下就行了。\r\n *\r\n * @param {DataView} bytes pcm二进制数据\r\n * @param {number} inputSampleRate 输入采样率\r\n * @param {number} outputSampleRate 输出采样率\r\n * @param {number} numChannels 声道数\r\n * @param {number} oututSampleBits 输出采样位数\r\n * @param {boolean} littleEdian 是否是小端字节序\r\n * @returns {DataView} wav二进制数据\r\n */\r\nfunction encodeWAV(bytes, inputSampleRate, outputSampleRate, numChannels, oututSampleBits, littleEdian = true) {\r\n let sampleRate = outputSampleRate > inputSampleRate ? inputSampleRate : outputSampleRate, // 输出采样率较大时,仍使用输入的值,\r\n sampleBits = oututSampleBits, buffer = new ArrayBuffer(44 + bytes.byteLength), data = new DataView(buffer), channelCount = numChannels, // 声道\r\n offset = 0;\r\n // 资源交换文件标识符\r\n writeString(data, offset, 'RIFF');\r\n offset += 4;\r\n // 下个地址开始到文件尾总字节数,即文件大小-8\r\n data.setUint32(offset, 36 + bytes.byteLength, littleEdian);\r\n offset += 4;\r\n // WAV文件标志\r\n writeString(data, offset, 'WAVE');\r\n offset += 4;\r\n // 波形格式标志\r\n writeString(data, offset, 'fmt ');\r\n offset += 4;\r\n // 过滤字节,一般为 0x10 = 16\r\n data.setUint32(offset, 16, littleEdian);\r\n offset += 4;\r\n // 格式类别 (PCM形式采样数据)\r\n data.setUint16(offset, 1, littleEdian);\r\n offset += 2;\r\n // 声道数\r\n data.setUint16(offset, channelCount, littleEdian);\r\n offset += 2;\r\n // 采样率,每秒样本数,表示每个通道的播放速度\r\n data.setUint32(offset, sampleRate, littleEdian);\r\n offset += 4;\r\n // 波形数据传输率 (每秒平均字节数) 声道数 × 采样频率 × 采样位数 / 8\r\n data.setUint32(offset, channelCount * sampleRate * (sampleBits / 8), littleEdian);\r\n offset += 4;\r\n // 快数据调整数 采样一次占用字节数 声道数 × 采样位数 / 8\r\n data.setUint16(offset, channelCount * (sampleBits / 8), littleEdian);\r\n offset += 2;\r\n // 采样位数\r\n data.setUint16(offset, sampleBits, littleEdian);\r\n offset += 2;\r\n // 数据标识符\r\n writeString(data, offset, 'data');\r\n offset += 4;\r\n // 采样数据总数,即数据总大小-44\r\n data.setUint32(offset, bytes.byteLength, littleEdian);\r\n offset += 4;\r\n // 给wav头增加pcm体\r\n for (let i = 0; i < bytes.byteLength;) {\r\n data.setUint8(offset, bytes.getUint8(i));\r\n offset++;\r\n i++;\r\n }\r\n return data;\r\n}\r\nexports.encodeWAV = encodeWAV;\r\n\n\n//# sourceURL=webpack://microphone-recorder-utils/./src/transform/transform.ts?");
/***/ })
/******/ });
/************************************************************************/
/******/ // The module cache
/******/ var __webpack_module_cache__ = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/ // Check if module is in cache
/******/ var cachedModule = __webpack_module_cache__[moduleId];
/******/ if (cachedModule !== undefined) {
/******/ return cachedModule.exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = {
/******/ // no module.id needed
/******/ // no module.loaded needed
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/************************************************************************/
/******/
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module can't be inlined because the eval devtool is used.
/******/ var __webpack_exports__ = __webpack_require__("./src/index.ts");
/******/
/******/ })()
;
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
TypeScript
1
https://gitee.com/li_shi_sheng/microphone-recorder-utils.git
git@gitee.com:li_shi_sheng/microphone-recorder-utils.git
li_shi_sheng
microphone-recorder-utils
microphone-recorder-utils
master

搜索帮助