# How Meetily's Import and Enhance Feature Enables Re-Transcribing Recordings

> Re-transcribe recordings with Meetily's Import and Enhance feature. Upload audio, re-run VAD and transcription pipelines with different AI models or languages for improved accuracy.

- Repository: [Zackriya Solutions/meetily](https://github.com/Zackriya-Solutions/meetily)
- Tags: how-to-guide
- Published: 2026-07-19

---

**Meetily's Import and Enhance feature allows users to import external audio files for initial transcription and re-transcribe existing meetings with different AI models or languages by re-running the same Voice Activity Detection (VAD) and transcription pipeline on the original audio.**

Meetily is an open-source meeting assistant that provides a complete transcription pipeline for audio processing. The **Import** functionality creates new meetings from external audio files, while the **Enhance** capability enables re-transcription with alternative providers like Whisper or Parakeet, or different language settings, without requiring the original source file again.

## The Import Pipeline Architecture

The import process follows a strict six-stage pipeline implemented in Rust within the Tauri backend. Each stage emits progress events to keep the frontend responsive while processing large audio files up to 20 GB.

### File Selection and Validation

The entry point `select_and_validate_audio_command` in [`frontend/src-tauri/src/audio/import.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/import.rs) opens a native file dialog and performs fast validation checks. This includes verifying file existence, enforcing size limits, checking supported extensions, and extracting duration metadata without loading the entire file into memory.

```rust
#[tauri::command]
pub async fn select_and_validate_audio_command<R: Runtime>(
    app: AppHandle<R>,
) -> Result<Option<AudioFileInfo>, String> {
    // Opens native file-picker filtered to supported extensions
    // Validates: existence → size limit (20 GB) → allowed extension → duration
}

```

If `extract_duration_from_metadata` succeeds, the system avoids the expensive full audio decode until the user confirms the import.

### Audio Decoding and Resampling

Once validation passes, `start_import_audio_command` checks the global `IMPORT_IN_PROGRESS` atomic flag to prevent concurrent imports, then spawns the `run_import` background task. This task copies the source file to a new meeting folder and decodes it using `decode_audio_file_with_progress`, then resamples the audio to **16 kHz mono PCM** using `to_whisper_format_with_progress`—a requirement for both Whisper and Parakeet transcription engines.

### Voice Activity Detection (VAD)

The `ContinuousVadProcessor` in [`frontend/src-tauri/src/audio/vad.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/vad.rs) processes the resampled audio to isolate speech chunks while preserving natural utterance boundaries. It configures Silero VAD with specific parameters optimized for batch processing:

- **Sample rate**: 16 kHz (required by transcription engines)
- **Redemption time**: 2,000 ms (keeps natural pauses within the same utterance)
- **Minimum speech time**: 250 ms (prevents tiny fragments that violate Whisper's 100 ms minimum segment rule)

```rust
// VAD configuration in vad.rs
ContinuousVadProcessor::new(
    16000,  // sample_rate
    2000,   // redemption_time_ms for batch imports
    250,    // min_speech_time_ms
)

```

### Segmentation and Splitting

Long speech segments exceeding 25 seconds are automatically split at silence boundaries using `split_segment_at_silence`. This ensures compliance with Whisper's architectural constraints while maintaining semantic coherence by breaking only at natural pauses.

### Transcription Engine Execution

Each speech segment is dispatched to the selected transcription provider. The system initializes the appropriate engine via `get_or_init_whisper` or `get_or_init_parakeet` in [`import.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/import.rs), then calls `engine.transcribe_audio_with_confidence` to generate text with confidence scores. The pipeline accumulates results across all segments while maintaining temporal order.

### Database Persistence

The final stage inserts a new meeting record into the SQLite database using `create_meeting_with_transcripts`, writes the transcript array to [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json), and generates [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json) with import timestamps and configuration details. This creates a complete, queryable meeting record within the Meetily ecosystem.

## The Enhance (Retranscription) Workflow

The **Enhance** feature leverages the same processing pipeline but operates on existing meeting folders rather than creating new ones. When users select "Retranscribe" to switch languages or upgrade from Whisper to Parakeet, the frontend invokes `start_retranscription_command` located in [`frontend/src-tauri/src/audio/retranscription.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/retranscription.rs).

```rust
#[tauri::command]
pub async fn start_retranscription_command<R: Runtime>(
    app: AppHandle<R>,
    meeting_id: String,
    meeting_folder_path: String,
    language: Option<String>,
    model: Option<String>,
    provider: Option<String>,
) -> Result<RetranscriptionStarted, String> {
    // Checks RETRANSCRIPTION_IN_PROGRESS flag
    // Loads existing audio from meeting_folder_path
    // Re-runs stages 3-7 of the import pipeline
}

```

Unlike import, enhancement works **in-place**: it reads the existing audio file from the meeting folder, re-processes it through VAD and transcription with the new parameters, overwrites the previous [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json), and updates [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json) with a `retranscribed_at` timestamp while preserving original metadata fields.

```rust
// Metadata update in retranscription.rs
obj.insert("retranscribed_at".to_string(), serde_json::json!(now));
obj.insert("status".to_string(), serde_json::json!("completed"));

```

## Frontend Integration Examples

### Importing New Audio with React

The frontend communicates with the Rust backend via Tauri's invoke API. The following TypeScript example demonstrates file selection and import initiation with progress monitoring:

```typescript
import { invoke } from '@tauri-apps/api/core';
import { listen } from '@tauri-apps/api/event';

async function importExternalAudio() {
  // Step 1: Select and validate
  const info = await invoke('select_and_validate_audio_command');
  if (!info) return; // User cancelled dialog
  
  // Step 2: Start import with specific provider
  await invoke('start_import_audio_command', {
    source_path: info.path,
    title: info.filename,
    language: 'en',
    model: 'large-v3',
    provider: 'whisper', // or 'parakeet'
  });
}

// Monitor progress events
listen('import-progress', (event) => {
  const { stage, progress_percentage, message } = event.payload;
  console.log(`[${stage}] ${progress_percentage}%: ${message}`);
});

```

### Retranscribing Existing Meetings

To enhance an existing meeting with a different language or model:

```typescript
async function enhanceMeeting(meetingId: string, folderPath: string) {
  await invoke('start_retranscription_command', {
    meeting_id: meetingId,
    meeting_folder_path: folderPath,
    language: 'es',        // Switch to Spanish
    model: 'large-v3',     // Upgrade model size
    provider: 'parakeet',  // Switch provider
  });
}

```

Both operations emit granular progress events (`import-progress` or `retranscription-progress`) and support cancellation via `cancel_import_command` and `cancel_retranscription_command`, which set the `IMPORT_CANCELLED` or `RETRANSCRIPTION_CANCELLED` atomic flags checked at each pipeline stage.

## Cancellation and Concurrency Control

The system maintains separate atomic boolean flags for import and retranscription operations to prevent race conditions:

- `IMPORT_IN_PROGRESS` and `IMPORT_CANCELLED` in [`import.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/import.rs)
- `RETRANSCRIPTION_IN_PROGRESS` and `RETRANSCRIPTION_CANCELLED` in [`retranscription.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/retranscription.rs)

These flags allow users to cancel long-running transcription jobs without corrupting the database or leaving partial files, as each pipeline stage checks the cancellation flag before proceeding.

## Summary

- **Import** creates new meetings by validating, copying, and transcribing external audio files through a six-stage pipeline involving VAD, segmentation, and AI transcription.
- **Enhance** re-transcribes existing meetings in-place by re-running the same pipeline with different languages, models, or providers, updating metadata with `retranscribed_at` timestamps.
- The **16 kHz mono PCM** format requirement ensures compatibility with both Whisper and Parakeet engines.
- **Silero VAD** with 2-second redemption time and 250 ms minimum speech duration optimizes transcription quality for batch processing.
- All operations provide granular progress events and cancellation support through Tauri commands in [`frontend/src-tauri/src/audio/import.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/import.rs) and [`retranscription.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/retranscription.rs).

## Frequently Asked Questions

### How does Meetily handle large audio files during import?

Meetily validates file size against a 20 GB limit during the selection phase using `select_and_validate_audio_command` in [`frontend/src-tauri/src/audio/import.rs`](https://github.com/Zackriya-Solutions/meetily/blob/main/frontend/src-tauri/src/audio/import.rs). The system extracts metadata without loading the entire file, then processes audio in chunks during decoding and VAD to maintain low memory footprint regardless of file size.

### Can I switch between Whisper and Parakeet providers when re-transcribing?

Yes. The `start_retranscription_command` accepts a `provider` parameter that switches between Whisper and Parakeet engines. The pipeline initializes the requested engine via `get_or_init_whisper` or `get_or_init_parakeet`, then re-processes the original audio file with the new provider while preserving the meeting ID and folder structure.

### What happens to the original transcription when I enhance a meeting?

The enhancement process overwrites the existing [`transcripts.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/transcripts.json) file with new results and updates [`metadata.json`](https://github.com/Zackriya-Solutions/meetily/blob/main/metadata.json) with a `retranscribed_at` timestamp. The original audio file remains untouched in the meeting folder, allowing unlimited re-transcription attempts with different configurations.

### Why does Meetily use 16 kHz mono PCM format for transcription?

Both Whisper and Parakeet transcription engines require 16 kHz mono PCM audio input. Meetily's `to_whisper_format_with_progress` function in the audio processing pipeline handles resampling and channel conversion automatically, ensuring optimal compatibility and transcription accuracy regardless of the source file's original format.