tonhowtf/omniget · error · anyhow

cole a URL de um .m3u8 ou .mpd

Error message

cole a URL de um .m3u8 ou .mpd

What it means

manifest_dl::download validates that the provided URL looks like an HLS (.m3u8) or DASH (.mpd) manifest before invoking ffmpeg. The check requires the URL to contain '.m3u8' or '.mpd' OR start with 'http'; anything else is rejected as invalid input.

Solutions

  1. Paste the direct .m3u8 or .mpd manifest URL (from the network tab of devtools), not the page URL
  2. Ensure opts.url starts with http(s) and points at the manifest, not an HTML page
  3. Trim whitespace/control characters from the pasted URL before calling
  4. If the manifest is behind an auth flow, copy the exact manifest request URL from the browser network panel

Example fix

// before
let opts = ManifestOptions { url: "https://example.com/player/watch/123".into(), .. };
// after
let opts = ManifestOptions { url: "https://example.com/hls/stream/index.m3u8".into(), .. };
Defensive patterns

Strategy: validation

Validate before calling

let url = opts.url.trim();
if !(url.starts_with("http") && (url.contains(".m3u8") || url.contains(".mpd"))) {
    return Err("URL must be a direct .m3u8 or .mpd manifest");
}

Type guard

fn is_manifest_url(u: &str) -> bool {
    let u = u.trim();
    u.starts_with("http") && (u.contains(".m3u8") || u.contains(".mpd"))
}

Try / catch

if !is_manifest_url(&opts.url) {
    // ask user for the direct manifest URL (devtools -> network -> .m3u8/.mpd)
    return;
}
download(&opts, &progress).await?;

Prevention

When it happens

Trigger: Calling download with opts.url empty, a bare filename, a local path, or an http(s) URL lacking .m3u8/.mpd — note the logic: any URL starting with 'http' passes even without an extension, so the error fires mainly for non-http inputs or empty strings.

Common situations: User pasted a webpage URL instead of the manifest URL (e.g. a player page); frontend passed an empty string; user pasted a blob: or file: URL; copied a base-only stream link without the manifest path.

Understand the failure class

Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/b1478a44f403a073. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/manifest_dl.rs:62

            h.push(e.trim().to_string());
        }
    }
    if h.is_empty() {
        None
    } else {
        Some(h.join("\r\n") + "\r\n")
    }
}

pub async fn download(
    opts: ManifestOptions,
    progress: super::ProgressFn,
) -> anyhow::Result<ManifestResult> {
    use tokio::io::{AsyncBufReadExt, BufReader};
    let ffmpeg = crate::core::dependencies::ensure_ffmpeg().await?;
    let url = opts.url.trim().to_string();
    if !(url.contains(".m3u8") || url.contains(".mpd") || url.starts_with("http")) {
        return Err(anyhow!("cole a URL de um .m3u8 ou .mpd"));
    }
    std::fs::create_dir_all(&opts.dest_dir)?;
    let mut name = super::sanitize_name(opts.file_name.trim());
    if !name.to_lowercase().ends_with(".mp4") && !name.to_lowercase().ends_with(".mkv") {
        name.push_str(".mp4");
    }
    let out = PathBuf::from(&opts.dest_dir).join(name);
    let mut cmd = crate::core::process::command(&ffmpeg);
    cmd.args([
        "-y",
        "-hide_banner",
        "-loglevel",
        "error",
        "-nostats",
        "-progress",
        "pipe:1",
    ]);
    if !opts.user_agent.trim().is_empty() {

View on GitHub (pinned to 8600b91f42)