Expand description
M-RECORD.0 — RecordingSession state machine + shared monotonic
clock for the coordinated recording lifecycle (M-RECORD-EXPORT).
This module is pure Rust — no Tauri types, no I/O. It defines:
SessionState—Idle → Starting → Running → Stopping → Idle. Mirrors the per-channelMicLifecycle/ScreenLifecycleshape so the M-RECORD.2 LED renderer can reuse the same colour map.StreamKind— which of the four input streams (camera, screen, microphone, system audio) aStreamHealthrefers to.StreamHealth— per-stream health snapshot (lifecycle + cumulative frame count + last-frame timestamp). Built fresh by M-RECORD.1’srecording_statusIPC every 500 ms.SessionStreams— which streams the user enabled for this session (boolean flags). Doesn’t own the actual pipelines — those stay in their existing Tauri-managedState<>handles; the session just coordinates their lifecycles.RecordingSession— the orchestrator type itself. Wraps the four state pieces above into one immutable-once-started struct with a sharedstarted_at: Instantclock used by the M-EXPORT encoder to compute per-frame PTS.
M-RECORD.0 lands the **types + state machine** only. The Tauri
`start_recording` / `stop_recording` / `recording_status` IPC and
the 500 ms event-push task that consumes this state live in
M-RECORD.1. Splitting the chunks keeps the state machine
unit-testable without Tauri's `AppHandle`.Structs§
- Encoder
Handle - Live encoder + its background feed-thread cancel flag. Owned by
RecordingState::encoderfor the duration of a session. - Pending
Export - A finished recording sitting in the scratch directory, awaiting
the user’s format choice in the Save panel (M-SAVE.1). Held in
RecordingState::pending_exportbetweenstop_recordingandexport_recording/discard_recording. Pure Rust — no Tauri / serde; the IPC-facing mirror isPendingExportView. - Pending
Export View - IPC mirror of
PendingExport. Carries only what the Save panel needs — never the internal scratch path. - Recording
Config start_recordingargument. Carries which streams to enable + the per-channel picker selections + the output target. M-EXPORT.4 extendsoutput_path/formatsemantics; here they’re carried through unchanged so the IPC seam doesn’t need to break later.- Recording
Session - One coordinated recording session — the orchestrator owned by
RecordingState(M-RECORD.1) for the lifetime of one start → stop cycle. - Recording
State - Tauri-managed wrapper around the optional active session. Held
in
tauri::Stateso thestart_recording/stop_recording/recording_statusIPC commands + the 500 ms event-push task share one source of truth. Mirror ofMicCaptureState/ScreenCaptureState. - Recording
Status View - Snapshot of the active session for the
recording_statusIPC - Recording
Summary - Result of a successful
stop_recording. Distinct fromRecordingStatusViewbecause it’s a final summary (no live state) — fields the UI uses to show the post-record toast + “Reveal in Finder” button (M-EXPORT.4). - Session
Streams - Which streams the user enabled at session-start time. Doesn’t
own the actual pipeline handles — those stay in their existing
Tauri-managed
State<>wrappers; the session just remembers which channels to start + stop together. - Stream
Health - Per-stream health snapshot for the
recording-statusevent push. Built fresh every 500 ms by M-RECORD.1.
Enums§
- Session
State - Master state of a
RecordingSession. Mirrors the per-channelMicLifecycle/ScreenLifecycleshape (and renders with the same LED colour map in M-RECORD.2). - Stream
Kind - Which of the four input streams a
StreamHealthdescribes. Sent across the IPC seam so the Leptos<RecorderControls />can colour the right LED.
Constants§
- DEFAULT_
AUDIO_ 🔒CHANNELS - Default audio mixer channel count (stereo). Matches the
EncoderConfigdefault + the SCK / mic worker output formats.
Statics§
- NEXT_
SESSION_ 🔒ID - Monotonically-increasing session id. Resets per process start;
the id only needs to be unique within a single app run so the
recording-statusevent consumer can ignore stale events from a previous session.
Functions§
- cfr_
catchup_ 🔒frames - How many video frames a constant-frame-rate stream should have emitted
by
elapsed(atframe_interval), minus those alreadypushed— i.e. the number to push this tick to keep the encoder’s frame count locked to wall-clock. The live encoder timestamps frames by count at a fixed rate, so a compose pump that can’t sustain that rate must duplicate the last frame to fill the deficit, or the recording plays fast. Bounded bymax_burstso a long stall can’t emit an unbounded catch-up burst. - feed_
real_ 🔒capture - Real-capture feed loop (M-PIX.6) — pulls composed frames from
crate::recording_compose::RecordingCompose+ mixed audio from the sharedSharedAudioMixeruntil cancel fires. - feed_
test_ 🔒pattern - Test-pattern feed loop running on a dedicated thread. Pushes a solid colour BGRA frame at the encoder’s framerate (and a chunk of silence at the audio sample rate) until cancel fires.
- new_
audio_ mixer - Construct a fresh shared mixer with the default channel count.
- new_
frame_ slot - Construct a fresh frame slot —
Arc<Mutex<None>>.
Type Aliases§
- Frame
Slot - Latest-frame-wins slot the capture pipelines write into and the
encoder feed thread reads from (M-PIX.0).
Noneuntil the first frame; the capture pipeline overwrites with each new frame; the encoder reads (cloned) at render time. - Shared
Audio Mixer - Shared audio mixer (M-PIX.0) the mic worker + SCK audio
delegate push samples into, and the encoder feed thread drains
via
AudioMixer::pull().