Skip to content

Repository files navigation

MediaDL



Version Β  Sites Β  PowerShell Β  License


Download videos and extract audio from YouTube, Facebook, Twitter/X, TikTok, Instagram, and 1800+ more.
Auto-detects media on any page. Floating download pills. Zero configuration.


3-tier failover Β Β·Β  hidden background server Β Β·Β  real-time progress Β Β·Β  7-layer Facebook extraction



Β Β πŸš€ Quick InstallΒ Β 
Β Β Β 
  ✨ Features  
Β Β Β 
  🌍 Sites  
Β Β Β 
Β Β πŸ—οΈ ArchitectureΒ Β 
Β Β Β 
Β Β πŸ”§ TroubleshootΒ Β 


πŸš€ Quick Install

One command. Everything configured. No manual setup.

irm https://raw.githubusercontent.com/SysAdminDoc/MediaDL/refs/heads/main/Install-MediaDL.ps1 | iex

Run in an elevated PowerShell window. The installer downloads yt-dlp, ffmpeg, registers protocol handlers, deploys the background download server, creates a Scheduled Task for auto-start, and installs the userscript.


🌍 Supported Sites

MediaDL has optimized detection for these platforms, including Instagram Reels, Stories, and Highlights, plus generic <video> detection for any site yt-dlp supports:

Platform Video Audio Platform Video Audio
▢️ YouTube βœ… βœ… πŸ”΅ Vimeo βœ… βœ…
πŸ“˜ Facebook βœ… βœ… πŸ”Š SoundCloud β€” βœ…
🐦 Twitter / X βœ… βœ… 🎸 Bandcamp β€” βœ…
🎡 TikTok βœ… βœ… πŸ“Ί Dailymotion βœ… βœ…
πŸ“· Instagram βœ… βœ… πŸ…±οΈ Bilibili βœ… βœ…
🟣 Twitch βœ… βœ… 🏴 Rumble / Odysee βœ… βœ…
πŸ”΄ Reddit βœ… βœ… 🍿 Crunchyroll / Nebula βœ… βœ…

+ Kick, Floatplane, Streamable, Imgur, Arte, Tagesschau, and 1800+ more via yt-dlp


✨ Features

🌐 MediaDL Userscript

πŸ” Auto-Detect

Scans every page for video and audio elements. Attaches floating download pills automatically β€” no clicking required.

TikTok uses server-rendered play URLs first for watermark-free MP4, with wmplay/download fallback when only a watermarked stream is exposed.

X Spaces discovers live .m3u8 audio from resource timing and embedded playback data.

Live YouTube and Twitch players expose a REC action that starts a server-backed recording from the current live edge.

πŸ›‘οΈ 3-Tier Failover

HTTP server β†’ protocol handler β†’ GM_download. If one method fails, the next activates seamlessly.

Video pills include a click-or-hold quality picker for Best, 720p, 1080p, and 4K. The server also applies editable per-host presets for format, quality, codec, and audio fallback.

Playlist and channel URLs are handled as collection downloads with one queue item, playlist-aware folders, the configured rate limit, and the download archive for resume-safe retries. API clients can force this behavior with channelMode: true in the /download body.

⚑ Background Server

Lightweight HTTP server on 127.0.0.1:9751. Concurrent downloads, progress tracking, queue management. Starts on login.

Queue requests and interrupted states persist in a SQLite WAL journal at %LOCALAPPDATA%\MediaDL\queue.db. The settings panel also exposes a bandwidth slider and per-site concurrency cap to keep busy hosts fair. Open http://127.0.0.1:9751/ui for the local queue viewer, where drag handles persist priority order and active downloads can be paused, resumed, or cancelled. Optional post-processing extracts MP3 audio, looks up MusicBrainz tags, and moves the result into the configured Music folder. The server can also show an opt-in native Windows toast after each download completes.

πŸ”‘ Zero-Config Auth

Server token negotiated automatically via X-MDL-Client header handshake. No manual setup.

πŸ“Š Progress Toasts

In-page progress bars with download speed and ETA. Appear at the bottom-right of the browser window.

πŸ”„ SPA Compatible

