Re‑Transcribe Existing Recordings with Different Models or Languages Using the Meetily Import Module

The import module exposes a Tauri command that accepts optional language, model, and provider parameters, allowing any audio file—including existing meeting recordings—to be processed through the transcription pipeline with completely new settings.

The Meetily open‑source meeting assistant (available at Zackriya-Solutions/meetily) includes a robust import system that treats re‑transcription as a first‑class operation. Rather than locking you into the settings used during the original recording, the import module lets you revisit any audio file and apply different transcription models, language hints, or even switch between providers like Whisper and Parakeet.

How the Import Module Handles Re‑Transcription

The re‑transcription capability centers on a parameter‑driven Tauri command that decouples the audio source from the processing configuration. This means the same pipeline used for live recordings can be invoked retroactively with fresh parameters.

The Tauri Command Entry Point

The frontend communicates with the backend through start_import_audio_command, defined in frontend/src-tauri/src/audio/import.rs. This command accepts the source audio path alongside optional transcription settings:

#[tauri::command]
pub async fn start_import_audio_command<R: Runtime>(
    app: AppHandle<R>,
    source_path: String,
    title: String,
    language: Option<String>,
    model: Option<String>,
    provider: Option<String>,
) -> Result<ImportStarted, String> {
    // Guard against concurrent imports
    if IMPORT_IN_PROGRESS.load(Ordering::SeqCst) {
        return Err("Import already in progress".into());
    }

    // Run the import in a background task
    tauri::async_runtime::spawn(async move {
        let _ = start_import(app, source_path, title, language, model, provider).await;
    });

    Ok(ImportStarted { message: "Import started".into() })
}

Because language, model, and provider are all Option<String>, the command remains flexible: omitting them triggers auto‑detection or default settings, while providing them overrides the behavior for that specific import session.

Background Processing and Validation

Once the command accepts the request, it delegates to start_import, which spawns a background task. The flow follows three distinct phases:

  1. Validation – The system calls validate_audio_file to verify the audio format and integrity before processing begins.
  2. Pipeline Routing – The validated file enters the import pipeline, which ultimately invokes the transcription provider trait defined in src-tauri/src/audio/transcription/provider.rs.
  3. Event Emission – Progress updates (import-progress), completion (import-complete), and errors (import-error) are emitted as Tauri events, allowing the frontend to track the re‑transcription status in real time.

Provider‑Specific Language and Model Handling

The transcription layer delegates to concrete provider implementations based on the provider argument:

Whisper Provider (src-tauri/src/audio/transcription/whisper_provider.rs): Accepts both language and model parameters directly. The transcribe_audio_with_confidence method forwards these to the underlying Whisper engine:

pub async fn transcribe_audio_with_confidence(
    &self,
    audio: Vec<f32>,
    language: Option<String>,
) -> Result<TranscriptionResult, anyhow::Error> {
    // Whisper can receive a language hint; if None it auto‑detects
    let lang = language.unwrap_or_else(|| "auto".into());
    self.whisper_engine
        .transcribe_with_confidence(audio, Some(lang), self.model.clone())
        .await
}

Parakeet Provider (src-tauri/src/audio/transcription/parakeet_provider.rs): Currently respects the selected model but logs a warning when a language hint is supplied (the hint is ignored in the current implementation). This architecture allows the provider to be extended later without changing the import module’s interface.

Code Implementation Details

Frontend Hook for Custom Imports

The React frontend consumes the re‑transcription capability through the useImportAudio hook located in frontend/src/hooks/useImportAudio.ts. This hook wraps the Tauri command and listens for backend events to update the UI state:

import { useImportAudio } from '@/hooks/useImportAudio';

function ReTranscribeButton({ meeting }) {
  const { startImport } = useImportAudio({
    onComplete: (result) => console.log('Re‑transcribed', result),
  });

  const handleClick = async () => {
    // Path points to the existing meeting’s audio file
    const sourcePath = meeting.audioFilePath;
    const title = meeting.title;

    // Choose a different model or language
    const language = 'es';          // Spanish
    const model = 'medium';         // Whisper medium model
    const provider = 'whisper';     // Use Whisper provider

    await startImport(sourcePath, title, language, model, provider);
  };

  return <button onClick={handleClick}>Re‑transcribe in Spanish</button>;
}

This pattern enables users to point at an existing meeting’s audio file and override the transcription settings without affecting the original recording data.

Rust Command Handler

The backend implementation in frontend/src-tauri/src/audio/import.rs demonstrates how the import module guards against race conditions (via IMPORT_IN_PROGRESS) while allowing asynchronous re‑transcription. The start_import function orchestrates the entire flow, ensuring that even long‑running transcriptions on large existing recordings do not block the main thread.

Whisper Provider Integration

When re‑transcribing with Whisper, the provider trait method transcribe (defined in src-tauri/src/audio/transcription/provider.rs) receives the optional language hint:

pub async fn transcribe(
    &self,
    audio: AudioChunk,
    language: Option<String>,
) -> Result<TranscriptionResult, anyhow::Error> { … }

Each provider implements this trait, ensuring that the import module remains agnostic to whether the underlying engine is OpenAI Whisper, NVIDIA Parakeet, or future providers.

Re‑Transcription Workflow

For developers looking to extend or debug the re‑transcription feature, the following files form the complete execution path:

Summary

  • The import module exposes start_import_audio_command, which accepts language, model, and provider as optional overrides.
  • Any audio file path—including those from existing meetings—can be passed to this command, enabling re‑transcription without re‑recording.
  • The Whisper provider respects both language hints and model selection, while the Parakeet provider architecture allows for future extension.
  • Event‑driven architecture (import-complete, import-error) keeps the frontend synchronized with background processing tasks.
  • The feature is gated behind beta flags in betaFeatures.ts and implemented in retranscription.rs for existing meeting objects.

Frequently Asked Questions

How does the import module know which transcription provider to use?

The provider parameter in start_import_audio_command determines which concrete implementation of the transcription trait is instantiated. Valid values typically include "whisper" or "parakeet", with the system defaulting to a preconfigured provider if the parameter is omitted.

Can I re‑transcribe a meeting that was originally recorded in English using a Spanish language model?

Yes. By passing language: "es" to the import command, the Whisper provider will treat the audio as Spanish input. If the provider supports the specified language code, the transcription will be generated accordingly, even if the original meeting metadata specifies English.

What happens if I try to import the same audio file while another import is running?

The command checks the IMPORT_IN_PROGRESS atomic boolean before spawning a background task. If an import is already active, the function returns an error with the message "Import already in progress", preventing resource contention and ensuring sequential processing.

Is the original transcription overwritten when I re‑transcribe an existing recording?

According to the current implementation in Zackriya-Solutions/meetily, the new transcription result is typically stored alongside the original or replaces it depending on the frontend state management. The raw audio file remains untouched; only the derived transcript text is updated or appended based on how the useImportAudio hook handles the import-complete event.

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 →