diff --git a/EJS.md b/EJS.md new file mode 100644 index 0000000..0bc9541 --- /dev/null +++ b/EJS.md @@ -0,0 +1,179 @@ +# External JS Scripts Setup Guide + +To download from YouTube, yt-dlp needs to solve JavaScript challenges presented by YouTube using an external JavaScript runtime. + +This involves running challenge solver scripts maintained at [yt-dlp-ejs](https://github.com/yt-dlp/ejs). Depending on your yt-dlp installation method, you may need to set up and enable these components manually. + +This guide will help you set up and enable the necessary components based on your yt-dlp installation method. + +> [!NOTE] +> EJS replaces the prior JSInterp and PhantomJS based approach. For YouTube both are no longer used. PhantomJS is still being used for a few other extractors, but is planned to be deprecated in the near future. + +## Setup steps + +1. [Install a supported JavaScript runtime](#step-1-install-a-supported-javascript-runtime) +2. [Install EJS challenge solver scripts](#step-2-install-ejs-challenge-solver-scripts) + +## Step 1: Install a supported JavaScript Runtime + +| JS Runtime | Summary | +|---------------------------------|--------------------------------------| +| [Deno](#deno) (recommended) | Enabled by default. | +| [Node](#node) | Enable with `--js-runtimes node` | +| [Bun](#bun) | Enable with `--js-runtimes bun` | +| [QuickJS](#quickjs--quickjs-ng) | Enable with `--js-runtimes quickjs` | + + +### deno + +> [!TIP] +> Recommended + +https://deno.com + +#### Installation instructions + +Minimum supported version: `2.0.0` + +Download from https://docs.deno.com/runtime/getting_started/installation/ or from your package manager. + +When grabbing deno manually from the [Github release assets](https://github.com/denoland/deno/releases/latest) you will need to download `deno` and not `denort`. + +#### Enable + +Deno is enabled by default. To supply an optional path, use `--js-runtimes deno:/path/to/deno` + +#### Notes + +- Code is run with restricted permissions (e.g, no file system or network access) +- Supports downloading EJS script dependencies from [npm](https://www.npmjs.com/) (`--remote-components ejs:npm`). + +--- + +### node + +https://nodejs.org + +#### Installation instructions + +Minimum supported version: `20.0.0` + +Download from https://nodejs.org/en/download/ or from your package manager. + +#### Enable + +Enable with `--js-runtimes node` or `--js-runtimes node:/path/to/node`. + +It is recommended to add this to your [yt-dlp configuration file](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#configuration) to avoid needing to pass it every time. + +#### Notes + +- Runs code with [*some* permissions restricted](https://nodejs.org/api/permissions.html). + +--- +### bun + +https://bun.com + +#### Installation instructions + +Minimum supported version: `1.0.31` + +Download from https://bun.com/docs/installation or from your package manager. + +#### Enable + +Enable with `--js-runtimes bun` or `--js-runtimes bun:/path/to/bun`. + +It is recommended to add this to your [yt-dlp configuration file](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#configuration) to avoid needing to pass it every time. + + +#### Notes + +- No permission restrictions available. Scripts have full file system and network access. +- Supports downloading EJS script dependencies from [npm](https://www.npmjs.com/) (`--remote-components ejs:npm`). +- No support for SOCKS proxies when downloading EJS script dependencies from npm. + +--- +### QuickJS / QuickJS-NG + +https://bellard.org/quickjs/ / https://quickjs-ng.github.io/quickjs/ + +#### Installation instructions + +Minimum supported QuickJS version: `2023-12-9` + +All versions of QuickJS-NG are supported. + +Download from https://bellard.org/quickjs/ / https://quickjs-ng.github.io/quickjs/installation or from your package manager. + +#### Enable + +Enable with `--js-runtimes quickjs` or `--js-runtimes quickjs:/path/to/qjs`. + +It is recommended to add this to your [yt-dlp configuration file](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#configuration) to avoid needing to pass it every time. + + +#### Notes + +- QuickJS versions prior to `2025-4-26` are missing optimizations which can lead to execution times of several minutes. +- All QuickJS-NG versions are missing optimizations which can lead to execution times of several minutes. +- Both QuickJS and QuickJS-NG do not fully allow executing files from stdin, so yt-dlp will create temporary files for each EJS script execution. This can theoretically lead to time-of-check to time-of-use (TOCTOU) vulnerabilities. + + +## Step 2: Install EJS challenge solver scripts + +| yt-dlp distribution | EJS scripts installation options | +|--------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| Official PyInstaller-bundled executable (e.g. `yt-dlp.exe`, `yt-dlp_macos`, `yt-dlp_linux`, etc) | No additional action required. All the necessary JavaScript components will be bundled with these executables. | +| PyPI package (e.g. installed with pip, pipx, etc): | - [Install and upgrade yt-dlp with `default` dependency group](#option-1-install-the-yt-dlp-ejs-python-package)
- or [enable npm downloads](#option-2-enable-ejs-script-downloads-from-npm) ([deno](#deno)/[bun](#bun) only)
- or [enable GitHub downloads](#option-3-enable-ejs-script-downloads-from-github)
| +| Official zipimport binary (the `yt-dlp` Unix executable) | No additional action required. All the necessary JavaScript components will be bundled with these executables. | +| Third-party package users (e.g. installed with pacman, brew, etc) | The will depend on if your third-party package repository ships or bundles the EJS script package with yt-dlp.

If it does not (or it is out of date):
- [enable npm downloads](#option-2-enable-ejs-script-downloads-from-npm) ([deno](#deno)/[bun](#bun) only)
- or [enable GitHub downloads](#option-3-enable-ejs-script-downloads-from-github)
| + + +### Option 1: Install the yt-dlp-ejs python package + +yt-dlp ships a companion package, `yt-dlp-ejs`, which contains all the EJS scripts. + +If you installed yt-dlp using the PyPI package (e.g. with pip or pipx), install _and upgrade_ yt-dlp with the `default` dependency group: + +i.e. `pip install -U "yt-dlp[default]"` + +The default dependency group includes the `yt-dlp-ejs` package. + +Refer to https://github.com/yt-dlp/yt-dlp/wiki/Installation#with-pip for more details. + +Alternatively, if you only want to install the EJS package, you can install the `yt-dlp-ejs` package directly from PyPI. The version MUST match the version specified in yt-dlp's `pyproject.toml` for the version of yt-dlp you are using. + +> [!WARNING] +> This library SHOULD be updated alongside yt-dlp to avoid running an outdated version. The version MUST be a supported version as per yt-dlp's pyproject.toml file. yt-dlp may bump the minimum version on updates without warning, and old versions will be ignored by yt-dlp. + +### Option 2: Enable EJS script downloads from npm + +> [!IMPORTANT] +> This option only works with Deno and Bun runtimes, which support downloading npm packages on-the-fly. + +To enable this, supply `--remote-components ejs:npm` to yt-dlp. It is recommended to add this to your [yt-dlp configuration file](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#configuration) to avoid needing to pass it every time and allow automatic updates. + +### Option 3: Enable EJS script downloads from GitHub + +yt-dlp can automatically download the EJS scripts directly from GitHub (https://github.com/yt-dlp/ejs). + +To enable this, supply `--remote-components ejs:github` to yt-dlp. It is recommended to add this to your [yt-dlp configuration file](https://github.com/yt-dlp/yt-dlp?tab=readme-ov-file#configuration) to avoid needing to pass it every time and allow automatic updates. + + +> [!NOTE] +> This method may not work if GitHub and GitHub release assets are not accessible from your network. This includes if you are using yt-dlp with a IPv6 IP-only (e.g., `--force-ipv6`) + +## Plugins + +You can install alternatives to the built-in JS challenge solvers through plugins. + +### Featured Plugins: +- [yt-dlp-apple-webkit-jsi](https://github.com/grqz/yt-dlp-apple-webkit-jsi) by [grqz](https://github.com/grqz) + - Experimental Apple WebKit JS Challenge Provider plugin for yt-dlp. Should work on most Apple devices. *Maintained by a yt-dlp maintainer* + +Check out the [yt-dlp-jsc-provider](https://github.com/topics/yt-dlp-jsc-provider) GitHub topic for more JSC Provider plugins. + +For developers, refer to the [JSC Provider developer documentation](https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/extractor/youtube/jsc/README.md) +- **Please note: Currently only the base JavaScript Challenge Provider API is public. The API to hook into yt-dlp's EJS scripts is private at this time due to ongoing development with potential breaking changes; it may be made public in the future.** \ No newline at end of file