Commit 9a6ef089 authored by martin hou's avatar martin hou

fix: 增加live对接测试

parent 34e1e94a
......@@ -29,6 +29,7 @@ export function Home() {
const [rmsRight, setRmsRight] = useState<number>(0);
const [liveDelay, setLiveDelay] = useState<number>(100);
const liveTimeoutRef = useRef<number | null>(null);
const sendTimeoutRef = useRef<number | null>(null);
const liveIntervalRef = useRef<number>(liveDelay);
useEffect(() => { liveIntervalRef.current = liveDelay; }, [liveDelay]);
......@@ -494,7 +495,7 @@ export function Home() {
const outFrames = Math.floor((totalFrames + downFactor - 1) / downFactor) * 2; // 向上取整
let sumL = 0;
let sumR = 0;
const mono8 = new Uint8Array(outFrames);
const mono8 = new Uint8Array(outFrames + 8);
let j = 0, k = 0;
for (let i = 8; i + 3 < u8.length; i += 4, j++)
{
......@@ -521,8 +522,8 @@ export function Home() {
else if (m < -32768) m = -32768;
let H = (m >> 8) & 0xff;
let L = m & 0xff;
mono8[k++] = (L << 8);
mono8[k++] = H;
mono8[8 + k++] = (L << 8);
mono8[8 + k++] = H;
}
}
const leftRms = Math.sqrt(sumL / totalFrames);
......@@ -548,20 +549,134 @@ export function Home() {
setRmsLeft(Math.floor(rms1 * 4 * 400));
setRmsRight(Math.floor(rms2 * 4 * 400));
console.log('live', 'rest: ' + live?.rest);
// 根据live.rest的值决定timeout的间隔时长,如果>1则为50,否则为100
let timeout = live.rest > 1 ? 50 : 100;
liveTimeoutRef.current = window.setTimeout(scheduleLiveTick, Math.max(0, timeout | 0));
}
const startLive = async () => {
let jensen = getJensen();
const startSession = async () => {
const jensen = getJensen();
if (jensen == null) return;
let rst = await jensen.startRealtime(2, 1);
Logger.info('jensen', 'live', 'Start Live: ' + JSON.stringify(rst));
if (liveTimeoutRef.current !== null) {
window.clearTimeout(liveTimeoutRef.current);
}
// 立即触发一次,并在回调末尾调度下一次
liveTimeoutRef.current = window.setTimeout(scheduleLiveTick, 100);
// 开启发送音频定时器
if (sendTimeoutRef.current !== null) {
window.clearTimeout(sendTimeoutRef.current);
}
sendTimeoutRef.current = window.setTimeout(sendLiveAudio, 100);
}
function stringToUuidBytes(str: string): Uint8Array {
const encoder = new TextEncoder();
const data = encoder.encode(str);
const hash = new Uint8Array(16);
// 如果数据长度小于16,用0填充;如果大于16,截断
for (let i = 0; i < 16; i++) {
hash[i] = i < data.length ? data[i] : 0;
}
return hash;
}
const sendLiveAudio = async () => {
if (blocksRef.current.length == 0) return sendTimeoutRef.current = window.setTimeout(sendLiveAudio, 10);
console.log('live', 'send audio, rest: ', blocksRef.current.length);
const audio = blocksRef.current.shift();
if (audio == null) return console.log('live', 'skip cuz audio is null');
if (audio.length == 0) return console.log('live', 'skip cuz audio is empty');
let time = new Date().getTime();
const timeBytes = u64ToBytesLE(time);
audio.set(timeBytes, 0);
wsRef.current?.send(audio.buffer);
sendTimeoutRef.current = window.setTimeout(sendLiveAudio, 10);
}
function u64ToBytesLE(n: number): Uint8Array {
// 确保是 BigInt
let bn = BigInt(n);
const mask = BigInt(0xff);
const shift = BigInt(8);
const bytes = new Uint8Array(8);
for (let i = 0; i < 8; i++) {
bytes[i] = Number(bn & mask);
bn = bn >> shift;
}
for (let i = 0; i < 4; i++) {
let tmp = bytes[i];
bytes[i] = bytes[7 - i];
bytes[7 - i] = tmp;
}
return bytes;
}
// 创建一个websocket实例
const wsRef = useRef<WebSocket | null>(null);
const startLiveSession = async () => {
const token = 'kL5NmbPEGOptIGbt8jtR3pjXVHT9p774n7N4oQAARb0ctUMnq4bABgBPZ7QjYSUi';
let url = 'wss://live.test.hidock.com/ws/realtime?accesstoken=' + token + '&mode=room&language=cmn&';
// wss://live.test.hidock.com/ws/realtime?accesstoken=&mode=room&language=cmn
wsRef.current = new WebSocket(url);
wsRef.current.onopen = () => {
console.log('websocket connected');
const config = {
"type": "config",
"sequence": String(new Date().getTime()),
"body": {
"language": "cmn",
"enable_speaker_diarization": true,
"translation": {
"type": "one_way",
"language": "cmn",
"target_language": "eng"
},
"language_hints": ["cmn"],
"create_note": false
}
};
wsRef.current?.send(JSON.stringify(config));
}
wsRef.current.onmessage = (event) => {
// console.log('websocket message', event.data);
// {"code":0,"message":"","sequence":"1764835254003","data":{"type":"config","type":"config","session_id":"91e0c9710467faaa57c21eb8b8c73a61","status":"created"}}
let msg = JSON.parse(event.data);
if (msg.code != 0) return console.error('websocket message error', msg);
let data = msg.data;
if (data.type == 'config' && data.status == 'created')
{
console.log('websocket session created', data);
startSession();
}
if (data.type == 'partial')
{
console.log('live', data.text);
}
if (data.type == 'final')
{
console.log('live', data.text);
}
}
wsRef.current.onerror = (event) => {
console.log('websocket error', event);
}
wsRef.current.onclose = () => {
console.log('websocket closed');
}
}
const startLive = async () => {
let jensen = getJensen();
if (jensen == null) return;
startLiveSession();
}
const stopLive = async () => {
......@@ -574,8 +689,7 @@ export function Home() {
liveTimeoutRef.current = null;
}
console.log('live stopped');
// 将blocksRef.current合并为单一Uint8Array
/*
const totalSamples = blocksRef.current.reduce((sum, arr) => sum + arr.length, 0);
const monoAll = new Uint8Array(totalSamples);
let offsetMono = 0;
......@@ -590,6 +704,7 @@ export function Home() {
a.download = 'live.pcm';
a.click();
URL.revokeObjectURL(url);
*/
}
return (
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment