Skip to content

Show recording: record the on-air mix to hourly files - #43

Merged
epell-development merged 3 commits into
mainfrom
claude/project-thread-jt1img
Nov 1, 2026
Merged

epell-development merged 3 commits into
mainfrom
claude/project-thread-jt1img

Conversation

@epell-development

Copy link
Copy Markdown
Owner

Requested by epell · project thread

Closes #40

What it does

A show recorder (logger) that saves everything going on air, in the background, as proof of broadcast.

  • Where: Tools → Show recorder (its own window), and Settings → Show recording. The status bar shows ⏺ REC; clicking it opens the window.
  • Files: lined up with the clock, one per hour by default (15 min to 24 h can be chosen). Each day gets a folder: <folder>/2026-11-01/2026-11-01 14-00.mp3. A restart during the hour starts … (2).mp3 instead of overwriting.
  • Folder: local, network (\\server\share) or a cloud-synced folder (OneDrive, Dropbox, Google Drive). If it can't be written (say the network share is offline), that hour goes into the data folder's recordings folder and the window says so.
  • Formats: MP3 at 64–320 kbps (built-in LAME), FLAC (lossless, through ffmpeg) or WAV (uncompressed; files capped at 6 h to stay under 4 GB). The issue asked for "lossless compression for WAV at 64–320 kbps". Lossless and a fixed 64–320 kbps can't go together, so MP3 is the small option and FLAC the lossless one.
  • Storage: keep N days (default 90; 0 keeps everything). Only files RadioMaster named itself, inside its day folders, are deleted. The window estimates the size an hour, a day and for all the days kept.
  • When: days of the week and hours (all day by default), like the advert rules.
  • Progress: the window shows the file being written, a bar across its hour, minutes recorded, size, files finished and any error.

How it works

  • src/recorder.rs: its own thread, fed by an engine.add_tap (same mixed PCM as the stream encoders). No file I/O on the UI thread. WAV headers are corrected every 10 s, so a crash still leaves a playable file.
  • Playout::follow_recording (in tick) starts, stops or restarts the recorder when cfg.recording changes. A change only applies once it has held for 2 s, so typing a folder name doesn't make a file per key press.
  • Server mode: recording is a station setting, so the server records and connected apps edit its settings (cfg_denied: needs the Streaming permission). Live.recording carries the server recorder's status to apps. When the app connects to a server, its local recorder stops ("one station on air at a time"); it starts again after disconnecting.
  • stream::PipeEncoder is now pub(crate) and has finish(), which collects ffmpeg's last FLAC frames when a file closes.

Testing

  • cargo fmt, cargo +1.99.0 clippy --all-targets -- -D warnings, cargo test (5 new recorder tests: clock alignment, segment lengths, file naming and retention, WAV/MP3 writing, FLAC via ffmpeg), tools/extract_strings.py, tools/check_glyphs.py and tools/smoke_server.sh all pass.
  • Ran the app under Xvfb with recording on. It wrote 2026-11-01 10-00.mp3 (about 32 s at 128 kbps) and the file closed properly when the app was stopped.

Merge order

The only clash with #42 is the generated lang/template.json. If #42 merges first, I'll merge main in and regenerate it. No clash with #36.


Generated by Claude Code

…adcast

A new show recorder (Tools → Show recorder, and Settings → Show recording)
saves everything that goes on air in the background. Files are lined up with
the clock (15 minutes to 24 hours each, one hour by default), go into a folder
per day, and can be written to a local, network or cloud-synced folder. If
that folder can't be written, the hour goes into the data folder instead.
Formats: MP3 at 64–320 kbps (built in), FLAC (lossless, through ffmpeg) or
WAV. Recording can be limited to days and hours, and recordings older than N
days are deleted (only files RadioMaster named itself). The window shows the
file being written and how far into it; the status bar shows REC.

On a RadioMaster Server the server records, and connected apps show its
recorder's status. The local recorder stops while connected to a server.

Closes #40

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016m2QHUr78jx6YokVULXvt7
@epell-development epell-development self-assigned this Nov 1, 2026

@mergeguards mergeguards Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MergeGuard review
Risk: 🔴 60/100 — risky
Findings: 🔴 1 high
Open Files changed for 1 inline review thread on the diff.

💡 Use the Fix All MergeGuard Findings checkbox comment on this PR to apply auto-fixes in batch, or reply @mergeguards fix on any inline finding.

⚠️ This PR may benefit from a deep scan — consider triggering @mergeguards deep-scan.


Reviewed by MergeGuard AI

Comment thread src/app.rs Resolved
@mergeguards

mergeguards Bot commented Nov 1, 2026 •

Copy link
Copy Markdown

MergeGuard agent actions

Fix all findings

All issues (1)
  • high · src/recui.rs:12 — Untranslated string literal 'hours' used in format string. The tr() macro is applied to the format string itself, not to the interpolated word.

Apply auto-fixes for the findings above on this branch:

  • Fix All MergeGuard Findings

Or reply with @mergeguards fix-all on this pull request.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016m2QHUr78jx6YokVULXvt7

@mergeguards mergeguards Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ MergeGuard — new commits are on this pull request.

Re-scan the latest diff: paste this line by itself (copy/paste is fine) — either on the Conversation tab (Add a comment) or on Files changed as a comment on the diff:

@mergeguard-followup

@mergeguards mergeguards Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MergeGuard review
Risk: 🔴 60/100 — risky
Findings: 🔴 1 high
Open Files changed for 1 inline review thread on the diff.

💡 Use the Fix All MergeGuard Findings checkbox comment on this PR to apply auto-fixes in batch, or reply @mergeguards fix on any inline finding.

⚠️ This PR may benefit from a deep scan — consider triggering @mergeguards deep-scan.


Reviewed by MergeGuard AI

Comment thread src/playout.rs Resolved
Dropping the recorder only asks its thread to stop; when RadioMaster or the
server quits, the process could end before the file being written was flushed
and closed. Quitting now waits (up to 12 s) for that.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016m2QHUr78jx6YokVULXvt7

@mergeguards mergeguards Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ MergeGuard — new commits are on this pull request.

Re-scan the latest diff: paste this line by itself (copy/paste is fine) — either on the Conversation tab (Add a comment) or on Files changed as a comment on the diff:

@mergeguard-followup

@mergeguards mergeguards Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MergeGuard review
Risk: 🔴 60/100 — risky
Findings: 🔴 1 high
Open Files changed for 1 inline review thread on the diff.

💡 Use the Fix All MergeGuard Findings checkbox comment on this PR to apply auto-fixes in batch, or reply @mergeguards fix on any inline finding.

⚠️ This PR may benefit from a deep scan — consider triggering @mergeguards deep-scan.


Reviewed by MergeGuard AI

Comment thread src/recui.rs Resolved
@epell-development
epell-development merged commit 5924f96 into main Nov 1, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show Recording

2 participants