MutationObserver + URL change detection handles single-page navigation on YouTube, Facebook, Twitter, and all modern SPAs.

πŸ–₯️ Download Handler

🧡 Async UI

Title and thumbnail fetched in background jobs. The progress popup renders instantly and never freezes.

🎯 Duplicate Prevention

Content identity lock (site + video ID + channel when available) prevents equivalent page/CDN URLs from being queued twice; a scoped URL hash remains the fallback for sites without stable IDs.

πŸ“ˆ Smooth Progress

Animated bar with eased interpolation. Reads only last 4KB via FileStream.Seek.

πŸ”ͺ Cancel Kills All

Cancelling kills both the PowerShell wrapper and child yt-dlp.exe / ffmpeg.exe via CIM process lookup.

πŸ–ΌοΈ Universal Thumbnails

YouTube via direct API. All other sites via yt-dlp --get-thumbnail. Both non-blocking.

βœ‚οΈ Chapter Splitting

Enable chapter splitting in the server settings to emit one file per YouTube Chapters: section while preserving embedded chapter markers.

🎡 Music Post-Processing

Enable the opt-in post-processing switches to extract audio after a video completes, tag it through MusicBrainz, and move it to a collision-safe Music folder filename.

πŸŽ›οΈ Format Control

Configure host presets in the server settings JSON. The built-in examples request 1080p AV1 MP4 for YouTube, best MP4 for X/Twitter, and FLAC with an MP3 retry for SoundCloud.

Subtitle control can optionally download manual and automatic captions as SRT and mux them into an MKV output.

Hardware transcode is opt-in in the same settings panel: choose NVENC or QSV to re-encode completed video with FFmpeg while copying audio, subtitle, and data streams unchanged.

πŸ“‚ Open on Complete

Click "Complete!" to open Explorer with the downloaded file pre-selected.

πŸͺŸ Win11 Native

DWM rounded corners via DwmSetWindowAttribute. Degrades gracefully on Windows 10.

πŸ”„ Verified Dependency Updates

The background server checks yt-dlp and ffmpeg once per day, downloads only the expected GitHub release assets, and replaces them only after their SHA-256 release digests match. Missing digests or unexpected download origins fail closed and leave the installed tools untouched.

Completion toasts are opt-in and fail safely when WinRT toast registration is unavailable.

πŸ›‘ Crash-Proof

4-layer exception handling: closing flag, nuclear try/catch, control guards, and global Application.ThreadException.

🌍 Browser Variants

The extension/ directory contains unsigned MV3 packages for Chrome and Firefox, plus an Edge package with a native side-panel queue viewer. Run node extension/build.mjs after changing MediaDL.user.js to regenerate the shared content/background adapters. Firefox AMO submission/signing is intentionally not performed; load the unsigned package as a development extension.

MediaDL.mobile.user.js is the lightweight Kiwi Browser/Orion variant. It contains no Windows paths, local protocol, or PowerShell assumptions and downloads direct MP4/audio URLs; page-managed blobs and HLS playlists are reported as desktop-only limitations.


πŸ“Έ Screenshots

Installer Wizard


Installer - Welcome

Installer - Config

Installer - Complete


πŸ—οΈ Architecture

 β”Œβ”€ Browser ───────────────────────┐    β”Œβ”€ Windows ──────────────────────────┐
 β”‚                                 β”‚    β”‚                                    β”‚
 β”‚  MediaDL Userscript             β”‚    β”‚  β”Œβ”€ Tier 1: Download Server ────┐  β”‚
 β”‚  β”œβ”€ Auto-detect <video>         β”‚HTTPβ”‚  β”‚  ytdl-server.ps1              β”‚  β”‚
 β”‚  β”œβ”€ Floating download pills     │◀──▢│  β”‚  127.0.0.1:9751              β”‚  β”‚
 β”‚  β”œβ”€ Facebook 7-layer extraction β”‚    β”‚  β”‚  β”œβ”€ Concurrent downloads (3x) β”‚  β”‚
 β”‚  β”œβ”€ In-page progress toasts     β”‚    β”‚  β”‚  β”œβ”€ Real-time progress        β”‚  β”‚
 β”‚  └─ SPA navigation handling     β”‚    β”‚  β”‚  └─ Auto-start on login      β”‚  β”‚
 β”‚                                 β”‚    β”‚  └───────────────────────────────  β”‚
 β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   ytdl://   β”‚                                    β”‚
 β”‚         β”‚ Click pill    │────────▢│  β”Œβ”€ Tier 2: Protocol Handler ────┐  β”‚
 β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚    β”‚  β”‚  ytdl-handler.ps1            β”‚  β”‚
 β”‚                                 β”‚    β”‚  β”‚  β”œβ”€ Progress popup           β”‚  β”‚
 β”‚         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   GM_dlβ”‚    β”‚  β”‚  β”œβ”€ Thumbnail + title        β”‚  β”‚
 β”‚         β”‚ CDN direct    │───────▢│  β”‚  └─ Auto-retry (3x)           β”‚  β”‚
 β”‚         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜        β”‚    β”‚  └──────────────────────────────  β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                      β”‚
                                          Scheduled Task: MediaDL-Server
                                          (auto-start on login, hidden)
Tier Method How Progress Activates When
1 HTTP Server GM_xmlhttpRequest to 127.0.0.1:9751 βœ… Real-time polling Server is running (default)
2 Protocol Handler ytdl:// URL triggers ytdl-handler.ps1 βœ… Popup window Server is offline
3 Browser Direct GM_download for CDN URLs ❌ None Both 1 & 2 fail, URL is direct CDN

πŸ”¬ Facebook 7-Layer Extraction


Facebook aggressively obfuscates video URLs. MediaDL defeats this with seven extraction layers tried in priority order:

# Layer Technique
1 XHR/Fetch Intercept Hooks window.fetch and XMLHttpRequest at document-start to capture playable_url_quality_hd from GraphQL responses
2 Performance Resource Timing Scans performance.getEntriesByType('resource') for fbcdn.net video entries, sorted by transfer size
3 React Fiber Tree Walk Traverses __reactFiber from the <video> element upward through memoizedProps searching for browser_native_hd_url
4 Embedded JSON Scrape Searches <script type="application/json"> blocks for HD video URL patterns
5 DOM Permalink Walk Climbs the DOM tree from the video element to find a /videos/, /watch/, or /reel/ link
6 Page URL Candidate Keeps the current Facebook video/reel/story URL as a fallback candidate
7 MQTT / GraphQL WebSocket Hooks page-context WebSocket frames and extracts HD URLs from text, JSON, Blob, and ArrayBuffer payloads

πŸ”Œ Server API Reference


The download server runs on 127.0.0.1:9751 (localhost only, not exposed to network).

Method Endpoint Auth Response
GET /health β€” Server status. Returns auth token when X-MDL-Client: MediaDL header is present
GET /ui β€” Local queue viewer with drag handles and download controls
GET /plugins πŸ” Loaded extractor plugin names, versions, and directory
POST /download πŸ” Start download. Body: {url, title, audioOnly, referer, format, quality, channelMode}. Returns {id}
GET /status/:id πŸ” {status, progress, speed, eta, filename}
GET /queue πŸ” Priority-ordered array of downloads with status and site
POST /queue/reorder πŸ” Persist priority order. Body: {ids: [...]}
POST /pause/:id πŸ” Suspend a download process tree
POST /resume/:id πŸ” Resume a paused download
DELETE /cancel/:id πŸ” Cancel and clean up a download
GET /shutdown πŸ” Gracefully stop the server

πŸ” = Requires X-Auth-Token header (auto-negotiated by the userscript)

The same local control surface is available on the \\.\pipe\MediaDL named pipe to avoid TCP port collisions. Send one newline-delimited JSON request such as {"method":"GET","path":"/health","headers":{"X-MDL-Client":"MediaDL"}}; the response is {"status":200,"body":...}. Pipe requests support health, download, status, queue, pause, resume, cancel, and shutdown operations and use the same auth token.

🧩 Extractor Plugins


Drop a trusted .ps1 file in %LOCALAPPDATA%\MediaDL\plugins. It registers a handler with Register-MediaDLPlugin; CanHandle receives the original page URL and Extract returns an absolute media URL plus optional metadata. Plugins are loaded at server start, limited to 256 KiB each, and can be inspected through the authenticated /plugins endpoint.

