How Meetily Implements Import Audio for Subsequent Re-Transcription
Meetily treats imported audio files as new meetings by copying them into a local directory and processing them through the same decode-resample-VAD-transcription pipeline used for live recordings, enabling users to re-transcribe them later with different languages, models, or providers.
Meetily is an open-source meeting transcription application from Zackriya-Solutions that unifies external audio files and live recordings under a single processing architecture. The import audio feature for subsequent re-transcription allows users to ingest existing audio files, store them persistently, and re-process them multiple times using various transcription engines without re-importing the source file.
Import Pipeline Architecture
When a user imports an audio file, Meetily creates a dedicated meeting folder and runs the audio through a standardized pipeline that ensures compatibility with both Whisper and Parakeet transcription engines.
File Selection and Validation
The process begins with a Tauri command that opens a native file dialog and validates the selected file. In frontend/src-tauri/src/audio/import.rs, the select_and_validate_audio_command function (lines 21‑44) handles the initial user interaction, checking file extensions and returning basic file information to the frontend before any processing begins.
Background Processing and Pipeline
Once validation succeeds, start_import_audio_command (lines 71‑80) spawns the import job in a background async task. The system acquires an ImportGuard to set the global IMPORT_IN_PROGRESS flag (lines 62‑64), preventing concurrent import operations and ensuring thread safety.
The pipeline executes the following stages sequentially:
- Meeting folder creation:
create_meeting_foldergenerates a new directory under the default recordings path (lines 42‑44) - Audio copying: The source file is copied into the meeting folder as
audio.<ext>(typicallymp4), preserving the original (lines 48‑63) - Decoding:
decode_audio_file_with_progressruns on a blocking thread to convert container formats into raw PCM (lines 73‑81) - Resampling:
to_whisper_format_with_progressconverts audio to 16 kHz mono format, the standard required by Whisper models (lines 104‑110) - Voice Activity Detection:
get_speech_chunks_with_progressapplies VAD with a 2000 ms redemption time—longer than the live pipeline—to identify speech segments accurately (lines 122‑130)
Metadata Creation
After successful processing, Meetily writes a metadata.json file using write_import_metadata (lines 78‑104). This implementation uses atomic file operations: it writes to a temporary file first, then renames it to ensure consistency even if the process terminates unexpectedly. The metadata includes a "source":"import" tag, meeting ID, duration, and audio filename.
Finally, unload_engine_after_batch (lines 80‑82) releases the transcription engine to free system resources, regardless of whether the job succeeded, failed, or was cancelled.
Re-Transcription Implementation
Re-transcription leverages the same core utilities as the initial import, ensuring consistent audio processing while allowing flexible transcription parameters.
Locating Stored Audio
When a re-transcription request arrives, find_audio_file in frontend/src-tauri/src/audio/retranscription.rs (lines 39‑66) searches the meeting folder for standard audio filenames or any file matching supported extensions. This locates the previously imported audio without requiring the user to re-select the file.
Re-running the Processing Stages
The run_retranscription function (lines 100‑220 and 236‑400) executes the identical pipeline used during import: decode → resample → VAD → optional segment-splitting → transcription. However, unlike the fixed settings used during initial import, re-transcription accepts parameters for language, model, and provider, allowing users to switch between Whisper and Parakeet engines or select different model sizes without re-importing the audio.
Progress events are emitted at each stage, enabling the frontend to display real-time status updates through the retranscription-progress event channel.
Updating Metadata
Upon completion, write_retranscription_metadata (lines 723‑756) updates metadata.json with "source":"retranscription" and records a retranscribed_at timestamp. The system writes new transcripts to transcripts.json via audio::common utilities, then emits a retranscription-complete event containing the meeting ID, segment count, duration, and language used (lines 14‑24).
Implementation Details
Shared Utilities and Consistency
Both import and re-transcription modules rely on audio::decoder, audio::vad, and audio::common as defined in src/audio/mod.rs. This shared architecture ensures identical VAD parameters (such as VAD_REDEMPTION_TIME_MS = 2000) and segment-splitting logic apply whether processing live recordings, imported files, or re-transcription jobs.
Cancellation and Concurrency Protection
Meetily implements global atomic flags including IMPORT_IN_PROGRESS, IMPORT_CANCELLED, RETRANSCRIPTION_IN_PROGRESS, and RETRANSCRIPTION_CANCELLED to prevent overlapping jobs and enable graceful aborts. The ImportGuard and equivalent re-transcription guards automatically clear these flags when the processing scope ends.
Provider Flexibility
The pipelines accept an optional provider parameter that defaults to Whisper but switches to Parakeet when "parakeet" is specified. Boolean checks like use_parakeet in both import.rs and retranscription.rs determine which transcription engine handles the audio segments.
Code Examples
Importing Audio via Frontend
import { invoke } from '@tauri-apps/api/tauri';
// Open file dialog, validate, then start import
const fileInfo = await invoke('select_and_validate_audio_command');
if (fileInfo) {
await invoke('start_import_audio_command', {
source_path: fileInfo.path,
title: 'Team Sync',
language: 'en',
model: undefined, // use default model
provider: undefined // use Whisper
});
}
Listening for Import Progress
import { listen } from '@tauri-apps/api/event';
listen('import-progress', e => {
console.log('Import progress:', e.payload);
});
listen('import-complete', e => {
console.log('Import finished – meeting ID:', e.payload.meeting_id);
});
Triggering Re-Transcription
await invoke('start_retranscription_command', {
meeting_id: '<meeting‑id>',
meeting_folder_path: '/Users/me/Library/Application Support/Meetily/recordings/Team Sync',
language: 'es', // re‑transcribe to Spanish
model: 'medium',
provider: undefined // Whisper
});
Monitoring Re-Transcription Progress
listen('retranscription-progress', e => {
const p = e.payload as {
meeting_id: string;
stage: string;
progress_percentage: number;
message: string
};
console.log(`[${p.stage}] ${p.progress_percentage}% – ${p.message}`);
});
Summary
- Unified Pipeline: Meetily uses identical decode-resample-VAD-transcription logic in
audio::decoder,audio::vad, andaudio::commonfor both initial imports and subsequent re-transcriptions. - Atomic Metadata: File operations use temporary files and atomic renames to prevent corruption during interruptions.
- Flexible Re-processing: Re-transcription allows changing languages, models, and providers (Whisper or Parakeet) without re-importing the original audio file.
- Concurrency Safety: Global flags and guard patterns prevent overlapping import or re-transcription jobs.
- Persistent Storage: Imported audio lives in dedicated meeting folders under the recordings directory, enabling unlimited re-transcription cycles.
Frequently Asked Questions
What is the difference between importing audio and re-transcribing in Meetily?
Importing creates a new meeting by copying external audio into Meetily's storage and processing it for the first time, while re-transcription re-processes that already-stored audio using different transcription settings. Both operations use the same core pipeline in audio::import.rs and audio::retranscription.rs, but re-transcription skips the file copying stage and allows parameter overrides.
How does Meetily prevent concurrent import or re-transcription jobs?
The system uses atomic flags (IMPORT_IN_PROGRESS, RETRANSCRIPTION_IN_PROGRESS) and guard structs like ImportGuard that set these flags when a job starts and automatically clear them when the scope ends. This mechanism prevents resource conflicts and ensures only one intensive audio processing job runs at a time.
What happens to the original audio file when I import it into Meetily?
Meetily copies the original file into a newly created meeting folder within the recordings directory, typically naming it audio.mp4 or preserving the original extension. The source file remains untouched in its original location, while Meetily works with the copy for all processing and subsequent re-transcription cycles.
Can I change the transcription language or model when re-transcribing imported audio?
Yes, re-transcription accepts new language, model, and provider parameters that override the original import settings. You can switch from Whisper to Parakeet, change from English to Spanish, or select a different model size without re-importing the file, as implemented in run_retranscription (lines 100‑400 of retranscription.rs).
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 →