Skip to content
/ dnt-yt Public

DNT-YT is a lightweight YouTube caching + offline browsing API.

License

Notifications You must be signed in to change notification settings

gnh1201/dnt-yt

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DNT-YT

Discord chat

DNT-YT (Do-Not-Track YouTube) is a lightweight YouTube caching + offline browsing API.

DNT-YT structure overview

Inspired by Piped and Invidious. However, their goals and typical use-cases differ from what I need, so I created DNT-YT.

DNT-YT prioritizes offline YouTube video exploration above everything else. In fact, this is the only purpose of the source code in this repository.

What it does

  • Accepts various YouTube URL formats (or a raw video_id)

  • Automatically requests caching when missing

  • Stores cached media (video/audio, thumbnail and subtitles) and serves them as browser-playable URLs

  • Serves an HTML watch page that:

    • polls cache status every 5 seconds when not ready
    • auto-plays video (muted) once ready
    • uses a Mute/Unmute toggle as the user gesture to enable audio
    • keeps A/V synchronized in the browser (no FFmpeg)
    • supports thumbnails and multilingual subtitles

Architecture

  • API: FastAPI
  • Queue: RQ
  • Storage/State: Redis (jobs/status) + local media volume
  • Downloader: yt-dlp (caching audio/video separately; no FFmpeg required)

Endpoints

Watch (HTML)

These routes render the HTML player page. If the cache is missing, the server should enqueue a caching job automatically, then the page waits/polls until the cache becomes ready.

1) Root /<video_id>

/wLp_c3M-nPA

2) Path-based watch

/watch/wLp_c3M-nPA

3) Query v=<video_id> (YouTube-like)

/watch?v=wLp_c3M-nPA

4) Query url=<full-youtube-url>

/watch?url=https://www.youtube.com/watch?v=wLp_c3M-nPA

API (JSON)

Request caching / play intent

Queues a cache job if missing.

GET /v1/yt/play?url=<youtube_url>

Example:

curl "http://localhost:58000/v1/yt/play?url=https://www.youtube.com/watch?v=wLp_c3M-nPA"

Typical response:

{
  "ok": true,
  "ready": false,
  "video_id": "wLp_c3M-nPA",
  "job_id": "..."
}

Cache status

Returns whether cache is ready and (when ready) URLs for cached media.

GET /v1/yt/status?video_id=<video_id>

Example:

curl "http://localhost:58000/v1/yt/status?video_id=wLp_c3M-nPA"

Typical response:

{
  "ok": true,
  "ready": true,
  "video_id": "wLp_c3M-nPA",
  "video_url": "/media/wLp_c3M-nPA/video",
  "audio_url": "/media/wLp_c3M-nPA/audio",
}

Media (cached files)

These URLs are browser-playable once caching completes.

GET /media/<video_id>/video
GET /media/<video_id>/audio
GET /media/<video_id>/thumbnail  # thumbnail image
GET /media/<video_id>/subtitles  # the list of all subtitles
GET /media/<video_id>/subtitles/<lang>  # subtitles (vtt format)

Example:

/media/wLp_c3M-nPA/video
/media/wLp_c3M-nPA/audio
/media/wLp_c3M-nPA/thumbnail  # thumbnail image
/media/wLp_c3M-nPA/subtitles  # the list of all subtitles
/media/wLp_c3M-nPA/subtitles/en  # subtitles (vtt format)

Content negotiation (HTML vs JSON)

DNT-YT can decide response format based on request headers. Typical behavior:

  • If the client requests text/html, return the watch page
  • If the client requests application/json, return JSON (status or play response)
  • (Optional) oEmbed / OpenGraph can be added for social previews

Playback model (no FFmpeg)

DNT-YT downloads audio and video separately using yt-dlp and serves them as separate files.

The watch page:

  • starts video playback automatically (usually requires muted for autoplay)
  • uses a Mute/Unmute toggle button as the explicit user action to enable audio reliably
  • keeps audio aligned to video time (periodic drift correction and seek sync)

This avoids any server-side muxing/merging and therefore avoids FFmpeg.

Dependencies

  • yt-dlp (required)
  • Redis
  • FastAPI / Uvicorn
  • RQ

Quick start (Docker)

Typical:

docker compose up --build

Then open:

  • Watch page: http://localhost:58000/wLp_c3M-nPA
  • API: http://localhost:58000/v1/yt/play?url=...

Goals / non-goals

Goals

  • Offline-first YouTube exploration
  • Simple caching API
  • Browser-playable cached URLs
  • Minimal server-side processing (no FFmpeg)

Non-goals

  • Full UI like a Piped or Invidious
  • Account features / subscriptions / comments
  • Complex transcoding pipelines

CDN Cache Rules

For scenarios where a CDN is used for long-distance data transfer, it is recommended to configure appropriate cache rules to reduce bandwidth usage and improve performance.

The following example shows a cache rule configuration based on Cloudflare:

(http.request.full_uri wildcard r"https://domain.tld/media/*/video")
or
(http.request.full_uri wildcard r"https://domain.tld/media/*/audio")
or
(http.request.full_uri wildcard r"https://domain.tld/media/*/thumbnail")

Use cases

Screenshots

DNT-YT screenshot

My test videos

Disclaimer

This software is licensed under the GNU General Public License v3.0 and is provided without any warranty, to the extent permitted by applicable law. See the GPL v3.0 license for details.

The authors and contributors shall not be held liable for any damages arising from the use of this software. Any illegal or unauthorized use is solely the responsibility of the user, who must ensure compliance with all applicable laws and regulations.

Join the community

I am always open. Collaboration, opportunities, and community activities are all welcome.