Commit

ca7791e

Bun it is: bun:sqlite, Bun.serve WebSockets, a Dockerfile with one data volume for Dokploy. Next: frontend. Default is React via Bun's HTML imports, served by the same process (no separate build server). OK?
Ok as long as we can deploy new server version robustly. Existing connection can cut, but can recover with no data loss. I also have a Sockudo instance, maybe viewers can get notified of changes through it instead? What do you think?
Good idea. Viewers stay connected while our server redeploys, and fan-out is off our process. Plan: viewer loads a snapshot over HTTP, then applies Sockudo events carrying a sequence number; on a gap or reconnect it refetches. Sender still talks WS to us directly. Sound right?
Next: should the sender's local buffer survive a tab reload or browser crash? Default: write chunks to IndexedDB, so a reopened sender page resumes uploading what the server hasn't acked, and old acked chunks get pruned.
Yes, but it is possible that we will be streaming for the whole day. So just make sure we don't run into problems with the storage space on the browser
Raw PCM is ~115 MB/hour, so a day would be over 1 GB. But acked chunks are deleted right away, so the browser only holds the unsent backlog. The sender shows the backlog size and warns as it nears the browser's quota.
Next: the transcript. Default: a list of segments, each tied to an audio time range, so any segment can be re-transcribed or LLM-cleaned later and replayed as audio. Should admins also be able to hand-edit text live?
Yes, it should also provide a simple REST-based API so that the admin can hand it over to the AI agent to edit. Let's aim for an append-only architecture so that we can recover from bad edits. To reclaim the storage space on the server, we can delete the room as a whole after…
Timestamps: qwen3-asr-flash-realtime gives none on transcripts, but its server VAD emits speech_started/stopped with audio_start_ms/audio_end_ms, so we get segment-level times. qwen-audio-3.1-asr-flash-streaming has word-level begin/end times. Both take opus input.
Clock sync idea: ignore the client wall clock. A stream gets a random id; chunk n is at stream offset n*100ms. While connected, client pings with its elapsed time since stream start (monotonic); server estimates stream start in server time from the lowest-RTT ping. Good?
Last one before I write the spec: the public viewer. Default is a live scrolling transcript (partial text shown dimmed), auto-scroll with pause on scroll-up, a fullscreen caption mode for projectors, and a text export. Anything to add or drop?
The public viewer should also contain a section on how to connect the AI agent so that it can read the transcript efficiently. Regarding Opus, I wonder if the client should be the one encoding Opus packets, or should it be that the client is sending raw PCM stream and the server…
Agent section in the viewer: noted. Opus: I'd encode on the client with WebCodecs AudioEncoder. That shrinks both the IndexedDB backlog and upload on venue wifi by ~10x, which is where robustness matters most. Raw PCM stays as a fallback if the browser lacks it. Server stores…
Ok good. By the way, in contrast to Matt Pocock's skills, I will not be using multiple separate sessions to implement stuff. But I will use this long-running session for most of the work, but you should feel free to delegate to sub-agents to work autonomously.
Got it, saved that to memory. Writing the spec issue next. Test seams I'd propose: 1. Server as a whole: start it in-process, drive its HTTP + WS API, with a fake ASR provider and a fake Sockudo publisher. 2. Sender's buffer/uploader: a fake socket that drops and reconnects. OK?
Ok. By the way, is it clear enough to implement? Or do you need any further grilling? The artifact that I kind of expect is the code on the branch with a Dockerfile, so I can make Dokploy build it. The Docker file should also contain the EXPOSE directive, which tells me which port I should forward to the container, as well as VOLUME, so I know which container dir needs persistence. I also expect frequent progress updates with screenshots and stuff. You can push your work directly to the v2 branch.

commit ca7791e

Clear enough to build. Spec: https://github.com/dtinth/live-speech/issues/2 (one open risk: catch-up pacing after an outage; I'll measure it). Starting now: Dockerfile with EXPOSE + VOLUME, pushed to v2, updates with screenshots as I go. To test for real I'll need a DashScope…
GitHubv2: live captioning rewrite spec · Issue #2 · dtinth/live-speechProblem Statement Live captions at local tech talks in Thailand have to cope with Thai speech full of English technical terms. The 2024 version of live-speech handled this by chaining a fast stream...