yt-dlp, the web's most powerful video and audio downloader, now embedded fully in your browser.
If you can name the site, dlPro can download from it! Download maximum quality audio and video from your favorite websites, with zero dependence on external servers.
Due to the nature of dlPro (being able to download content from sites that may not want you to), some web stores have rejected dlPro. Below is instructions for those browsers.
Above is also applicable to other Chromium browsers like Opera and Brave.
dlPro is a very complex program because of the intricacies of web content security policy. tldr different sections of the program (iframes, sandboxes, workers, wasm, etc) can do different things, and execution has to constantly pass between them to accomplish everything.
I created a full UML sequence diagram for those curious:
sequenceDiagram
title dlPro Event Sequence
actor user
create participant background
user->>background: user clicks extension icon
background->>content: spawns content
content->>background: requests cookies
note over content:creates area for iframe
create participant iframe
content->>iframe: creates iframe
note over iframe:inits primary UI
background->>content:sends cookies
content->>iframe:sends download url and cookies
create participant worker
iframe->>worker: spawns worker
iframe->>worker: sends cookies and dlurl
note over worker: fetches latest yt-dlp
create participant pyodide
worker->>pyodide:inits pyodide and libs
worker->>pyodide:runs yt-dlp
create participant yt-dlp
pyodide->>yt-dlp:inits and patches yt-dlp
pyodide->>yt-dlp:runs extract_info
note over yt-dlp:see http request section later
yt-dlp->>pyodide:returns info
pyodide->>worker:asks user for selection
worker->>iframe:forwards request
iframe->>user:presents UI to user
user->>iframe:makes format selection
iframe->>worker:sends user selection
worker->>pyodide:forwards
pyodide->>yt-dlp:runs yt-dlp downloader
note over yt-dlp:these sections aren't necessarily ran in this order, or at all
critical http_request Group ran whenever yt-dlp makes an http request
create participant pyodide_http_fork
yt-dlp->>pyodide_http_fork:monkey patched http request
alt request contains origin header
note over pyodide_http_fork: origin header can't be faked, must be sent from origin
pyodide_http_fork->>worker:proxy_fetch
worker->>content:forwards
note over content:normal xmlhttprequest
note over content:requests from here match page's origin
content->>worker:request result
worker->>pyodide_http_fork:forwards
else request does not contain origin header
alt browser supports atomics
note over pyodide_http_fork:stream request for better progress indicator
create participant streaming_worker
pyodide_http_fork->>streaming_worker:starts request
note over streaming_worker:fetch request
streaming_worker->>pyodide_http_fork:sends progress via atomics
destroy streaming_worker
streaming_worker->>pyodide_http_fork:sends success/error code
else browser doesn't support atomics
note over pyodide_http_fork:normal xmlhttprequest
end
end
destroy pyodide_http_fork
pyodide_http_fork->>yt-dlp:http result
end
critical JS_challenge ran when page needs advanced JS-based captcha solving
yt-dlp->>pyodide:hits registered JSC handler
pyodide->>worker:sends js
worker->>iframe:forwards
create participant sandbox
iframe->>sandbox:creates sandcritical to run arbitrary js
iframe->>sandbox:sends JS code (patched npm import calls)
sandbox->>iframe:sends result
destroy sandbox
iframe->>sandbox:removes
iframe->>worker:forwards
worker->>pyodide:forwards
pyodide->>yt-dlp:returns result
end
critical ffmpeg_ffprobe_call ran when media file needs processing
yt-dlp->>pyodide:monkey patched popen
pyodide-->>yt-dlp:hardcoded result for basic ffprobe capabilities
create participant ffmpegwasm
pyodide->>ffmpegwasm:spawns ffmpegwasm
pyodide->>ffmpegwasm:loads libs
pyodide->>ffmpegwasm:copies or moves files
pyodide->>ffmpegwasm:execute command
ffmpegwasm->>pyodide:stdout results
ffmpegwasm->>pyodide:command completed
ffmpegwasm->>pyodide:pyodide moves files
note over ffmpegwasm:ffmpeg worker is kept alive if needed again
destroy ffmpegwasm
ffmpegwasm -x ffmpegwasm: destroy
end
yt-dlp->>pyodide:postprocessor hook is called
pyodide->>worker:send_to_user
pyodide->>worker:worker moves files
worker->>iframe:copies files
iframe->>user:copies files
destroy yt-dlp
yt-dlp->>pyodide:execution finishes
destroy pyodide
worker->>pyodide:waits for files to finish sending
destroy worker
worker-xworker:
user->>content:requests dlpro close
destroy iframe
content->>iframe:removes iframe
note over content:execution finishes
destroy content
content--xcontent: