{"record":{"id":"dfbf6792763a5ead","repo":"tonhowtf/omniget","slug":"ffmpeg-publish","errorCode":null,"errorMessage":"ffmpeg: {}","messagePattern":"ffmpeg: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src-tauri/omniget-core/src/core/tools/instagram/publish.rs","lineNumber":103,"sourceCode":"async fn as_jpeg(path: &Path) -> anyhow::Result<(Vec<u8>, u32, u32)> {\n    let bytes = tokio::fs::read(path).await?;\n    if let Some((w, h)) = jpeg_dimensions(&bytes) {\n        return Ok((bytes, w, h));\n    }\n    let ffmpeg = crate::core::dependencies::ensure_ffmpeg().await?;\n    let out = super::super::temp_dir().join(format!(\"ig-{}.jpg\", upload_id()));\n    let status = crate::core::process::command(&ffmpeg)\n        .args([\"-y\", \"-hide_banner\", \"-loglevel\", \"error\", \"-i\"])\n        .arg(path)\n        .args([\"-q:v\", \"2\", \"-pix_fmt\", \"yuvj420p\"])\n        .arg(&out)\n        .stdin(std::process::Stdio::null())\n        .stdout(std::process::Stdio::null())\n        .stderr(std::process::Stdio::piped())\n        .output()\n        .await?;\n    if !status.status.success() {\n        return Err(anyhow!(\n            \"ffmpeg: {}\",\n            String::from_utf8_lossy(&status.stderr).trim()\n        ));\n    }\n    let bytes = tokio::fs::read(&out).await?;\n    let _ = tokio::fs::remove_file(&out).await;\n    let (w, h) = jpeg_dimensions(&bytes)\n        .or_else(|| png_dimensions(&bytes))\n        .unwrap_or((1080, 1080));\n    Ok((bytes, w, h))\n}\n\nasync fn rupload_photo(\n    client: &IgClient,\n    bytes: Vec<u8>,\n    w: u32,\n    h: u32,\n    uid: &str,","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/tonhowtf/omniget/blob/8600b91f4246848bac346874daa9e61c1fc5677a/src-tauri/omniget-core/src/core/tools/instagram/publish.rs#L85-L121","documentation":"as_jpeg shells out to ffmpeg to convert an input media file to a JPEG frame; when the ffmpeg process exits with a non-zero status the captured stderr is wrapped into an anyhow error 'ffmpeg: <stderr>'. This indicates the conversion command itself failed.","triggerScenarios":"publish_web -> as_jpeg on a file that ffmpeg cannot decode: corrupt file, unsupported codec/container, wrong path/extension, or ffmpeg binary missing/incompatible arguments.","commonSituations":"Uploading a photo in an exotic format (HEIC with old ffmpeg, WEBP without libwebp), a zero-byte or truncated download, or a mismatched ffmpeg build lacking needed decoders.","solutions":["Run the same ffmpeg command manually to see the full stderr","Verify the input file is decodable (ffprobe it) and not corrupt/empty","Update/reinstall ffmpeg with the needed codecs (e.g. libheif for HEIC)","Convert the file to JPEG/PNG beforehand and pass a standard format"],"exampleFix":"// before\nErr(anyhow!(\"ffmpeg: {}\", String::from_utf8_lossy(&status.stderr).trim()))\n// after (include exit code and input path)\nErr(anyhow!(\"ffmpeg exited with {:?}: {}\", status.status.code(), String::from_utf8_lossy(&status.stderr).trim()))","handlingStrategy":"validation","validationCode":"let ok = tokio::process::Command::new(\"ffprobe\").args([\"-v\",\"error\",\"-select_streams\",\"v:0\",\"-show_entries\",\"stream=codec_name\",\"-of\",\"csv=p=0\", path]).output().await?.status.success();\nif !ok { return Err(anyhow!(\"input is not a decodable image/video\")); }","typeGuard":null,"tryCatchPattern":"match as_jpeg(path).await { Err(e) if e.to_string().starts_with(\"ffmpeg:\") => { eprintln!(\"conversion failed: {e}\"); fallback_to_original_format(path) }, r => r }","preventionTips":["Pre-convert user media to JPEG/PNG before publish","Ship/pin a full-featured ffmpeg build (libheif, libwebp)","Reject zero-byte or corrupt files early"],"tags":["ffmpeg","process","media-conversion","rust"],"backgroundTag":"http-request-failed","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"}