How Meetily's Import Module Handles External Audio File Ingestion and Format Detection
Meetily's import module handles external audio file ingestion and format detection through a Rust-based pipeline in frontend/src-tauri/src/audio/import.rs that validates file extensions against a whitelist, probes metadata using the Symphonia crate for efficient duration extraction, and falls back to full decoding when necessary, supporting files up to 20 GB.
Meetily's import module provides a robust backend for ingesting external audio files into the application, implemented in the Zackriya-Solutions/meetily repository. The system leverages Tauri's native dialog capabilities and the Symphonia audio library to detect formats and validate files before processing them for transcription. This technical deep-dive explores the exact mechanisms used to handle file selection, format detection, and the validation pipeline that ensures only compatible audio reaches the transcription engine.
The Three-Phase Import Architecture
The import pipeline operates through three distinct phases orchestrated by commands defined in frontend/src-tauri/src/audio/import.rs.
Phase 1: Native File Selection
The process begins when the frontend invokes select_and_validate_audio_command, which launches a native file dialog via tauri_plugin_dialog. The dialog automatically filters selectable files using the AUDIO_EXTENSIONS constant defined in constants.rs, presenting users with a whitelist of supported formats including MP4, M4A, WAV, MP3, FLAC, OGG, AAC, MKV, WebM, and WMA.
Once the user selects a file, the command returns the path to the Rust backend for validation. This approach ensures that only potentially compatible files reach the validation stage while providing a native OS-level selection experience.
Phase 2: Validation and Format Detection
The validate_audio_file function performs comprehensive validation before any heavy processing occurs. First, it verifies the file exists and checks that its size does not exceed the 20 GB limit enforced to prevent out-of-memory errors.
Format detection occurs in two stages for efficiency:
- Extension validation: The file extension is normalized to lowercase and compared against the
AUDIO_EXTENSIONSslice fromconstants.rs. - Metadata extraction: The function calls
extract_duration_from_metadata, which uses the Symphonia crate to build aHintfrom the file extension, probe the format, and readsample_rateandn_framesto calculate duration without decoding audio data.
If Symphonia cannot determine the duration (for example, when frame counts are missing), the system falls back to decode_audio_file from decoder.rs for a full decode.
Phase 3: Import Orchestration
Once validated, start_import_audio_command spawns start_import, which acquires a guard to ensure only one import runs concurrently. This phase:
- Creates a dedicated meeting folder
- Copies the source file to the new location
- Decodes and resamples audio to 16 kHz mono format required by Whisper
- Runs Voice Activity Detection (VAD) via
get_speech_chunks_with_progressfromvad.rs - Transcribes speech chunks
- Writes
transcripts.jsonandmetadata.jsonto the meeting folder
Technical Implementation of Format Detection
Format detection in Meetily balances speed with accuracy through a tiered approach.
Extension-Based Whitelist Validation
The authoritative list of supported formats resides in frontend/src-tauri/src/audio/constants.rs:
pub const AUDIO_EXTENSIONS: &[&str] = &[
"mp4", "m4a", "wav", "mp3", "flac", "ogg", "aac", "mkv", "webm", "wma"
];
During validation, the system extracts the extension using path.extension(), converts it to lowercase, and checks membership in this static slice. This provides instantaneous rejection of unsupported containers before any I/O-intensive operations occur.
Metadata Probing with Symphonia
The extract_duration_from_metadata function (lines 192-250 in import.rs) implements efficient format detection:
pub fn extract_duration_from_metadata(path: &Path) -> Result<f64> {
let file = File::open(path)?;
let mss = MediaSourceStream::new(Box::new(file), Default::default());
// Build hint from file extension
let mut hint = Hint::new();
if let Some(ext) = path.extension() {
hint.with_extension(&ext.to_string_lossy());
}
// Probe format and read metadata
let probed = symphonia::default::get_probe()
.format(&hint, mss, &Default::default(), Default::default())?;
// Calculate duration from sample_rate and n_frames
// ...
}
This approach reads only container metadata, making it suitable for multi-gigabyte files where full decoding would be prohibitively expensive.
Fallback Full-Decode Strategy
When metadata probing fails, the system invokes decode_audio_file from decoder.rs. This function performs a complete decode to determine duration and validate format integrity. While more resource-intensive, this fallback ensures compatibility with malformed or complex audio files that report incomplete metadata headers.
Code Implementation Examples
Frontend File Selection
React/TypeScript code that triggers the import dialog:
import { invoke } from '@tauri-apps/api/tauri';
interface AudioFileInfo {
path: string;
filename: string;
duration_seconds: number;
size_bytes: number;
format: string;
}
async function pickAudioFile() {
const info = await invoke<AudioFileInfo | null>('select_and_validate_audio_command');
if (!info) {
console.log('User cancelled selection');
return;
}
console.log(`Selected ${info.format} file: ${info.filename}, duration: ${info.duration_seconds}s`);
}
Backend Validation Logic
The core validation function in frontend/src-tauri/src/audio/import.rs:
pub fn validate_audio_file(path: &Path) -> Result<AudioFileInfo> {
// Verify file exists
if !path.exists() {
return Err(anyhow!("File does not exist: {}", path.display()));
}
// Validate extension against whitelist
let extension = path.extension()
.and_then(|e| e.to_str())
.map(|e| e.to_lowercase())
.unwrap_or_default();
if !AUDIO_EXTENSIONS.contains(&extension.as_str()) {
return Err(anyhow!("Unsupported format: .{} not in supported list", extension));
}
// Size guard (20 GB limit)
let metadata = fs::metadata(path)?;
if metadata.len() > 20 * 1024 * 1024 * 1024 {
return Err(anyhow!("File exceeds 20 GB limit"));
}
// Attempt metadata extraction, fallback to decode
let duration_seconds = match extract_duration_from_metadata(path) {
Ok(d) => d,
Err(_) => decode_audio_file(path)?.duration_seconds,
};
Ok(AudioFileInfo {
path: path.to_string_lossy().to_string(),
filename: path.file_name().unwrap().to_string_lossy().to_string(),
duration_seconds,
size_bytes: metadata.len(),
format: extension.to_uppercase(),
})
}
Drag-and-Drop Validation
For files dropped onto the application:
#[tauri::command]
pub async fn validate_audio_file_command(path: String) -> Result<AudioFileInfo, String> {
validate_audio_file(Path::new(&path))
.map_err(|e| e.to_string())
}
Summary
- Meetily's import module uses a three-phase pipeline (selection, validation, orchestration) implemented in
frontend/src-tauri/src/audio/import.rs - Format detection relies on extension whitelisting from
constants.rsfollowed by Symphonia metadata probing, with full-decode fallback for edge cases - File size limits of 20 GB prevent memory exhaustion during processing
- Supported formats include MP4, M4A, WAV, MP3, FLAC, OGG, AAC, MKV, WebM, and WMA
- Final processing converts all valid audio to 16 kHz mono and applies VAD before transcription
Frequently Asked Questions
What audio formats does Meetily support?
Meetily supports MP4, M4A, WAV, MP3, FLAC, OGG, AAC, MKV, WebM, and WMA files. The authoritative list is defined in the AUDIO_EXTENSIONS constant in frontend/src-tauri/src/audio/constants.rs. The system validates extensions case-insensitively before attempting any format detection.
How does Meetily detect audio formats without decoding the entire file?
The system uses the Symphonia crate's extract_duration_from_metadata function to probe file headers and metadata. This creates a Hint from the file extension, probes the format, and reads sample_rate and n_frames to calculate duration without loading audio samples into memory. This approach handles multi-gigabyte files efficiently.
What happens if Symphonia cannot read the audio metadata?
When metadata extraction fails (typically due to missing frame counts or malformed headers), Meetily falls back to decode_audio_file from decoder.rs. This performs a full audio decode to determine the duration and validate the file. While more resource-intensive, this fallback ensures compatibility with problematic files that would otherwise be rejected.
Is there a file size limit for imported audio?
Yes, Meetily enforces a 20 GB limit during the validation phase in validate_audio_file. Files exceeding this size are rejected immediately to prevent out-of-memory errors during the subsequent decode, resample, and VAD processing stages. This guard is checked after extension validation but before any metadata extraction occurs.
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 →