How to Import and Enhance Existing Audio Files with Different Transcription Models in Meetily

Meetily treats imported audio files as meetings that flow through the same processing pipeline as live recordings, allowing you to select Whisper models during import and swap them later via the retranscribe_meeting function without re-uploading your files.

Meetily is an open-source, desktop-first meeting assistant that unifies live capture and file import into a single processing pipeline. Whether you are importing a legacy recording or enhancing an existing transcript with a larger model, the application treats every audio source identically—running it through voice-activity detection, GPU-accelerated transcription, and LLM summarization. This approach ensures consistent quality while giving you the flexibility to upgrade transcription accuracy long after the initial import.

Initiating the Import via Tauri Commands

The import process begins in the frontend, which invokes the Tauri command start_import_audio_command registered in src/lib.rs. This command accepts the file path, an optional meeting title, the language code, the specific Whisper model to use, and the LLM provider for downstream summarization.

The Tauri runtime handles the request asynchronously, ensuring the UI remains responsive while the backend validates and processes the audio. Progress events—including import-progress, import-complete, and import-error—are emitted back to the frontend to provide real-time feedback.

Validating Files and Creating Meeting Records

Once invoked, the import logic in frontend/src-tauri/src/audio/import.rs takes over. First, it validates the file extension against a whitelist defined in audio/constants.rs to ensure compatibility with the processing pipeline.

The module then opens a file dialog via the tauri::api::dialog API, allowing users to select their audio file interactively. Upon selection, the system creates a temporary meeting record in the local SQLite database, storing critical metadata such as the source path, selected language, transcription model, and LLM provider.

Processing Audio Through the Unified Pipeline

After validation, the audio streams through frontend/src-tauri/src/audio/pipeline.rs, which uses the same AudioMixerRingBuffer employed for live captures. This ensures identical processing behavior regardless of source.

The pipeline performs two critical optimizations before transcription:

  1. Resampling the audio to a uniform 48 kHz rate to match Whisper's expected input.
  2. Voice-Activity Detection (VAD) to strip silence and non-speech segments, dramatically reducing the data volume sent to the transcription engine and improving processing speed.

Selecting and Loading Transcription Models

The actual speech-to-text conversion happens in frontend/src-tauri/src/whisper_engine/whisper_engine.rs. The engine supports multiple Whisper model sizes—tiny, base, small, medium, and large-v3—selected via the model parameter passed during import.

The engine loads the specified model once and caches it for the session to avoid redundant disk I/O. GPU acceleration is automatically detected and applied through helpers in whisper_engine/acceleration.rs, leveraging Metal on macOS and CUDA or Vulkan on Windows and Linux.

Retranscribing with Different Models

Meetily's architecture allows you to enhance transcription quality without re-importing the original file. The retranscribe_meeting function in frontend/src-tauri/src/audio/retranscription.rs enables model swapping by clearing the previous transcript, unloading the current Whisper instance, loading the new model, and re-running the audio through the pipeline.

This approach preserves the original meeting metadata while allowing you to upgrade from a fast tiny model to a more accurate large-v3 model, or switch languages entirely, using the stored audio file path retrieved from the database.

Example: Importing Audio from the Frontend

To import an audio file from the TypeScript frontend, invoke the command with your desired model and provider parameters:

import { invoke } from '@tauri-apps/api/tauri';

async function importAudio() {
  const result = await invoke('start_import_audio_command', {
    sourcePath: '/Users/alex/Downloads/team_meeting.wav',
    title: 'Team Sync – April 2026',
    language: 'en',                     // ISO‑639‑1 code
    model: 'medium',                    // Whisper model name
    provider: 'openrouter'              // LLM provider for summarisation
  });

  console.log('Import started:', result);
}

Example: Core Import Logic in Rust

The backend implementation creates the meeting entry, configures the Whisper engine, and streams the audio through the pipeline:

