Meeting recorder: fix the level meter in a background tab, show live sources - #341
Merged
Conversation
added 2 commits
September 9, 2026 14:56
…sources The meter ran on requestAnimationFrame, which browsers suspend in a background tab. Sharing a meeting tab is exactly the case that puts the recorder page in the background, so the meter froze and the "no sound has reached the recorder" note appeared while audio was recording correctly. A 100 ms interval keeps sampling. Alongside that, the panel now says what it is capturing rather than leaving it to be discovered afterwards: a live "Meeting audio: on / Microphone: off" line while recording, the microphone hint spelling out that it belongs on whenever the user or anyone in the room will speak, and a plain line at start when the microphone is off. The silence note no longer implies the recording has stopped. Claude-Session: https://claude.ai/code/session_01SXuk2GeBZTwo9wP3D2VEQF
A ninety-minute recording failed at minute 60 with "fetch failed" while the transcription endpoint had answered every request with 200 OK. Node's fetch has no public knob for undici's 300 s headers timeout, and a ten-minute slice on CPU sits right on that boundary: the slice that broke it took 306 seconds. Three changes, none of which add a dependency. - Slices default to four minutes rather than ten, which finishes well inside the limit with room for the machine to be busy. - A failed slice retries three times with backoff, so a transient hiccup costs seconds rather than the whole run. - Each finished slice is cached beside the audio, so a re-run resumes instead of paying again for minutes already transcribed. The first failure discarded sixty minutes of completed work. Claude-Session: https://claude.ai/code/session_01SXuk2GeBZTwo9wP3D2VEQF
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
The level meter ran on
requestAnimationFrame. Browsers suspend animation frames in a background tab, and sharing a meeting tab is precisely the case that puts the recorder page in the background. So the meter froze and the "No sound has reached the recorder yet" note appeared and stayed, whileMediaRecorderwent on capturing correctly the whole time.Found after a real 90-minute recording: the file was clean (mean volume -23.7 dB, continuous across all seven sample points, intelligible on spot transcription), but the page had said otherwise while it ran.
The sampler now runs on a 100 ms interval, which keeps firing in a background tab, and is cleared in
cleanup().Alongside it
The panel now states what it is capturing rather than leaving it to be discovered from the session metadata afterwards.
Meeting audio: on · Microphone: offline while recording, with the microphone half marked in--crow-warningwhen it is off.Verified
Panel rendered through
renderLayout: all new elements present, norequestAnimationFramein the shipped script,--crow-warningconfirmed as a real token rather than an invented one. Audited all 26 script element references against the markup, no orphans — which caught one element the script referenced before the markup carried it.a11y-baselineanddashboard-no-theme-statepass, 12/12.https://claude.ai/code/session_01SXuk2GeBZTwo9wP3D2VEQF