{"record":{"id":"4132ed58d896a14e","repo":"Zackriya-Solutions/meetily","slug":"no-audio-samples-decoded-from-file","errorCode":null,"errorMessage":"No audio samples decoded from file","messagePattern":"No audio samples decoded from file","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"frontend/src-tauri/src/audio/decoder.rs","lineNumber":558,"sourceCode":"                        last_progress = current_progress;\n                        callback(current_progress, &format!(\"Decoding audio: {}%\", current_progress));\n                    }\n                }\n            }\n            Err(e) => {\n                warn!(\"Error decoding packet: {}\", e);\n                continue;\n            }\n        }\n    }\n\n    // Ensure we report 100% completion\n    if let Some(callback) = &progress_callback {\n        callback(100, \"Decoding complete\");\n    }\n\n    if all_samples.is_empty() {\n        return Err(anyhow!(\"No audio samples decoded from file\"));\n    }\n\n    let total_frames = all_samples.len() / channels as usize;\n    let duration_seconds = total_frames as f64 / sample_rate as f64;\n\n    info!(\n        \"Decoded {} samples ({:.2}s) at {}Hz, {} channels\",\n        all_samples.len(),\n        duration_seconds,\n        sample_rate,\n        channels\n    );\n\n    Ok(DecodedAudio {\n        samples: all_samples,\n        sample_rate,\n        channels,\n        duration_seconds,","sourceCodeStart":540,"sourceCodeEnd":576,"githubUrl":"https://github.com/Zackriya-Solutions/meetily/blob/0281737d87d26352fb0adc78c8c0975f691b23d1/frontend/src-tauri/src/audio/decoder.rs#L540-L576","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","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.","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.","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.","For a file still being written (live recording/export), wait until the writer finalizes the container (moov atom for MP4) and retry.","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."],"exampleFix":"// before: first non-null codec track wins, may pick a data/cover track\nlet track = format.tracks().iter().find(|t| t.codec_params.codec != CODEC_TYPE_NULL)\n    .ok_or_else(|| anyhow!(\"No audio track found in file\"))?;\n\n// after: prefer a track with declared sample_rate (real audio)\nlet track = format.tracks().iter()\n    .filter(|t| t.codec_params.codec != CODEC_TYPE_NULL)\n    .max_by_key(|t| t.codec_params.sample_rate.is_some() as u8)\n    .ok_or_else(|| anyhow!(\"No audio track found in file\"))?;","handlingStrategy":"validation","validationCode":"// Rust caller: cheap pre-check that the file has a decodable audio track\nfn has_decodable_audio(path: &Path) -> bool {\n    let Ok(f) = std::fs::File::open(path) else { return false };\n    let mss = symphonia::default::MediaSourceStream::new(Box::new(f), Default::default());\n    let Ok(probed) = symphonia::default::get_probe().format(&Hint::new(), mss, &Default::default(), &Default::default()) else { return false };\n    probed.format.tracks().iter().any(|t| t.codec_params.sample_rate.is_some())\n}\n// or shell out: ffmpeg -v error -i file -f null - ; exit 0 means decodable","typeGuard":null,"tryCatchPattern":"// Treat decode failure as: try ffmpeg fallback once, else surface a clear message\nlet decoded = match decode_audio_file(&path) {\n    Ok(d) => d,\n    Err(e) if e.to_string().contains(\"No audio samples decoded\") => {\n        let wav = convert_to_wav_16k_via_ffmpeg(&path)?; // explicit fallback\n        decode_audio_file(&wav)?\n    }\n    Err(e) => return Err(e),\n};","preventionTips":["Validate recordings with ffprobe before offering them to the import flow.","Install ffmpeg on PATH so MKV/WebM/WMA and codec-mismatch cases go through conversion instead of Symphonia failure.","Reject zero-byte and header-only files at the extension/size gate before decoding.","Log the per-packet Symphonia warnings - they reveal the true codec error behind the empty-sample result."],"tags":["audio","decoding","symphonia","import","whisper"],"backgroundTag":"audio-decode-zero-samples","analyzedSha":"0281737d87d26352fb0adc78c8c0975f691b23d1","analyzedAt":"2026-08-16T20:57:52.567Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}