Files
stream-capture/spec/url_parsing.md
2025-12-02 10:29:39 -04:00

4.1 KiB

Feature Request: Advanced Playlist Parsing & Mix Handling

Context

We are upgrading the StreamCapture application. Currently, the app only supports parsing standard single video URLs. We need to implement robust support for Standard Playlists and YouTube Mixes (Radio), while solving performance issues and thumbnail loading errors.

Problem Statement

  1. Playlists (/playlist?list=...): Fails to parse entries or hangs because it attempts to resolve full metadata for every video. Thumbnails are missing.
  2. Mixes (/watch?v=...&list=RD...): Currently fails or behaves unpredictably.
  3. UI/UX: Users need a specific choice when encountering a "Mix" link:
    • Option A (Default): Treat it as a single video (ignore the list).
    • Option B: Parse the Mix as a playlist (limit to top 20 items).

Technical Requirements

1. Rust Backend Refactoring (src-tauri/src/ytdlp.rs)

Refactor the fetch_metadata command to use a unified, efficient parsing strategy.

A. Command Construction

For ALL metadata fetching, use the --flat-playlist flag to prevent deep extraction (which causes the hang).

Base Command:

yt-dlp --dump-single-json --flat-playlist --no-warnings [URL]

B. Handling Different URL Types

  1. Single Video:

    • yt-dlp returns a single JSON object with _type: "video" (or no type).
    • Action: Wrap it in a list of 1.
  2. Standard Playlist:

    • yt-dlp returns _type: "playlist" with an entries array.
    • Action: Map the entries to our Video struct.
  3. Mix / Radio (Infinite List):

    • Condition: If the frontend flags this request as a "Mix Playlist scan".
    • Modification: Add flag --playlist-end 20 to the command.
    • Reason: Mixes are infinite; we must cap them.

C. Data Normalization & Thumbnail Fallback

When using --flat-playlist, the entries often lack full thumbnail URLs or return webp formats that might not render immediately.

2. Frontend Logic (src/views/Home.vue & Stores)

A. URL Detection & User Choice

Before sending the URL to Rust, analyze the string:

  1. Regex Check: Detect if the URL contains both v= AND list= (typical for Mixes).

  2. New UI Element:

    • If a Mix link is detected, show a Checkbox or Toggle near the "Analyze" button.
    • Label: "Scan Playlist (Max 20)"
    • Default State: Unchecked (Off).
  3. Submission Logic:

    • If Unchecked (Default): Strip the &list=... parameter from the URL string before calling Rust. Treat it as a pure single video.
    • If Checked: Keep the full URL and pass a flag (e.g., is_mix: true) to the Rust backend (or handle the logic to request the top 20).

B. Displaying Results

  • Ensure the "Selection Area" can render a list of cards whether it contains 1 video or 20 videos.
  • If it's a playlist, show a "Select All" / "Deselect All" control.

Implementation Plan

Step 1: Rust Structs Update

Update the Serde structs in ytdlp.rs to handle the flat-playlist JSON structure.

// Example structure hint
struct YtDlpResponse {
    _type: Option<String>,
    entries: Option<Vec<VideoEntry>>,
    // ... fields for single video fallback
    id: Option<String>,
    title: Option<String>,
}

struct VideoEntry {
    id: String,
    title: String,
    duration: Option<f64>,
    thumbnail: Option<String>, // Might be missing
}

Step 2: Rust Logic Update

Modify command::fetch_metadata.

  • Accept an optional argument parse_mix_playlist: bool.
  • If true, append --playlist-end 20.
  • Implement the thumbnail fallback logic (if thumbnail is None, use i.ytimg.com).

Step 3: Frontend Update

  • Add the "Mix Detected" logic in Home.vue.
  • Add the toggle UI.
  • Update the analyze function to handle URL stripping vs. passing through based on the toggle.

Deliverables

Please rewrite the necessary parts of src-tauri/src/ytdlp.rs, src-tauri/src/commands.rs, and src/views/Home.vue to implement this logic.