腾讯云语音识别本地音频转文字 封装node模块
const fs = require("fs");
const path = require("path");
const AsrClient = require("tencentcloud-sdk-nodejs").asr.v20190614.Client;
/**
* 分段上传音频文件并通过腾讯云语音识别服务实现语音转文字
* @param {String} filePath 音频文件的本地路径
* @param {String} secretId 腾讯云 API 密钥的 SecretId
* @param {String} secretKey 腾讯云 API 密钥的 SecretKey
* @param {String} outPath 输出结果的路径 生成的txt srt文件存放处
* @returns {Promise<String>} 返回语音转换后的文本内容
*/
async function convertAudioToText(filePath, secretId, secretKey ,outPath) {
// 1. 实例化 SDK 客户端
const client = new AsrClient({
credential: {
secretId,
secretKey,
},
region: "ap-guangzhou",
profile: {
httpProfile: {
endpoint: "asr.tencentcloudapi.com",
},
},
});
// 2. 读取本地音频文件并转化为 Buffer
const fileSize = fs.statSync(filePath).size;
const maxSegmentSize = 5242880; // 5MB
const buffer = fs.readFileSync(filePath);
// 3. 将音频文件分段上传并获取识别结果
const segmentCount = Math.ceil(fileSize / maxSegmentSize);
let taskIds = []; // 用于保存每个任务的 ID
let results = {}; // 用于保存每个任务的识别结果
for (let i = 0; i < segmentCount; i++) {
const start = i * maxSegmentSize;
const end = (i + 1) * maxSegmentSize;
const segmentBuffer = buffer.slice(start, end); // 将音频文件按照指定大小分段
const params = {
EngineModelType: "16k_zh", // 指定引擎模型
ChannelNum: 1, // 指定声道数
ResTextFormat: 0, // 指定识别结果的格式
SourceType: 1, // 指定音频数据来源
Data: segmentBuffer.toString("base64"), // 将分段后的音频数据转化为 base64 编码格式
};
const response = await client.CreateRecTask(params); // 调用 CreateRecTask 接口创建任务
const taskId = response.Data.TaskId; // 从响应中获取任务 ID
taskIds.push(taskId); // 将任务 ID 存储到 taskIds 数组中
console.log(`Task ${i + 1} created with ID: ${taskId}`);
}
// 4. 轮询任务状态并获取识别结果
const interval = setInterval(async () => {
const completedCount = taskIds.filter(id => results[id]).length; // 计算已完成的任务数量
console.log(`${completedCount}/${segmentCount} tasks completed`);
if (completedCount === segmentCount) {
clearInterval(interval); // 如果所有任务都完成,则停止轮询
results = Object.values(results).reverse();
console.log('results',results.length , results);
const finalResult = results.filter(result => result).join(""); // 将所有任务的识别结果拼接在一起
const finalText = finalResult.replace(/\[\d+:\d+\.\d+,\d+:\d+\.\d+\]\s*/g, ""); // 将所有任务的识别结果拼接在一起
// 将识别结果保存到文件
const resultPath = path.join(outPath, "result.txt");
fs.writeFileSync(path.join(outPath,'resultsrt.txt'), finalResult); // 将识别结果srt保存到文件
fs.writeFileSync(resultPath, finalText);
console.log(`All tasks completed. The result has been saved to ${resultPath}.`);
return finalText;
}
}, 1000);
taskIds.forEach(taskId => {
pollTaskStatus(client, taskId, results); // 遍历所有任务 ID,轮询任务状态并获取识别结果
});
}
// 5. 轮询单个任务的状态并获取识别结果
async function pollTaskStatus(client, taskId, results ) {
const params = {
TaskId: taskId,
};
while (true) {
const response = await client.DescribeTaskStatus(params); // 调用 DescribeTaskStatus 接口查询任务状态
const taskStatus = response.Data.Status; // 获取任务状态
if (taskStatus === 2) { // 如果任务已完成,则获取识别结果
const result = response.Data.Result;
console.log(`Task ${taskId} completed with result length: ${result.length}`);
results[taskId] = result; // 将识别结果存储到 results 数组中
break;
} else if (taskStatus === 3) { // 如果任务失败,则打印错误信息
const errorMessage = response.Data.Message;
console.log(`Task ${taskId} failed with error: ${errorMessage}`);
break;
} else { // 如果任务还在进行中,则继续轮询
console.log(`Task ${taskId} is in progress.`);
await sleep(1000);
}
}
}
// 辅助函数:暂停指定时间
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
module.exports = convertAudioToText;
// 调用 创建 audio-to-text.js 模块
// const convertAudioToText = require("./audio-to-text");
// const filePath = "/path/to/audio/file.mp3";
// const secretId = "your_secret_id";
// const secretKey = "your_secret_key";
// const outPath = "outPath";
// convertAudioToText(filePath, secretId, secretKey ,outPath )
// .then(text => {
// console.log(text);
// })
// .catch(err => {
// console.error(err);
// });
最终生成 txt文件 , 以及字幕srt txt文件 ,
过程 : 选择文件 -> 对大于5mb的音频文件进行分块上传 - > 上传 - > 得到腾讯云返回的 taskId -> 轮询 查询的taskid状态 -> taskids状态为全部完成 - 拼接这些返回的结果
注意 : 因为腾讯云 , 有上传限制 ,一次最大 只能上传 5mb , 所以 ,对于超过5mb的音频文件 , 进行分块上传识别 , 最后拼接这几个分块识别的语音结果 。