// src-tauri/src/audio/import.rs – core import logic (simplified)
pub async fn start_import<R: Runtime>(
    app: AppHandle<R>,
    source_path: String,
    title: Option<String>,
    language: Option<String>,
    model: Option<String>,
    provider: Option<String>,
) -> Result<(), String> {
    // 1️⃣ Validate the file and create a new meeting entry
    let meeting_id = database::manager::create_meeting(&app, title, source_path.clone()).await?;

    // 2️⃣ Configure the Whisper engine with the requested model
    let whisper = WhisperEngine::new(model.unwrap_or_else(|| "base".to_string()))?;
    app.manage(whisper);

    // 3️⃣ Stream the audio through the pipeline (VAD + resampling)
    audio::pipeline::process_file(&app, &source_path).await?;

    // 4️⃣ Emit a completion event for the UI
    app.emit_all("import-complete", meeting_id).map_err(|e| e.to_string())
}

Example: Swapping Models with Retranscription

To re-transcribe an existing meeting with a different model, unload the current engine and reload the desired one:

// src-tauri/src/audio/retranscription.rs – swapping transcription models
pub async fn retranscribe_meeting<R: Runtime>(
    app: AppHandle<R>,
    meeting_id: u64,
    new_model: String,
) -> Result<(), String> {
    // Unload the previous Whisper instance
    app.state::<WhisperEngine>()
        .write()
        .unwrap()
        .unload();

    // Load the new model
    let whisper = WhisperEngine::new(new_model)?;
    app.manage(whisper);

    // Re‑run the pipeline on the stored audio file
    let file_path = database::queries::get_meeting_audio_path(&app, meeting_id).await?;
    audio::pipeline::process_file(&app, &file_path).await
}

Downstream Processing and Summarization

Once transcription completes, the resulting text flows to the selected LLM provider—such as Ollama, Groq, or OpenRouter—via the respective command modules in openrouter/mod.rs and ollama/mod.rs. A prompt template assembles the final meeting summary, maintaining the privacy-first, local-only workflow that characterizes Meetily's architecture.

Summary

  • Unified Pipeline: Meetily processes imported audio through the same AudioMixerRingBuffer and VAD pipeline used for live recordings, ensuring consistent quality.
  • Flexible Model Selection: Choose from Whisper models (tiny through large-v3) during initial import via start_import_audio_command, with automatic GPU acceleration detection.
  • Non-Destructive Enhancement: Use retranscribe_meeting in audio/retranscription.rs to upgrade transcription accuracy or change languages without re-importing the original file.
  • Event-Driven Feedback: The import system emits progress events (import-progress, import-complete, import-error) to keep the frontend responsive and informed.

Frequently Asked Questions

What audio file formats does Meetily support for import?

Meetily validates file extensions against a whitelist defined in frontend/src-tauri/src/audio/constants.rs before processing. While specific extensions depend on the platform's audio codec support, the system ensures compatibility with standard formats like WAV and MP3 by verifying the extension and then attempting to stream the file through the resampling pipeline.

Can I switch from a smaller Whisper model to a larger one after transcription?

Yes. The retranscribe_meeting function in frontend/src-tauri/src/audio/retranscription.rs allows you to clear the existing transcript and re-process the stored audio with any available model—from tiny to large-v3—without requiring you to re-import the original file. The function retrieves the audio path from the SQLite database and re-runs the pipeline with the new model configuration.

How does Meetily handle GPU acceleration for transcription?

The whisper_engine automatically detects available hardware acceleration through frontend/src-tauri/src/whisper_engine/acceleration.rs. On macOS, it leverages Metal; on Windows and Linux, it utilizes CUDA or Vulkan. This detection happens during engine initialization in whisper_engine.rs, ensuring the selected model runs on the most efficient hardware available without manual configuration.

Where is meeting metadata stored during the import process?

When you initiate an import, the system creates a temporary meeting record in the local SQLite database via database::manager::create_meeting. This record stores the source file path, selected language, transcription model, and LLM provider. The metadata persists through the transcription and summarization phases, allowing the retranscribe_meeting function to locate and re-process the audio file later.

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 →