Files
sgxt_web/public/textVideo/textVideo.js

276 lines
7.7 KiB
JavaScript
Raw Normal View History

2025-07-16 18:34:49 +08:00
/**
* Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
* Reserved. MIT License (https://opensource.org/licenses/MIT)
*/
/* 2022-2023 by zhaoming,mali aihealthx.com */
// 连接; 定义socket连接类对象与语音对象
var wsconnecter = new WebSocketConnectMethod({ msgHandle: getJsonMessage, stateHandle: getConnState });
var audioBlob;
var isfilemode = true; // if it is in file mode
// 录音; 定义录音对象,wav格式
var rec = Recorder({
type: "pcm",
bitRate: 16,
sampleRate: 16000,
onProcess: recProcess
});
var sampleBuf = new Int16Array();
var rec_text = ""; // for online rec asr result
var offline_text = ""; // for offline rec asr result
var file_ext = "";
var file_sample_rate = 16000; //for wav file sample rate
var file_data_array; // array to save file data
var totalsend = 0;
addresschange();
function addresschange() {
var Uri = 'ws://192.168.0.232:10095';
Uri = Uri.replace(/wss/g, "https");
window.open(Uri, '_blank');
}
var readWavInfo = function (bytes) {
//读取wav文件头统一成44字节的头
if (bytes.byteLength < 44) {
return null;
};
var wavView = bytes;
var eq = function (p, s) {
for (var i = 0; i < s.length; i++) {
if (wavView[p + i] != s.charCodeAt(i)) {
return false;
};
};
return true;
};
if (eq(0, "RIFF") && eq(8, "WAVEfmt ")) {
var numCh = wavView[22];
if (wavView[20] == 1 && (numCh == 1 || numCh == 2)) {//raw pcm 单或双声道
var sampleRate = wavView[24] + (wavView[25] << 8) + (wavView[26] << 16) + (wavView[27] << 24);
var bitRate = wavView[34] + (wavView[35] << 8);
var heads = [wavView.subarray(0, 12)], headSize = 12;//head只保留必要的块
//搜索data块的位置
var dataPos = 0; // 44 或有更多块
for (var i = 12, iL = wavView.length - 8; i < iL;) {
if (wavView[i] == 100 && wavView[i + 1] == 97 && wavView[i + 2] == 116 && wavView[i + 3] == 97) {//eq(i,"data")
heads.push(wavView.subarray(i, i + 8));
headSize += 8;
dataPos = i + 8; break;
}
var i0 = i;
i += 4;
i += 4 + wavView[i] + (wavView[i + 1] << 8) + (wavView[i + 2] << 16) + (wavView[i + 3] << 24);
if (i0 == 12) {//fmt
heads.push(wavView.subarray(i0, i));
headSize += i - i0;
}
}
if (dataPos) {
var wavHead = new Uint8Array(headSize);
for (var i = 0, n = 0; i < heads.length; i++) {
wavHead.set(heads[i], n); n += heads[i].length;
}
return {
sampleRate: sampleRate
, bitRate: bitRate
, numChannels: numCh
, wavHead44: wavHead
, dataPos: dataPos
};
};
};
};
return null;
};
function upfileOnchange(files) {
this.files = [files];
var len = this.files.length;
for (let i = 0; i < len; i++) {
let fileAudio = new FileReader();
fileAudio.readAsArrayBuffer(this.files[i]);
file_ext = this.files[i].name.split('.').pop().toLowerCase();
var audioblob;
fileAudio.onload = function () {
audioblob = fileAudio.result;
file_data_array = audioblob;
}
fileAudio.onerror = function (e) {
console.log('error' + e);
}
}
// for wav file, we get the sample rate
if (file_ext == "wav") {
for (let i = 0; i < len; i++) {
let fileAudio = new FileReader();
fileAudio.readAsArrayBuffer(this.files[i]);
fileAudio.onload = function () {
audioblob = new Uint8Array(fileAudio.result);
var info = readWavInfo(audioblob);
file_sample_rate = info.sampleRate;
}
}
}
}
function play_file() {
var audioblob = new Blob([new Uint8Array(file_data_array)], { type: "audio/wav" });
var audio_record = document.getElementById('audio_record');
audio_record.src = (window.URL || webkitURL).createObjectURL(audioblob);
audio_record.controls = true;
}
function start_file_send() {
sampleBuf = new Uint8Array(file_data_array);
var chunk_size = 960; // for asr chunk_size [5, 10, 5]
while (sampleBuf.length >= chunk_size) {
sendBuf = sampleBuf.slice(0, chunk_size);
totalsend = totalsend + sampleBuf.length;
sampleBuf = sampleBuf.slice(chunk_size, sampleBuf.length);
wsconnecter.wsSend(sendBuf);
}
stop();
}
function stop() {
var chunk_size = new Array(5, 10, 5);
var request = {
"chunk_size": chunk_size,
"wav_name": "h5",
"is_speaking": false,
"chunk_interval": 10,
"mode": getAsrMode(),
};
if (sampleBuf.length > 0) {
wsconnecter.wsSend(sampleBuf);
sampleBuf = new Int16Array();
}
wsconnecter.wsSend(JSON.stringify(request));
// 控件状态更新
isRec = false;
if (isfilemode == false) {
//wait 3s for asr result
setTimeout(function () {
wsconnecter.wsStop();
}, 3000);
rec.stop(function (blob, duration) {
var audioBlob = Recorder.pcm2wav(data = { sampleRate: 16000, bitRate: 16, blob: blob },
function (theblob, duration) {
console.log(theblob);
var audio_record = document.getElementById('audio_record');
audio_record.src = (window.URL || webkitURL).createObjectURL(theblob);
audio_record.controls = true;
}, function (msg) {
console.log(msg);
}
);
}, function (errMsg) {
console.log("errMsg: " + errMsg);
});
}
// 停止连接
}
function getAsrMode() {
return 'offline';
}
function getHotwords() {
return null
}
function handleWithTimestamp(tmptext, tmptime) {
if (tmptime == null || tmptime == "undefined" || tmptext.length <= 0) {
return tmptext;
}
tmptext = tmptext.replace(/。|||、|\?|\.|\ /g, ","); // in case there are a lot of "。"
var words = tmptext.split(","); // split to chinese sentence or english words
var jsontime = JSON.parse(tmptime); //JSON.parse(tmptime.replace(/\]\]\[\[/g, "],[")); // in case there are a lot segments by VAD
var char_index = 0; // index for timestamp
var text_withtime = "";
for (var i = 0; i < words.length; i++) {
if (words[i] == "undefined" || words[i].length <= 0) {
continue;
}
if (/^[a-zA-Z]+$/.test(words[i])) { // if it is english
text_withtime = text_withtime + jsontime[char_index][0] / 1000 + ":" + words[i] + "\n";
char_index = char_index + 1; //for english, timestamp unit is about a word
}
else {
text_withtime = text_withtime + jsontime[char_index][0] / 1000 + ":" + words[i] + "\n";
char_index = char_index + words[i].length; //for chinese, timestamp unit is about a char
}
}
return text_withtime;
}
// 语音识别结果; 对jsonMsg数据解析,将识别结果附加到编辑框中
function getJsonMessage(jsonMsg) {
var rectxt = "" + JSON.parse(jsonMsg.data)['text'];
var asrmodel = JSON.parse(jsonMsg.data)['mode'];
var is_final = JSON.parse(jsonMsg.data)['is_final'];
var timestamp = JSON.parse(jsonMsg.data)['timestamp'];
if (asrmodel == "2pass-offline" || asrmodel == "offline") {
offline_text = offline_text + handleWithTimestamp(rectxt, timestamp); //rectxt; //.replace(/ +/g,"");
rec_text = offline_text;
} else {
rec_text = rec_text + rectxt;
}
videoText = rec_text;
if (is_final == true) {
play_file();
wsconnecter.wsStop();
btnConnect.disabled = false;
}
}
// 连接状态响应
function getConnState(connState) {
if (connState === 0) start_file_send();
}
// 识别启动、停止、清空操作
function start() {
var ret = wsconnecter.wsStart();//启动连接
return ret == 1 ? 1 : 0;
}
function recProcess(buffer, powerLevel, bufferDuration, bufferSampleRate, newBufferIdx, asyncEnd) {
if (isRec === true) {
var data_48k = buffer[buffer.length - 1];
var array_48k = new Array(data_48k);
var data_16k = Recorder.SampleData(array_48k, bufferSampleRate, 16000).data;
sampleBuf = Int16Array.from([...sampleBuf, ...data_16k]);
var chunk_size = 960; // for asr chunk_size [5, 10, 5]
while (sampleBuf.length >= chunk_size) {
sendBuf = sampleBuf.slice(0, chunk_size);
sampleBuf = sampleBuf.slice(chunk_size, sampleBuf.length);
wsconnecter.wsSend(sendBuf);
}
}
}
function getUseITN() {
return false;
}