Register-MediaDLPlugin -Name 'ExampleCdn' -Version '1.0' `
    -CanHandle { param($url) $url -match '^https://example\.com/video/' } `
    -Extract {
        param($url, $context)
        @{ url = $url -replace '/video/', '/media/'; title = $context.title }
    }

The server passes the resolved URL through the normal queue, duplicate, format, subtitle, post-processing, and notification paths. Plugin scripts are local code and therefore run with the server user's permissions.


πŸ“‚ Project Files

File Description
Install-MediaDL.ps1 PowerShell WPF installer wizard (dark-themed GUI)
MediaDL.user.js Userscript β€” auto-detect on all websites
ytdl-server.ps1 Hidden HTTP download server (127.0.0.1:9751)
ytdl-handler.ps1 Protocol handler with async progress popup
ytdl-server-launcher.vbs Windowless server launcher
ytdl-launcher.vbs Silent handler launcher
config.json Paths, server port/token, preferences
%LOCALAPPDATA%\MediaDL\plugins\*.ps1 Optional trusted extractor plugins

πŸ’» Installation

Option 1 β€” Automatic Installer (recommended)

# Open PowerShell as Administrator, then run:
irm https://raw.githubusercontent.com/SysAdminDoc/MediaDL/refs/heads/main/Install-MediaDL.ps1 | iex

The installer creates a MediaDL-Server Scheduled Task that auto-starts the background server on login. No console windows will appear.

Option 2 β€” Manual Installation

  1. Install Tampermonkey or Violentmonkey
  2. Install the userscript:
  3. Install yt-dlp and ffmpeg
  4. Set up protocol handlers manually (see below)
Protocol Handler Registry Entry
Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\ytdl]
@="URL:YTDL Protocol"
"URL Protocol"=""

[HKEY_CLASSES_ROOT\ytdl\shell\open\command]
@="wscript.exe \"C:\\Path\\To\\ytdl-launcher.vbs\" \"%1\""

πŸ“‹ Requirements

πŸ€– Automatic (recommended)

The installer handles everything:

Component Status
βœ… yt-dlp Auto-downloaded
βœ… ffmpeg Auto-downloaded
βœ… Protocol handler Auto-registered
βœ… Download server Auto-deployed
βœ… Scheduled Task Auto-created

πŸ”§ Manual

If installing without the wizard:

Component Link
πŸ“Œ Userscript manager Tampermonkey
πŸ“Œ yt-dlp GitHub
πŸ“Œ ffmpeg ffmpeg.org

πŸ”§ Troubleshooting

Issue Solution
Download pills don't appear Refresh the page. Verify userscript is enabled with @match *://*/*
Server not running Check Task Scheduler for MediaDL-Server, or run ytdl-server-launcher.vbs manually
Facebook downloads fail Click the video to trigger playback first (populates CDN URLs for extraction)
Download fails silently Verify yt-dlp and ffmpeg are installed and paths are correct in config.json
JIT debugging dialog Update to the latest handler (4-layer crash prevention)
Duplicate downloads Update to the latest handler (content identity lock with URL fallback)

πŸ—‘οΈ Uninstalling

Run the installer again β€” it auto-removes the previous installation before reinstalling.

For full manual removal:

  1. Task Scheduler β†’ Delete the MediaDL-Server task
  2. Delete %LOCALAPPDATA%\MediaDL
  3. Registry β†’ Remove HKCU:\Software\Classes\ytdl
  4. Browser β†’ Remove the userscript from Tampermonkey

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“„ License

This project is licensed under the MIT License β€” see the LICENSE file for details.



Built With


yt-dlp Β Β  ffmpeg Β Β  PowerShell




Β Β πŸ› Report IssuesΒ Β 
Β Β Β Β 
  ⭐ Star on GitHub  
Β Β Β Β 
Β Β πŸ‘€ SysAdminDocΒ Β 


Made with ❀️ by SysAdminDoc


About

Universal media downloader (userscript + PowerShell backend) with auto-detection on 1800+ websites, floating download buttons, 3-tier failover architecture, and 6-layer Facebook extraction.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages