@elelel13223/web-recorder-module
v3.0.5
Published
A simple web recorder module
Readme
RecorderModule 录音模块说明文档(v3.0.5)
1. RecorderModule 模块介绍
RecorderModule(v3.0.5) 是一个 javascript 模块,它封装了 Web 录音 API,并提供了一系列便捷的方法来实现音频录制、播放、上传和下载等功能(最后有vue示例)。(https://www.npmjs.com/package/@elelel13223/web-recorder-module)
2.1 模块导入
JavaScript
npm install @elelel13223/web-recorder-module2.2 实例化 RecorderModule
在您需要使用录音功能的代码中,实例化 RecorderModule。构造函数接受一个可选的 options 对象,用于配置模块的行为和回调函数。
JavaScript
//参数示例
new RecorderModule({
API: 'http://127.0.0.1:8080',//必填(*)
AUTHORIZATION: 'token',//必填(*)
SID: '', // 必填(*),会话ID,用于API请求的会话标识
sampleRate: 16000, // 可选,录音采样率,单位 Hz,表示每秒钟采集的音频样本数,常用的采样率有 16000Hz 和 44100Hz
bitRate: 16, // 可选,录音比特率,单位 kbps,表示音频数据的压缩率,影响音质和文件大小,常用的比特率有 16kbps, 32kbps, 64kbps 等
recordType: "mp3", // 可选,录音类型,目前只支持mp3
realTimeTranscription: true, //可选, 是否实时转写,为 true,则实时将录音缓存数据发送到后端进行转写,为 false,则等待录音结束后再发送
processInterval: 5000,// 可选,数据处理间隔时间 (毫秒),每隔多久处理一次录音缓存数据并发送到后端,默认 5000 毫秒 (5秒)
aiTimeout: 5000, // 请求接口超时时间,默认 5000 毫秒 (5秒)
onTimeout: null, // 请求接口超时的回调函数,默认为 null
waveConfig: { // 波形可视化配置 (用于 Recorder.WaveView)
/* 通用波形效果配置 */
scale: 2, // 缩放系数 (正整数),用于提高移动端清晰度,建议保持默认值 2
speed: 9, // 波形移动速度系数,值越大移动越快,可调整波形动画速度
phase: 21.8, // 相位,调整速度后可能需要调整此值,以获得更佳的波形视觉效果
fps: 20, // 帧率 (每秒绘制帧数),影响动画流畅度,调整后可能需同步调整 phase 值
keep: true, // 是否保持波形,true: 停止输入后波形保持,false: 停止输入后波形消失为直线
lineWidth: 3, // 基础线条粗细 (像素)
/* 渐变色配置 (颜色数组,[位置1, 颜色1, 位置2, 颜色2, ...]) */
linear1: [0, "rgba(150,96,238,1)", 0.2, "rgba(170,79,249,1)", 1, "rgba(53,199,253,1)"], // 线条渐变色1 (从左到右)
linear2: [0, "rgba(209,130,255,0.6)", 1, "rgba(53,199,255,0.6)"], // 线条渐变色2 (从左到右)
linearBg: [0, "rgba(255,255,255,0.2)", 1, "rgba(54,197,252,0.2)"], // 背景渐变色 (从上到下)
},
onPowerLevelUpdate: (durationText) => { // 录音音量更新回调函数,durationText 参数表示当前录音持续时间
this.powerLevelText = durationText;
},
onTranscriptionResult: (text) => { // 实时语音转录结果回调函数,识别结果
this.transcriptionResult += text + ' ';
},
onRecordStop: (blob: Blob, duration) => { // 录音停止回调函数,录音停止后被调用,参数 blob 包含录音音频数据,duration 参数表示录音时长
console.log('录音已停止, Blob:', blob, '时长:', duration);
this.recBlob = blob;
this.isRecording = false;
},
onTranscriptionComplete: (fullText) => { // 转译完成文本回调
console.log('转译完成 (onTranscriptionComplete), 完整文本:', fullText);
},
onRecordError: (errorMsg) => { // 录音错误回调函数,当录音过程中发生错误时被调用,参数 errorMsg 包含错误信息
console.error('录音错误:', errorMsg);
this.isRecording = false;
alert('录音发生错误: ' + errorMsg);
},
})options 参数说明 (构造函数入参)
options 是一个对象,用于配置 RecorderModule 的行为和回调函数。它包含以下属性:
| 参数名 | 类型 | 描述 | 默认值 |
| --------------------------- | -------------- | :----------------------------------------------------------- | ------------------------------------------------------- |
| API | String | 必需。 音频上传 API 的地址。当您调用 recUpload 或在 processAudioData 中发送实时音频数据时,将使用此地址。 | 'http://127.0.0.1:8080' |
| AUTHORIZATION | String | 必需。 API 授权 Token,用于 API 请求的身份验证。在发送音频数据到服务器时,将作为请求头 Authorization 的值。 | 'Your_Default_Token' |
| SID | String | 必需。 会话ID,用于API请求的会话标识。 | 'Your_Default_SID' |
| realTimeTranscription | Bool | 可选。 是否进行实时转写。为 true,则实时将录音缓存数据发送到后端进行转写,为 false,则等待录音结束后再发送。(若为false,无需设置processInterval参数) | false |
| processInterval | Int | 可选。 数据处理间隔时间 (毫秒),每隔多久处理一次录音缓存数据并发送到后端,默认 5000 毫秒 (5秒),实时语音转文字。 | 5000(5秒) |
| aiTimeout | Int | **可选。 请求接口超时时间,默认 5000 毫秒 (5秒) ** | 5000(5秒) |
| onTimeout | Function | **可选。请求接口超时的回调函数,默认为 null ** | null |
| recordType | String | 可选。 录音类型,目前只支持mp3。 | mp3 |
| sampleRate | Int | 可选。 录音采样率,单位 Hz,表示每秒钟采集的音频样本数,常用的采样率有 16000Hz 和 44100Hz。 | 16000 |
| bitRate | Int | 可选。 录音比特率,单位 kbps,表示音频数据的压缩率,影响音质和文件大小,常用的比特率有 16kbps, 32kbps, 64kbps 等。 | 16 |
| waveConfig | Object | 可选。 可视化配置,用于配置音频波形可视化效果 | 具体配置参考上面实例化 RecorderModule里面的waveConfig |
| onPowerLevelUpdate | Function | 可选。 录音时长更新回调函数。在录音过程中,会定时调用此函数,传递当前录音时长 (格式化为 mm:ss 字符串)。 | undefined |
| onTranscriptionResult | Function | 可选。 语音转文字结果回调函数。当服务器返回转文字结果时,会调用此函数,传递转文字的文本数据。 | undefined |
| onRecordStop | Function | 可选。 录音停止回调函数。当录音正常停止时,会调用此函数,传递录音的 Blob 对象,录音时长 (毫秒)。 | undefined |
| onTranscriptionComplete | Function | 可选。 录音停止后,转译完成文本回调。 | undefined |
| onRecordError | Function | 可选。 录音错误回调函数。当录音过程中发生错误(例如,麦克风授权失败、录音过程错误等)时,会调用此函数,传递错误信息字符串。 | undefined |
2.3 RecorderModule API 函数说明
以下是 RecorderModule 提供的 API 函数的详细说明,包括函数功能、参数、返回值和使用示例。
2.3.1 recOpen(waveElem)(注意* waveElem参数)
功能: 打开录音,请求麦克风权限,初始化录音资源。同时可以设置音频可视化效果。
参数:
waveElem:HTMLElement(必需)。 用于显示音频波形或频谱的 HTML 元素。可以是<div>或<canvas>等元素。如果不需要可视化,可以传入null或undefined。
返回值: 无。
使用示例:
JavaScript
const waveDisplayElement = document.getElementById('waveDisplay'); // 获取用于显示波形的元素 recorder.recOpen(waveDisplayElement); // 打开录音并设置波形显示元素
2.3.2 recClose()
功能: 关闭录音,释放麦克风资源。
参数: 无。
返回值: 无。
使用示例:
JavaScript
recorder.recClose(); // 关闭录音
2.3.3 recStart()
功能: 开始录音。只有在成功调用
recOpen()打开录音后,才能调用此方法。参数: 无。
返回值: 无。
使用示例:
JavaScript
recorder.recStart(); // 开始录音
2.3.4 recPause()
功能: 暂停录音。
参数: 无。
返回值: 无。
使用示例:
JavaScript
recorder.recPause(); // 暂停录音
2.3.5 recResume()
功能: 恢复暂停的录音。
参数: 无。
返回值: 无。
使用示例:
JavaScript
recorder.recResume(); // 恢复录音
2.3.6 recStop()
功能: 停止录音,结束录音过程,并生成音频 Blob 对象。录音结束后,会触发
onRecordStop回调函数。参数: 无。
返回值: 无。
使用示例:
JavaScript
recorder.recStop(); // 停止录音
2.3.7 recUpload()
功能: 上传录音文件到服务器。上传的文件是最后一次
recStop()生成的音频 Blob 对象。上传成功后,根据服务器返回的数据,可能会触发onTranscriptionResult回调函数。参数: 无。
返回值: 无。
使用示例:
JavaScript
recorder.recUpload(); // 上传录音文件
2.3.8 recLocalDown()
功能: 本地下载录音文件。浏览器会自动下载最后一次
recStop()生成的音频文件到本地。参数: 无。
返回值: 无。
使用示例:
JavaScript
recorder.recLocalDown(); // 本地下载录音文件
2.3.9 processAudioData(buffers, bufferSampleRate)
功能: 内部函数,用于处理录音过程中的音频数据缓存。通常无需手动调用。该函数在录音库内部
onProcess回调中被定时调用,用于缓存 PCM 数据,并定时将缓存的 PCM 数据转换为 MP3 Blob 发送到服务器进行实时转文字。参数
:
buffers:Array<Float32Array>- 音频数据缓存块,由录音库onProcess回调提供。bufferSampleRate:number- 音频数据的采样率,由录音库onProcess回调提供。
返回值: 无。
注意: 此函数为内部处理函数,一般情况下,您不需要直接调用它。模块内部会自动处理音频数据的缓存和发送。
2.3.10 pcm_to_mp3(pcm, sampleRate, callback)
功能: 内部函数,将 PCM 音频数据转换为 MP3 格式的 Blob 对象。通常无需手动调用。
参数
:
pcm:Int16Array- PCM 音频数据。sampleRate:number- PCM 数据的采样率。callback:Function- 回调函数。转换完成后,会将 MP3 Blob 对象作为参数传递给此回调函数。
返回值: 无。
注意: 此函数为内部工具函数,用于音频格式转换。
2.3.11 sendAudioToServer(blob)
功能: 内部函数,将音频 Blob 对象发送到服务器进行语音转文字处理。通常无需手动调用。
参数
:
blob:Blob- 音频 Blob 对象。
返回值: 无。
注意: 此函数为内部网络请求函数,用于发送音频数据到服务器。
2.3.12 formatMs(ms)
功能: 格式化毫秒数为
mm:ss格式的字符串,用于显示录音时长。参数:
ms:number- 毫秒数。
返回值:
String- 格式化后的时间字符串 (例如:"01:30").使用示例:
JavaScript
const duration = 90000; // 90秒,即 1 分 30 秒 const formattedDuration = recorder.formatMs(duration); // formattedDuration 将为 "01:30" console.log(formattedDuration);
2.3.13 getFormattedTime()
功能: 获取当前时间,并格式化为
yyyy-MM-dd_HH-mm-ss格式的字符串,用于生成文件名等。参数: 无。
返回值:
String- 格式化后的时间字符串 (例如:"2024-05-03_10-30-45").使用示例:
JavaScript
const currentTimeString = recorder.getFormattedTime(); // 获取当前格式化时间字符串 console.log(currentTimeString);
3. Vue 录音示例代码
<template>
<div class="audio-recorder-demo">
<h1>Vue 录音示例</h1>
<div class="controls">
<button @click="startRecord" :disabled="isRecording">
{{ isRecording ? '录音中...' : '开始录音' }}
</button>
<button @click="stopRecord" :disabled="!isRecording">停止录音</button>
<button @click="downloadRecord" :disabled="!recBlob">本地下载</button>
<button @click="uploadRecord" :disabled="!recBlob">上传录音</button>
</div>
<div class="display-area">
<div class="duration-display">
<label>录音时长:</label>
<span class="recpowert">{{ powerLevelText }}</span>
</div>
<div ref="waveCanvas" class="recwave"></div>
<div class="transcription-result">
<label>实时转文字结果:</label>
<div class="recresultx">{{ transcriptionResult }}</div>
</div>
</div>
</div>
</template>
<script lang="js">
// import RecorderModule from '@elelel13223/web-recorder-module';
import RecorderModule from './utils/index.js';
export default {
components: {},
data() {
return {
recorder: null, // RecorderModule 实例
powerLevelText: '00:00', // 录音时长显示文本
transcriptionResult: '', // 实时转文字结果
recBlob: null, // 录音 Blob 对象
isRecording: false, // 是否正在录音的标志
isPlaying: false, // 是否正在播放的标志
fullTextResult: '',// 新增用于显示完整转写文本的数据属性
};
},
mounted() {
this.initRecorder(); // 初始化录音模块
this.openRecorderOnLoad(); // 组件加载后自动打开录音
},
beforeUnmount() {
this.closeRecorderOnUnmount(); // 组件卸载前自动关闭录音
},
methods: {
initRecorder() {
// 初始化 RecorderModule 实例,配置 API 地址、授权信息和回调函数
this.recorder = new RecorderModule({
API: 'http://127.0.0.1:8080',
AUTHORIZATION: 'token',
SID: '1234',
realTimeTranscription: true, // 是否开启实时转文字功能
processInterval: 3000,
aiTimeout: 10000, // 设置超时时间为 10 秒
onTimeout: () => {
console.log("请求 AI 地址超时,请检查网络或稍后重试");
},
waveConfig: { // 波形可视化配置 (用于 Recorder.WaveView)
speed: 500, // 帧率 (每秒绘制帧数),影响动画流畅度,调整后可能需同步调整 phase 值
/* 渐变色配置 (颜色数组,[位置1, 颜色1, 位置2, 颜色2, ...]) */
linear1: [0, "rgba(10,96,238,1)", 0.2, "rgba(234,79,123,1)", 1, "rgba(123,199,253,1)"], // 线条渐变色1 (从左到右)
linear2: [0, "rgba(209,130,255,0.6)", 1, "rgba(53,199,255,0.6)"], // 线条渐变色2 (从左到右)
linearBg: [0, "rgba(255,255,255,0.2)", 1, "rgba(54,197,252,0.2)"], // 背景渐变色 (从上到下)
},
onPowerLevelUpdate: (durationText) => {
this.powerLevelText = durationText; // 更新录音时长显示
},
onTranscriptionResult: (text) => {
this.transcriptionResult += text + ' '; // 拼接实时转文字结果
},
onRecordStop: (blob, duration, fullTranscriptionText) => {
console.log('录音已停止, Blob:', blob, '时长:', duration);
this.recBlob = blob; // 保存录音 Blob 对象,用于播放和下载
this.isRecording = false; // 更新录音状态
this.fullTextResult = fullTranscriptionText; // 将完整转写文本赋值给 data 中的 fullTextResult
},
onRecordError: (errorMsg) => {
console.error('录音错误:', errorMsg);
this.isRecording = false; // 更新录音状态
alert('录音发生错误: ' + errorMsg); // 弹出错误提示
},
onTranscriptionComplete: (fullText) => {
console.log('转译完成 (onTranscriptionComplete), 完整文本:', fullText);
}
});
},
openRecorderOnLoad() {
// 组件加载时自动打开录音,请求麦克风权限
this.recorder.recOpen(this.$refs.waveCanvas);
},
closeRecorderOnUnmount() {
// 组件卸载时自动关闭录音,释放资源
this.recorder.recClose();
this.isRecording = false;
this.isPlaying = false;
},
startRecord() {
// 开始录音
if (!this.recorder) {
alert("录音模块未初始化,请检查!");
return;
}
this.transcriptionResult = ''; // 开始录音前清空转文字结果
this.powerLevelText = '00:00'; // 开始录音前重置时长显示
this.isRecording = true; // 设置为录音中状态
this.isPlaying = false; // 停止播放状态 (如果正在播放)
this.recorder.recStart(); // 调用 RecorderModule 的 recStart 方法开始录音
},
stopRecord() {
// 停止录音
if (!this.recorder) return;
this.isRecording = false; // 更新录音状态
this.recorder.recStop(); // 调用 RecorderModule 的 recStop 方法停止录音
},
downloadRecord() {
// 本地下载录音
if (!this.recorder) return;
this.recorder.recLocalDown(); // 调用 RecorderModule 的 recLocalDown 方法下载录音
},
uploadRecord() {
// 上传录音
if (!this.recorder) return;
this.recorder.recUpload(); // 调用 RecorderModule 的 recUpload 方法上传录音
}
},
};
</script>
<style scoped>
/* 示例样式保持不变 */
.audio-recorder-demo {
font-family: sans-serif;
padding: 20px;
display: flex;
flex-direction: column;
align-items: flex-start;
}
.controls button {
margin-right: 10px;
padding: 8px 15px;
border: 1px solid #ccc;
border-radius: 5px;
cursor: pointer;
}
.controls button:disabled {
cursor: not-allowed;
opacity: 0.6;
}
.display-area {
margin-top: 20px;
border: 1px solid #eee;
padding: 15px;
border-radius: 5px;
width: 400px;
}
.duration-display,
.transcription-result {
margin-bottom: 10px;
}
.duration-display label,
.transcription-result label {
font-weight: bold;
margin-right: 5px;
}
.recwave {
width: 100%;
height: 100px;
border: 1px solid #ccc;
margin-top: 5px;
}
.recresultx {
border: 1px solid #ddd;
padding: 10px;
min-height: 60px;
margin-top: 5px;
background-color: #f9f9f9;
}
</style>