How Meetily's Incremental Audio Saver with Checkpoints Prevents Data Loss

The incremental audio saver with checkpoints in Meetily writes temporary MP4 files every 30 seconds during recording, ensuring that even if the app crashes, partial audio data can be recovered and merged into a complete file.

The Meetily desktop application handles long-duration meeting recordings through a Rust-based incremental audio saver with checkpoints that mitigates data loss risks. This component splits continuous audio streams into discrete checkpoint segments stored in a hidden directory, then concatenates them upon completion. According to the Meetily source code in Zackriya-Solutions/meetily, this architecture maintains low memory usage while providing fault tolerance for recordings that might span hours.

Core Architecture

The system relies on four distinct layers working together to manage audio buffering, checkpoint serialization, and final file assembly.

IncrementalAudioSaver (incremental_saver.rs)

Located in frontend/src-tauri/src/audio/incremental_saver.rs, this struct holds the checkpoint_buffer of incoming audio samples and calculates the checkpoint_interval_samples threshold. When the buffer reaches 1,440,000 samples (30 seconds at 48 kHz), it triggers save_checkpoint() to encode the buffer as an individual .mp4 file in the .checkpoints/ folder.

RecordingSaver (recording_saver.rs)

The RecordingSaver in frontend/src-tauri/src/audio/recording_saver.rs owns an optional Arc<AsyncMutex<IncrementalAudioSaver>> named incremental_saver. It instantiates the saver when auto_save is enabled via IncrementalAudioSaver::new and forwards each audio chunk through incremental_saver.save_chunk.

RecordingManager (recording_manager.rs)

The RecordingManager in frontend/src-tauri/src/audio/recording_manager.rs controls the recording lifecycle and sets the auto_save flag that determines whether checkpointing should occur. It triggers finalization through finalize_recording when the user stops the session.

Tauri Command Layer (lib.rs)

Three Tauri commands exposed in frontend/src-tauri/src/lib.rs connect the backend to the frontend:

  • has_audio_checkpoints – verifies checkpoint file existence
  • recover_audio_from_checkpoints – merges existing checkpoints after crashes
  • cleanup_checkpoints – removes the temporary directory post-merge

Checkpoint Lifecycle

The incremental audio saver with checkpoints follows a strict six-phase lifecycle to ensure data integrity.

1. Initialization

When a meeting begins, the saver creates a hidden .checkpoints/ subdirectory inside the meeting folder using meeting_folder.join(".checkpoints").

2. Chunk Accumulation

Audio chunks append to checkpoint_buffer as floating-point PCM samples. The system tracks total_samples continuously during the recording session.

3. Checkpoint Trigger

When total_samples >= checkpoint_interval_samples (1,440,000 samples), the saver automatically invokes save_checkpoint().

4. Saving Individual Checkpoints

The save_checkpoint() method encodes the buffer to MP4 using FFmpeg and writes it to audio_chunk_{:03}.mp4, where the three-digit number represents the current checkpoint_count. The count increments after each successful write.

5. Finalization

Upon stopping, any remaining buffer data saves as a final checkpoint. The system generates an FFmpeg concat list (concat_list.txt) and merges all chunks into audio.mp4 in the meeting root.

6. Cleanup

After successful concatenation, cleanup_checkpoints removes the .checkpoints/ directory to reclaim disk space.

Implementation Details

Buffer Management and Memory Efficiency

The checkpoint_buffer uses a Vec of f32 samples that resets after each checkpoint write. This design ensures memory usage remains constant regardless of recording duration, as the buffer never holds more than 30 seconds of audio data at once.

FFmpeg Integration

Each checkpoint undergoes encoding through FFmpeg directly from the raw sample buffer. The final concatenation uses FFmpeg's concat demuxer with a generated list file rather than re-encoding, preserving audio quality and improving performance.

Code Examples

Starting a Recording with Checkpoints

// Start a meeting with audio checkpointing enabled
let mut saver = RecordingSaver::new(base_folder)?;
saver.start_meeting("Team Standup", true)?; // `true` enables checkpoints

// Feed audio chunks (f32 PCM) to the saver
saver.save_audio_chunk(AudioData { samples: my_samples })?;
// The saver automatically writes a checkpoint every 30 seconds

// Stop the meeting – merges checkpoints and cleans up
saver.stop_meeting()?; // Produces `audio.mp4` in the meeting folder

Recovering from Crashes via Frontend

// React frontend invoking Tauri recovery command
await invoke('recover_audio_from_checkpoints', {
  meetingFolder: '/path/to/Meetily/Meetings/Team Standup'
});

Internal Checkpoint Logic

// Inside `incremental_saver.rs` – checkpoint saving logic
fn save_checkpoint(&mut self) -> Result<()> {
    if self.checkpoint_buffer.is_empty() {
        warn!("Attempted to save empty checkpoint, skipping");
        return Ok(());
    }
    let checkpoint_path = self.checkpoints_dir
        .join(format!("audio_chunk_{:03}.mp4", self.checkpoint_count));
    // Encode `self.checkpoint_buffer` → MP4 using FFmpeg
    // ...
    self.checkpoint_count += 1;
    info!("Saved checkpoint {}: {:.2}s of audio", self.checkpoint_count, /* ... */);
    Ok(())
}

Error Recovery and Crash Resilience

The incremental audio saver with checkpoints provides robust recovery mechanisms for interrupted sessions. If the Meetily application crashes or the system loses power, the .checkpoints/ directory retains all successfully written segments. The recover_audio_from_checkpoints Tauri command inspects this directory, validates the sequence of audio_chunk_*.mp4 files, and executes the same FFmpeg concatenation process normally performed during clean shutdown. This ensures users lose at most 30 seconds of recording time—the interval between the last checkpoint and the crash event.

Summary

  • Incremental Audio Saver: A Rust component in incremental_saver.rs that buffers audio and writes MP4 checkpoints every 30 seconds
  • File Locations: Checkpoints stored in hidden .checkpoints/ directories as audio_chunk_{:03}.mp4
  • Trigger Threshold: 1,440,000 samples (30 seconds at 48 kHz) triggers automatic checkpoint creation
  • Recovery: The recover_audio_from_checkpoints command enables restoration of partial recordings after crashes
  • Cleanup: Automatic removal of temporary checkpoint files after successful concatenation into final audio.mp4

Frequently Asked Questions

What happens if the app crashes during a recording?

If Meetily crashes, the incremental audio saver with checkpoints preserves all completed checkpoint files in the .checkpoints/ folder. When the app restarts, you can invoke recover_audio_from_checkpoints to merge these segments into a complete audio file, losing only the audio recorded since the last 30-second checkpoint.

How much audio data is lost if the recording stops unexpectedly?

At maximum, you lose 30 seconds of audio—the duration between the last successful checkpoint and the interruption. The checkpoint_interval_samples calculation (1,440,000 samples at 48 kHz) enforces this 30-second window regardless of recording length.

Why does the system use MP4 format for checkpoints?

The saver encodes raw PCM buffers to MP4 using FFmpeg because MP4 provides efficient compression while maintaining compatibility with the final concatenation process. Using a standard container format simplifies the merge operation through FFmpeg's concat demuxer without requiring format conversion during finalization.

Where are the checkpoint files stored during recording?

Checkpoint files reside in a hidden .checkpoints/ subdirectory within the specific meeting folder. For example, a meeting named "Team Standup" stores temporary chunks at Meetings/Team Standup/.checkpoints/audio_chunk_001.mp4. This folder is automatically deleted after successful merging to free disk space.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →