{"record":{"id":"f3783b84cde594e0","repo":"tonhowtf/omniget","slug":"ffmpeg-nao-converteu-a-imagem","errorCode":null,"errorMessage":"ffmpeg nao converteu a imagem {}","messagePattern":"ffmpeg nao converteu a imagem (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/slides.rs","lineNumber":77,"sourceCode":"\n/// Converte qualquer imagem em JPEG pelo ffmpeg (webp/png escapam do DCTDecode).\npub(crate) async fn ensure_jpeg(data: Vec<u8>, work: &Path, idx: usize) -> anyhow::Result<Vec<u8>> {\n    if super::jpeg_pdf::is_jpeg(&data) {\n        return Ok(data);\n    }\n    let ffmpeg = crate::core::dependencies::ensure_ffmpeg().await?;\n    let input = work.join(format!(\"{}.img\", idx));\n    let output = work.join(format!(\"{}.jpg\", idx));\n    tokio::fs::write(&input, &data).await?;\n    let o = crate::core::process::command(&ffmpeg)\n        .args([\"-y\", \"-hide_banner\", \"-loglevel\", \"error\", \"-i\"])\n        .arg(&input)\n        .args([\"-q:v\", \"2\"])\n        .arg(&output)\n        .output()\n        .await?;\n    if !o.status.success() {\n        return Err(anyhow!(\"ffmpeg nao converteu a imagem {}\", idx));\n    }\n    Ok(tokio::fs::read(&output).await?)\n}\n\npub async fn download(\n    url: &str,\n    dest_dir: &str,\n    progress: super::ProgressFn,\n) -> anyhow::Result<SlidesResult> {\n    if !url.contains(\"slideshare.net\") {\n        return Err(anyhow!(\"cole um link do slideshare.net\"));\n    }\n    let client = super::client()?;\n    let html = client\n        .get(url)\n        .send()\n        .await?\n        .error_for_status()?","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/slides.rs#L59-L95","documentation":"ensure_jpeg converts a downloaded image (any format) to JPEG using ffmpeg at quality -q:v 2. If the conversion process exits non-zero, it throws 'ffmpeg nao converteu a imagem {idx}' (ffmpeg did not convert image idx), including the image index. This indicates ffmpeg could not decode the input image or write the JPEG output.","triggerScenarios":"Calling download() with a slide image whose format ffmpeg can't decode (corrupt download, HTML error page saved as image, unsupported/proprietary format), or an output path that can't be written.","commonSituations":"Remote URL returns an error page or rate-limits and the body is fed to ffmpeg; SVG/HEIC input without decoder support; zero-byte or truncated downloads; disk full.","solutions":["Validate the downloaded bytes are actually an image (content-type/magic bytes) before conversion.","Log ffmpeg stderr around the call to see the exact decode failure.","Add a pre-check on Content-Type and reject non-image responses before calling ensure_jpeg.","Ensure ffmpeg has decoders for the source format, or convert via an alternative tool (e.g. ImageMagick)."],"exampleFix":"// before\nlet bytes = http_get(url).await?;\nensure_jpeg(&bytes_path, idx).await?;\n// after\nlet resp = http_get(url).await?;\nanyhow::ensure!(\n    resp.content_type().starts_with(\"image/\"),\n    \"URL nao retornou uma imagem\"\n);\nensure_jpeg(&bytes_path, idx).await?;","handlingStrategy":"validation","validationCode":"// Rust\nasync fn looks_like_image(bytes: &[u8]) -> bool {\n    bytes.starts_with(b\"\\xFF\\xD8\") // jpeg\n        || bytes.starts_with(b\"\\x89PNG\")\n        || bytes.starts_with(b\"GIF8\")\n}","typeGuard":"fn is_image_response(ct: &str) -> bool { ct.starts_with(\"image/\") }","tryCatchPattern":"match ensure_jpeg(&input, idx).await {\n    Err(e) if e.to_string().contains(\"nao converteu a imagem\") => {\n        eprintln!(\"imagem {idx} invalida ou formato sem decoder\");\n    }\n    r => r?,\n}","preventionTips":["Validate Content-Type and magic bytes before feeding downloads to ffmpeg","Handle HTTP error pages/rate limits before treating the body as an image","Ensure ffmpeg has decoders for expected formats (avoid SVG/HEIC without support)","Check for zero-byte/truncated downloads before conversion"],"tags":["ffmpeg","image-conversion","http","rust"],"backgroundTag":"unexpected-response-shape","analyzedSha":"8600b91f4246848bac346874daa9e61c1fc5677a","analyzedAt":"2026-09-12T14:29:19.317Z","contentChangedAt":"2026-09-12T14:29:19.317Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}