Skip to content

machineonamission/dlPro

Repository files navigation

dlPro

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.

Get it

Get for Firefox Get for Edge

Rejected

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.

Download for Chrome

Above is also applicable to other Chromium browsers like Opera and Brave.

internal workings

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:
Loading

UML sequence diagram online

UML source

UML svg mirror