How Meetily's Retranscription Module Reprocesses Meeting Audio
Meetily's retranscription module uses a Rust-based Tauri backend to reprocess recorded meeting audio through Whisper, employing a global atomic flag for concurrency control, chunked 30-second audio processing, and metadata tracking to update transcription results without re-recording.
Meetily (from Zackriya-Solutions/meetily) provides a powerful retranscription feature that allows users to re-run Whisper transcription on previously recorded meetings. This functionality, implemented entirely in the Rust Tauri backend, enables users to experiment with different languages, models, or providers while maintaining data integrity through atomic state management and persistent metadata updates.
Command Registration and Public API
The retranscription feature exposes three Tauri commands in frontend/src-tauri/src/lib.rs (lines 742-744):
start_retranscription_command– Launches a background retranscription task with configurable parameterscancel_retranscription_command– Stops an in-progress job and releases the atomic lockis_retranscription_in_progress_command– Reports the current processing state to prevent duplicate invocations
These commands form the public API that the TypeScript frontend invokes to manage the retranscription lifecycle.
Core Retranscription Logic
The heavy lifting occurs in frontend/src-tauri/src/audio/retranscription.rs, which orchestrates audio decoding, Whisper inference, and result aggregation.
Concurrency Control with Atomic Flags
To prevent race conditions, the module uses a global atomic flag named RETRANSLATION_IN_PROGRESS (lines 19-26):
use std::sync::atomic::{AtomicBool, Ordering};
static RETRANSLATION_IN_PROGRESS: AtomicBool = AtomicBool::new(false);
When start_retranscription (lines 89-105) receives a request, it attempts to swap the flag to true using Ordering::SeqCst. If the flag is already set, the function returns an error immediately, ensuring only one retranscription job runs concurrently.
The Audio Processing Pipeline
The run_retranscription function (lines 171-188) executes the actual processing workflow:
- Audio Decoding: The
decodermodule reads the stored.wavor.mp3file from the meeting folder (seeaudio/decoder.rs) - Whisper Engine Initialization:
whisper_engine::WhisperEngineinstantiates with the user-selected model and provider - Chunked Transcription: The audio stream splits into 30-second windows, with each window sent to Whisper for inference
- Progress Emission: The backend emits
retranscription-progressevents (line 510) to update the frontend UI with real-time status
This chunked approach prevents memory exhaustion on large meeting files while maintaining transcription accuracy.
Metadata Persistence and Provenance
After successful completion, write_retranscription_metadata (lines 723-756) updates the meeting's metadata.json:
fn write_retranscription_metadata(path: &Path) -> anyhow::Result<()> {
let mut obj = read_json(path)?;
let now = chrono::Utc::now().to_rfc3339();
obj.insert("retranscribed_at".into(), json!(now));
obj.insert("source".into(), json!("retranscription"));
write_json(path, &obj)
}
This preserves existing fields while adding a retranscribed_at timestamp and marking the source as "retranscription", creating a clear audit trail of the processing history.
Cancellation and State Guarding
The module provides safe cancellation through cancel_retransmission (lines 84-85), which clears the atomic flag and aborts the background task. Additionally, all public command wrappers (lines 823-831) first verify is_retranscription_in_progress to reject duplicate invocations before processing begins.
Module Organization
The retranscription utilities are re-exported from frontend/src-tauri/src/audio/mod.rs (line 49), making them available to the broader backend while maintaining clean separation of concerns.
Frontend Integration
To initiate retranscription from the TypeScript frontend:
await invoke('start_retranscription_command', {
meeting_id: '2024-07-14-09-00',
meeting_folder_path: '/path/to/meeting',
language: 'en',
model: 'base',
provider: 'whisper'
});
The backend handles the request asynchronously, emitting progress events until the final metadata update completes.
Summary
- Atomic concurrency control: The
RETRANSLATION_IN_PROGRESSflag prevents simultaneous retranscription jobs usingOrdering::SeqCstfor thread safety - Chunked processing: Audio splits into 30-second windows to balance memory usage and Whisper API efficiency
- Metadata provenance: Each run updates
metadata.jsonwithretranscribed_attimestamps and"retranscription"source tags - Safe cancellation: Background tasks can be aborted via
cancel_retranscription_command, which clears the atomic lock and halts processing - Rust-based architecture: The entire workflow runs in the Tauri backend (
frontend/src-tauri/src/audio/retranscription.rs), isolating heavy audio processing from the frontend
Frequently Asked Questions
How does Meetily prevent concurrent retranscription jobs?
The system uses a global AtomicBool named RETRANSLATION_IN_PROGRESS that is checked atomically before starting any new job. If the flag is already true, the start_retranscription function returns an error immediately, ensuring only one retranscription process runs at a time to prevent resource conflicts and data corruption.
What audio formats does the retranscription module support?
According to the source code in frontend/src-tauri/src/audio/decoder.rs, the module reads stored .wav and .mp3 files from the meeting folder. The decoder handles format conversion before passing raw audio to the Whisper engine for transcription.
Can users change the Whisper model or language during retranscription?
Yes. The start_retranscription function accepts optional parameters for language, model, and provider. Users can reprocess existing meeting files with different Whisper models (e.g., switching from base to large) or translate to different languages without re-recording the original audio.
Where does Meetily store retranscription timestamps?
After successful completion, the write_retranscription_metadata function (lines 723-756 in retranscription.rs) updates the meeting's metadata.json file with a retranscribed_at field containing the ISO 8601 timestamp and sets the source field to "retranscription", creating a permanent record of when and how the transcription was generated.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →