YouTube.js
A wrapper around YouTube's internal API — reverse engineering InnerTube
README
YouTube.js
Description
InnerTube is an API used by all YouTube clients. It was created to simplify the deployment of new features and experiments across the platform [^1]. This library manages all low-level communication with InnerTube, providing a simple and efficient way to interact with YouTube programmatically. Its design aims to closely emulate an actual client, including the parsing of API responses.
If you have any questions or need help, feel free to reach out to us on our [Discord server][discord] or open an issue here.
Getting Started
Prerequisites
YouTube.js runs on Node.js, Deno, and modern browsers.
It requires a runtime with the following features:
- [fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)
- On Node, we use undici's fetch implementation, which requires Node.js 16.8+. If you need to use an older version, you may provide your own fetch implementation. See providing your own fetch implementation for more information.
- The Response object returned by fetch must thus be spec compliant and return a ReadableStream object if you want to use the VideoInfo#download method. (Implementations like node-fetch returns a non-standard Readable object.)
- [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) and [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) are required.
Installation
- ```bash
- # NPM
- npm install youtubei.js@latest
- # Yarn
- yarn add youtubei.js@latest
- # Git (edge version)
- npm install github:LuanRT/YouTube.js
- ```
When using Deno, you can import YouTube.js directly from deno.land:
- ```ts
- import { Innertube } from 'https://deno.land/x/youtubei/deno.ts';
- ```
Usage
Create an InnerTube instance:
- ```ts
- // const { Innertube } = require('youtubei.js');
- import { Innertube } from 'youtubei.js';
- const youtube = await Innertube.create(/* options */);
- ```
Initialization Options
Click to expand
Option | Type | Description | Default |
---|---|---|---|
--- | --- | --- | --- |
`lang` | `string` | Language. | `en` |
`location` | `string` | Geolocation. | `US` |
`account_index` | `number` | The | `0` |
`visitor_data` | `string` | Setting | `undefined` |
`retrieve_player` | `boolean` | Specifies | `true` |
`enable_safety_mode` | `boolean` | Specifies | `false` |
`generate_session_locally` | `boolean` | Specifies | `false` |
`device_category` | `DeviceCategory` | Platform | `DESKTOP` |
`client_type` | `ClientType` | InnerTube | `WEB` |
`timezone` | `string` | The | `*` |
`cache` | `ICache` | Used | `undefined` |
`cookie` | `string` | YouTube | `undefined` |
`fetch` | `FetchFunction` | Fetch | `fetch` |
Browser Usage
To use YouTube.js in the browser, you must proxy requests through your own server. You can see our simple reference implementation in Deno at [examples/browser/proxy/deno.ts](https://github.com/LuanRT/YouTube.js/tree/main/examples/browser/proxy/deno.ts).
You may provide your own fetch implementation to be used by YouTube.js, which we will use to modify and send the requests through a proxy. See [examples/browser/web](https://github.com/LuanRT/YouTube.js/tree/main/examples/browser/web) for a simple example using Vite.
- ```ts
- // Multiple exports are available for the web.
- // Unbundled ESM version
- import { Innertube } from 'youtubei.js/web';
- // Bundled ESM version
- // import { Innertube } from 'youtubei.js/web.bundle';
- // Production Bundled ESM version
- // import { Innertube } from 'youtubei.js/web.bundle.min';
- await Innertube.create({
- fetch: async (input: RequestInfo | URL, init?: RequestInit) => {
- // Modify the request
- // and send it to the proxy
- // fetch the URL
- return fetch(request, init);
- }
- });
- ```
Streaming
YouTube.js supports streaming of videos in the browser by converting YouTube's streaming data into an MPEG-DASH manifest.
The example below uses [dash.js](https://github.com/Dash-Industry-Forum/dash.js) to play the video.
- ```ts
- import { Innertube } from 'youtubei.js/web';
- import dashjs from 'dashjs';
- const youtube = await Innertube.create({ /* setup - see above */ });
- // Get the video info
- const videoInfo = await youtube.getInfo('videoId');
- // now convert to a dash manifest
- // again - to be able to stream the video in the browser - we must proxy the requests through our own server
- // to do this, we provide a method to transform the URLs before writing them to the manifest
- const manifest = await videoInfo.toDash(url => {
- // modify the url
- // and return it
- return url;
- });
- const uri = "data:application/dash+xml;charset=utf-8;base64," + btoa(manifest);
- const videoElement = document.getElementById('video_player');
- const player = dashjs.MediaPlayer().create();
- player.initialize(videoElement, uri, true);
- ```
A fully working example can be found in [examples/browser/web](https://github.com/LuanRT/YouTube.js/blob/main/examples/browser/web).
Providing your own fetch implementation
You may provide your own fetch implementation to be used by YouTube.js. This can be useful in some cases to modify the requests before they are sent and transform the responses before they are returned (eg. for proxies).
- ```ts
- // provide a fetch implementation
- const yt = await Innertube.create({
- fetch: async (input: RequestInfo | URL, init?: RequestInit) => {
- // make the request with your own fetch implementation
- // and return the response
- return new Response(
- /* ... */
- );
- }
- });
- ```