diff --git a/examples/webpage/app.js b/examples/webpage/app.js index d5a46bb..7d3638c 100644 --- a/examples/webpage/app.js +++ b/examples/webpage/app.js @@ -69,6 +69,9 @@ const state = { audioDeltaLogCount: 0, audioDeltaLogBytes: 0, lastAudioDeltaLogAt: 0, + audioSendLogCount: 0, + audioSendLogBytes: 0, + lastAudioSendLogAt: 0, }; /* ------------------------------------------------------------------ UI */ @@ -201,7 +204,12 @@ function addWsLog(direction, detail, kind = direction) { const dir = document.createElement("span"); dir.className = "ws-log__direction"; - dir.textContent = direction; + dir.textContent = + direction === "send" + ? "SEND" + : direction === "recv" + ? "RECV" + : direction.toUpperCase(); const body = document.createElement("span"); body.className = "ws-log__detail"; @@ -227,8 +235,30 @@ function flushAudioDeltaLog() { state.lastAudioDeltaLogAt = performance.now(); } +function flushAudioSendLog() { + if (state.audioSendLogCount === 0) return; + addWsLog( + "send", + `input.audio binary x${state.audioSendLogCount} (${state.audioSendLogBytes} bytes)`, + ); + state.audioSendLogCount = 0; + state.audioSendLogBytes = 0; + state.lastAudioSendLogAt = performance.now(); +} + +function flushPendingWsLogs() { + flushAudioDeltaLog(); + flushAudioSendLog(); +} + function logWsPayload(direction, payload) { - if (payload?.type === "response.audio.delta") { + if (direction === "send") { + flushAudioSendLog(); + } else { + flushAudioDeltaLog(); + } + + if (direction === "recv" && payload?.type === "response.audio.delta") { state.audioDeltaLogCount += 1; state.audioDeltaLogBytes += payload.bytes || payload.audio?.length || 0; const now = performance.now(); @@ -238,13 +268,50 @@ function logWsPayload(direction, payload) { return; } - flushAudioDeltaLog(); addWsLog(direction, compactWsPayload(payload)); } +function logBinarySend(byteLength) { + state.audioSendLogCount += 1; + state.audioSendLogBytes += byteLength; + const now = performance.now(); + if (now - state.lastAudioSendLogAt >= AUDIO_DELTA_LOG_INTERVAL_MS) { + flushAudioSendLog(); + } +} + +function wsSend(data) { + if (!state.ws || state.ws.readyState !== WebSocket.OPEN) return false; + + if (typeof data === "string") { + try { + logWsPayload("send", JSON.parse(data)); + } catch (_) { + flushAudioSendLog(); + flushAudioDeltaLog(); + addWsLog("send", truncateLogValue(data)); + } + } else { + const byteLength = + data instanceof ArrayBuffer + ? data.byteLength + : ArrayBuffer.isView(data) + ? data.byteLength + : 0; + if (byteLength > 0) { + logBinarySend(byteLength); + } + } + + state.ws.send(data); + return true; +} + function clearWsLog() { state.audioDeltaLogCount = 0; state.audioDeltaLogBytes = 0; + state.audioSendLogCount = 0; + state.audioSendLogBytes = 0; els.wsLog.innerHTML = '
Connect to the engine, enable your mic, and start talking.
-
- Audio is streamed as PCM16 mono @ 16 kHz over
- /ws-product.
+
Connect to the engine, enable your mic, and start talking.
+
+ Audio is streamed as PCM16 mono @ 16 kHz over
+ /ws-product.
+