Zackriya-Solutions/meetily · error

No audio samples decoded from file

Error message

No audio samples decoded from file

What it means

Raised by decode_audio_file_with_progress (decoder.rs:558) after the Symphonia packet loop finished with an empty all_samples vector. The container probed successfully and an audio track was found (earlier guards for probe/no-track/sample-rate already passed), but every packet either failed to decode (each decode error is only warned and skipped via `continue`), belonged to a different track_id, or the stream hit EOF before yielding any audio. In practice this means the file is structurally an audio file but contains zero decodable audio data.

Solutions

  1. Inspect the preceding warn! log lines ('Error reading packet'/'Error decoding packet') - they name the Symphonia error that caused every packet to be skipped; that is the root cause.
  2. Test the file outside the app with ffprobe (or ffmpeg -v error -i file -f null -) to confirm it has a decodable audio stream and non-zero duration.
  3. If ffprobe shows a codec Symphonia lacks (e.g. Opus in MP4, ATRAC, WMA Pro), re-encode once: ffmpeg -i in.ext -ac 1 -ar 16000 out.wav and import the WAV.
  4. If ffmpeg is not installed, install it and retry so the MKV/WebM/WMA pre-conversion path in decoder.rs runs instead of Symphonia failing packet-by-packet.
  5. For a file still being written (live recording/export), wait until the writer finalizes the container (moov atom for MP4) and retry.
  6. If the first track is not audio, extend track selection at decoder.rs:448 to prefer tracks whose codec_params indicate real audio (declared sample_rate) instead of the first non-NULL codec.

Example fix

// before: first non-null codec track wins, may pick a data/cover track
let track = format.tracks().iter().find(|t| t.codec_params.codec != CODEC_TYPE_NULL)
    .ok_or_else(|| anyhow!("No audio track found in file"))?;

// after: prefer a track with declared sample_rate (real audio)
let track = format.tracks().iter()
    .filter(|t| t.codec_params.codec != CODEC_TYPE_NULL)
    .max_by_key(|t| t.codec_params.sample_rate.is_some() as u8)
    .ok_or_else(|| anyhow!("No audio track found in file"))?;
Defensive patterns

Strategy: validation

Validate before calling

// Rust caller: cheap pre-check that the file has a decodable audio track
fn has_decodable_audio(path: &Path) -> bool {
    let Ok(f) = std::fs::File::open(path) else { return false };
    let mss = symphonia::default::MediaSourceStream::new(Box::new(f), Default::default());
    let Ok(probed) = symphonia::default::get_probe().format(&Hint::new(), mss, &Default::default(), &Default::default()) else { return false };
    probed.format.tracks().iter().any(|t| t.codec_params.sample_rate.is_some())
}
// or shell out: ffmpeg -v error -i file -f null - ; exit 0 means decodable

Try / catch

// Treat decode failure as: try ffmpeg fallback once, else surface a clear message
let decoded = match decode_audio_file(&path) {
    Ok(d) => d,
    Err(e) if e.to_string().contains("No audio samples decoded") => {
        let wav = convert_to_wav_16k_via_ffmpeg(&path)?; // explicit fallback
        decode_audio_file(&wav)?
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Calling decode_audio_file/decode_audio_file_with_progress on a file where: (a) the codec is recognized but every packet decode returns Err (corrupt payload, truncated download, DRM-protected M4A), (b) the selected first audio track is not the track that actually carries packets (packet.track_id() != track_id for all packets), (c) a 0-byte or header-only audio file passed extension validation, or (d) an ffmpeg pre-conversion (MKV/WebM/WMA path) produced a WAV from a video-only source. Note needs_ffmpeg_conversion only fires for a fixed extension list, so e.g. an .mp4 with an unsupported internal codec goes straight to Symphonia.

Common situations: Importing a meeting recording that was still being written when copied; importing DRM-protected iTunes/Audible audio; mislabeled extensions (e.g. an .mp3 that is actually a renamed PDF); WebM/MKV imports without ffmpeg on PATH so the conversion path never runs; files where the first track is a cover-art/video track and the audio track is second.

Related errors


AI-assisted analysis of Zackriya-Solutions/meetily@a2cb62e827 (2026-08-16). Data as JSON: /api/errors/4132ed58d896a14e. Report an issue: GitHub.

Appendix: source

Thrown at frontend/src-tauri/src/audio/decoder.rs:571

                        last_progress = current_progress;
                        callback(current_progress, &format!("Decoding audio: {}%", current_progress));
                    }
                }
            }
            Err(e) => {
                warn!("Error decoding packet: {}", e);
                continue;
            }
        }
    }

    // Ensure we report 100% completion
    if let Some(callback) = &progress_callback {
        callback(100, "Decoding complete");
    }

    if all_samples.is_empty() {
        return Err(anyhow!("No audio samples decoded from file"));
    }

    let total_frames = all_samples.len() / channels as usize;
    let duration_seconds = total_frames as f64 / sample_rate as f64;

    info!(
        "Decoded {} samples ({:.2}s) at {}Hz, {} channels",
        all_samples.len(),
        duration_seconds,
        sample_rate,
        channels
    );

    Ok(DecodedAudio {
        samples: all_samples,
        sample_rate,
        channels,
        duration_seconds,

View on GitHub (pinned to a2cb62e827)