YBD Project fork of ytdl-core
. This fork is dedicated to developing a YouTube downloader that is fast, stable, and takes into account various use cases, with reference to LuanRT/YouTube.js and yt-dlp.
- ℹ️Announcements at this timeℹ️
- Prerequisite
- Operating Environment
- Installation
- Usage
- API Documentation
- Limitations
- Rate Limiting
- Update Checks
- License
Note
We are investigating a problem where the video URL can be retrieved but the download fails with a 403.
To use @ybd-project/ytdl-core
without problems, use Node.js 16 or higher. (Recommended is Node.js 18 or higher.)
Important
Use with Node.js 16 is not recommended, but will be supported as much as possible.
If you have an operating system that works or does not work other than those listed here, please let us know at ybd-project/ytdl-core#25.
Important
Developers will only test on currently supported operating systems and versions. Older versions (e.g. Windows 7) will not be tested.
- Windows 11
Note
MacOS is under testing.
- 22.04
- 24.04
- 9 Stream
npm install @ybd-project/ytdl-core@latest
Make sure you're installing the latest version of @ybd-project/ytdl-core
to keep up with the latest fixes.
For more detailed information on how to use and specify options, please see the Wiki.
import fs from 'fs';
import { YtdlCore } from '@ybd-project/ytdl-core';
// JavaScript: const { YtdlCore } = require('@ybd-project/ytdl-core');
const ytdl = new YtdlCore({
// The options specified here will be the default values when functions such as getFullInfo are executed.
});
// Download a video
ytdl.download('https://www.youtube.com/watch?v=dQw4w9WgXcQ').pipe(fs.createWriteStream('video.mp4'));
// Get video info
ytdl.getBasicInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ').then((info) => {
console.log(info.title);
});
// Get video info with download formats
ytdl.getFullInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ').then((info) => {
console.log(info.formats);
});
Starting with v5.1.0, ytdl-core now uses classes. To use the old usage, you will need to change your package imports.
You can use ytdl-core in the conventional way by adding /old
at the end.
import ytdlCore from '@ybd-project/ytdl-core/old';
const ytdlCore = require('@ybd-project/ytdl-core/old');
@ybd-project/ytdl-core
supports OAuth2 Token.
These can be used to avoid age restrictions and bot errors. See below for instructions on how to use them.
Important
Be sure to generate tokens with accounts that can be banned, as accounts may be banned.
Note
The specified OAuth2 token is automatically updated by ytdl-core, so you do not need to update it yourself.
Tip
Do not specify OAuth2 directly as an argument. If you specify it directly, the token will be renewed repeatedly when it expires. Be sure to assign the OAuth2 token to a variable or specify it as an option when initializing the YtdlCore class.
import { YtdlCore } from '@ybd-project/ytdl-core';
/* Normal usage */
const NORMAL_OAUTH2 = new YtdlCore.OAuth2({
accessToken: '...',
refreshToken: '...',
expiryDate: 'yyyy-MM-ddThh-mm-ssZ',
});
const ytdl = new YtdlCore({
oauth2: NORMAL_OAUTH2,
});
/* If you need to specify a client ID and secret */
const OAUTH2_SPECIFY_CLIENT_DATA = new YtdlCore.OAuth2({
accessToken: '...',
refreshToken: '...',
expiryDate: 'yyyy-MM-ddThh-mm-ssZ',
clientData: {
clientId: '...',
clientSecret: '...',
},
});
const ytdl = new YtdlCore({
oauth2: OAUTH2_SPECIFY_CLIENT_DATA,
});
/* Specify to the function if there is a need to override what was specified during class initialization. */
const OVERRIDE_OAUTH2 = new YtdlCore.OAuth2({
accessToken: '...',
refreshToken: '...',
expiryDate: 'yyyy-MM-ddThh-mm-ssZ',
});
// This `ytdl` is already initialized as in the other examples.
ytdl.getFullInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ', { oauth2: OVERRIDE_OAUTH2 });
There are two recommended methods for generating OAuth2 tokens.
- Generate using imputnet/cobalt
- Generate using your own client ID and secret
Tip
The method of production with cobalt is very stable and is recommended. Tokens generated using cobalt can be used in the normal way.
Important
If you generate it yourself, specify the client ID and secret in clientData
. This is required to refresh the token.
To generate tokens using Cobalt, execute the following command.
git clone https://github.com/imputnet/cobalt
cd cobalt/api/src
npm install -g pnpm
pnpm install
npm run token:youtube
If you wish to generate your own, please refer to the example folder for an example.
@ybd-project/ytdl-core
supports poToken
.
The poToken
can be used to avoid bot errors and must be specified with visitorData
. If you need to obtain poToken
or visitorData
, please use the following repository to generate them.
- https://github.com/iv-org/youtube-trusted-session-generator
- https://github.com/fsholehan/scrape-youtube
import { YtdlCore } from '@ybd-project/ytdl-core';
// JavaScript: const { YtdlCore } = require('@ybd-project/ytdl-core');
/* Basic Method */
const ytdl = new YtdlCore({ poToken: 'PO_TOKEN', visitorData: 'VISITOR_DATA' });
// PoToken, etc. specified at the time of class instantiation will be used.
// PoToken used: PO_TOKEN
ytdl.getFullInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
// Specified as function arguments take precedence over those specified at the time of class instantiation.
// PoToken used: OVERRIDE_PO_TOKEN
ytdl.getFullInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ', { poToken: 'OVERRIDE_PO_TOKEN', visitorData: 'OVERRIDE_VISITOR_DATA' });
/* Using static method */
YtdlCore.createProxyAgent({ uri: 'my.proxy.server' });
YtdlCore.getFullInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ', { poToken: 'PO_TOKEN', visitorData: 'VISITOR_DATA' });
The use of cookies is deprecated. Use PoToken
, OAuth2
, or both.
@ybd-project/ytdl-core
supports proxies.
Important
Try PoToken or OAuth2 before using a proxy. These may have the same effect as proxies.
The following createProxyAgent
function cannot be used with the own proxy in the example folder.
import { YtdlCore } from '@ybd-project/ytdl-core';
const ytdl = new YtdlCore({
agent: YtdlCore.createProxyAgent({ uri: 'my.proxy.server' }),
});
ytdl.getFullInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
Using a proxy sold by one service may not work. In such cases, you can deploy your own proxy, e.g., to Cloudflare Workers.
See the example for a proxy server implementation.
import { YtdlCore } from '@ybd-project/ytdl-core';
const ytdl = new YtdlCore({
originalProxy: {
base: 'http://localhost:6543',
download: 'http://localhost:6543/video-download',
urlQueryName: 'apiUrl',
},
});
/* With rewriteRequest, you can specify various things. (e.g., random selection of multiple proxies) */
const ytdl = new YtdlCore({
rewriteRequest: (url, options, { isDownloadUrl }) => {
if (isDownloadUrl) {
// URL is like: https://***.googlevideo.com/playbackvideo?...
return {
url: `https://your-video-proxy.server.com/?url=${encodeURIComponent(url)}`,
options,
};
}
return {
url: `https://your-proxy.server.com/?url=${encodeURIComponent(url)}`,
options,
};
},
});
ytdl.getFullInfo('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
The getRandomIPv6
function has been removed in v5.1.0. Currently, there is no stable implementation method for IPv6, as the detailed use case for IPv6-related rotation is unknown.
If you wish to use rotation, please create a new issue.
For API documentation, see the Wiki.
ytdl-core is unable to retrieve or download information from the following videos.
- Regionally restricted (requires a proxy)
- Private (if you have access, requires OAuth2)
- Rentals (if you have access, requires OAuth2)
- YouTube Premium content (if you have access, requires OAuth2)
- Only HLS Livestreams are currently supported. Other formats will get filtered out in ytdl.chooseFormats
The URL to view the retrieved video is valid for 6 hours. (In some cases, downloading may only be possible from the same IP.)
When doing too many requests YouTube might block. This will result in your requests getting denied with HTTP-StatusCode 429. The following steps might help you:
- Update
@ybd-project/ytdl-core
to the latest version - Use OAuth2 (you can find an example here)
- Use proxies (you can find an example here)
- Extend the Proxy Idea by rotating (IPv6-)Addresses
- read this for more information about this
- Wait it out (it usually goes away within a few days)
The issue of using an outdated version of ytdl-core became so prevalent, that ytdl-core now checks for updates at run time, and every 12 hours. If it finds an update, it will print a warning to the console advising you to update. Due to the nature of this library, it is important to always use the latest version as YouTube continues to update.
If you'd like to disable this update check, you can do so by providing the YTDL_NO_UPDATE
env variable.
env YTDL_NO_UPDATE=1 node myapp.js
Distributed under the MIT License.