YTPTube

repository·dev·Indexed 21 days ago

https://github.com/arabcoders/ytptube

A web-based graphical user interface for yt-dlp designed to simplify downloading videos, playlists, and live streams. YTPTube features concurrent downloads support, scheduled tasks, custom download feeds, and integration with Apprise for notifications. It includes a dual-view UI (Technical vs. Simple), multi-language support, and a built-in video player. The project provides a comprehensive HTTP and WebSocket API for managing downloads, history, and system configuration.

Tokens
20.2K
Snippets
64
Records
95
Agent score
75%

What's inside ytptube

  1. Overview of YTPTube features

    dev

    YTPTube is a web-based GUI for yt-dlp that facilitates downloading videos, playlists, channels, and live streams.

    Key Capabilities:

    • Automation: Schedule downloads for channels/playlists and create custom download feeds from non-supported sites.
    • Notifications: Integration with Apprise to send notifications based on events.
    • Advanced yt-dlp Support: Powerful presets system, support for curl-cffi (Docker only), and bundled pot provider plugin (Docker only).
    • Bypassing Protections: Support for FlareSolverr or Trawl to bypass Cloudflare.
    • UI Modes: Dual view mode (Technical vs. Simple) and multi-language support (English, العربية, Français, 中文, 日本語).
    • Media Playback: Built-in video player with sidecar external subtitle support (requires ffmpeg in PATH for non-Docker setups).
  2. Overview of YTPTube HTTP API

    dev

    The YTPTube HTTP API provides endpoints for managing downloads, history, tasks, system configuration, and media playback.

    Key Characteristics:

    • Response Format: All endpoints return JSON responses unless specified otherwise.
    • Media Content: Some endpoints serve static or streaming content such as .ts, .m3u8, and .vtt files.
    • Status Codes: The API uses standard HTTP status codes to communicate success or error conditions.
  3. How download conditions work

    dev

    Download conditions allow you to automate download behavior based on specific criteria.

    Key Concepts:

    • Priority: Conditions are evaluated in priority order. Higher priority values are evaluated first. The default priority is 0.
    • Automation via extras:
      • extras.set_preset: Can automatically select an existing preset when the condition matches.
      • extras.set_cookies: Can override the active preset with Netscape-format cookie file contents.
    • Evaluation: When a condition's filter matches, its associated cli arguments or extras are applied to the download process.

    Endpoints:

    • GET /api/conditions/: List conditions with pagination.
    • POST /api/conditions/: Create a new condition.
  4. Understand error parameter conventions for i18n

    dev

    When implementing internationalization (i18n), the params object in error responses contains keys following specific namespaces. Clients should resolve these namespaces to localized strings before interpolating them into the error templates.

    Namespace Conventions:

    • api.resources.* (e.g., api.resources.preset, api.resources.task, api.resources.file, api.resources.item)
    • api.fields.* (e.g., api.fields.url, api.fields.name, api.fields.ids, api.fields.args)
    • api.features.* (e.g., api.features.console, api.features.monitoring, api.features.fileLogging)

    Best Practice: Use the error field as a fallback for non-i18n clients, but prioritize resolving the params values for localized user experiences.

  5. WebSocket Message Format

    dev

    All WebSocket messages (both Client $\rightarrow$ Server and Server $\rightarrow$ Client) follow a standard JSON structure containing an event string and a data payload.

    Structure:

    {
      "event": "event_name",
      "data": { /* payload */ }
    }
  6. Monitor sites without RSS using Generic Task Handlers

    dev

    YTPTube can automatically scrape pages and enqueue new links using a generic task handler. This works by turning JSON definitions into site-specific scrapers.

    Workflow

    1. Create a Definition: In the WebUI, go to tasks > Definitions and create a JSON definition.
    2. Create a Task: Create a task referencing the target URL. Ensure the task uses a preset with --download-archive enabled to avoid duplicates.
    3. Execution: The handler scans definitions, matches the task URL against match_url (supports Glob and Regex), fetches the page, and extracts items.

    Definition Schema

    Each definition is a JSON object. Key fields include:

    • name: Identifier for logs.
    • match_url: List of Glob or Regex strings to match task URLs.
    • engine: The fetch engine (httpx default, or selenium for remote Chrome sessions).
    • request: HTTP settings (method, url, headers, params, data, json_data, timeout).
    • response: The response format (html default, or json).
    • parse: Extraction logic.
      • items: Container for per-item extraction. Requires a selector (CSS or XPath) and fields.
      • fields: Mapping of keys to extraction rules. Each field requires a type (css, xpath, or jsonpath), an expression, and an attribute (e.g., text, html, href).

    Parsing Rules

    • Link Requirement: Every definition must provide a link field (either at the top level or inside parse.items.fields).
    • Attributes:
      • text / inner_text: Applies normalize-space().
      • html / outer_html: Returns raw HTML fragment.
      • For link fields, if attribute is omitted, it defaults to href.
    • JSON Responses: If response.type is json, set type and field type to jsonpath and use JMESPath expressions.

    Fetch Engines

    • httpx: Default. Supports custom headers, params, JSON payloads, and proxies.
    • selenium: Requires a remote Chrome session. Provide the hub URL in engine.options.url. Supports arguments, wait_for (CSS/XPath), wait_timeout, and page_load_timeout.
    {
      "name": "example",
      "match_url": ["https://example.com/articles/*"],
      "engine": { "type": "httpx" },
      "request": { "method": "GET", "url": "https://example.com/articles/latest" },
      "response": { "type": "html" },
      "parse": {
        "items": {
          "selector": ".columns .card",
          "fields": {
            "link": { "type": "css", "expression": ".card-header a", "attribute": "href" },
            "title": { "type": "css", "expression": ".card-header a", "attribute": "text" }
          }
        }
      }
    }
  7. Connect to the WebSocket API

    dev

    The WebSocket API provides real-time bidirectional communication for download queue management and status updates.

    Connection Details:

    • Endpoint: /ws (or {base_path}/ws if a base path is configured).
    • Protocol: ws:// or wss://.
    • Heartbeat: 10-second interval.
    • Auto-reconnect: Clients are responsible for implementing reconnection logic.

    Authentication: If YTP_AUTH_USERNAME and YTP_AUTH_PASSWORD are set, authenticate via:

    1. Query Parameter (Recommended): ws://localhost:8080/ws?apikey=<base64_urlsafe_credentials>
    2. HTTP Basic Auth: Include Authorization: Basic base64("<username>:<password>") during the handshake.
    const ws = new WebSocket('ws://localhost:8080/ws');
    ws.onopen = () => console.log('Connected');
    ws.onmessage = (event) => {
      const message = JSON.parse(event.data);
      console.log('Event:', message.event, 'Data:', message.data);
    };
  8. Prepare and stream ZIP downloads

    dev

    To download multiple files as a single ZIP archive, use a two-step process:

    1. Prepare: Call POST /api/file/download with a JSON array of relative file paths. This returns a short-lived token.
    2. Stream: Call GET /api/file/download/{token} using the returned token. This returns a streaming response with Content-Type: application/zip.

    Direct File Access: To serve a single file directly without zipping, use GET /api/download/{filename} where {filename} is the URL-encoded relative path.

    # 1. Prepare download
    POST /api/file/download
    # Body: ["path/to/file1.mp4", "path/to/file2.mp4"]
    # Response: { "token": "<uuid>", "files": [...] }
    
    # 2. Stream the ZIP
    GET /api/file/download/<uuid>
  9. Bypass Cloudflare challenges with FlareSolverr

    dev

    To bypass Cloudflare challenges, set up FlareSolverr or Trawl and point the YTP_FLARESOLVERR_URL environment variable to your instance.

    services:
      ytptube:
        # ...
        environment:
          - YTP_FLARESOLVERR_URL=http://flaresolverr:8191/v1
        depends_on:
          - flaresolverr
      flaresolverr:
        image: flaresolverr/flaresolverr:latest
        container_name: flaresolverr
        restart: unless-stopped    
  10. Download only a single video from a playlist link

    dev

    To prevent YTPTube from downloading an entire playlist when a link contains a playlist ID, create a preset in the WebUI. In the Command options for yt-dlp field of the preset, add the following flag:

    --no-playlist

    Select this preset whenever you are processing links that include playlist IDs.