### Basic download example Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/index.md Basic usage example: downloads a YouTube video and pipes it to a file. The stream is returned immediately and the download starts when getInfo resolves. ```javascript const ytdl = require("@distube/ytdl-core"); const fs = require("fs"); ytdl("http://www.youtube.com/watch?v=aqz-KE-bpKQ").pipe(fs.createWriteStream("video.mp4")); ``` -------------------------------- ### Example - cookies Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/agents.md Example of using createAgent with cookies and options, then passing the agent to getBasicInfo. ```javascript const ytdl = require("@distube/ytdl-core"); const cookies = [ { name: "cookie1", value: "COOKIE1_HERE" }, { name: "cookie2", value: "COOKIE2_HERE" }, ]; const agent = ytdl.createAgent(cookies, { pipelining: 5, maxRedirections: 0 }); ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ``` -------------------------------- ### Example - proxy Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/agents.md Example showing how to create a proxy agent and pass it to ytdl.getInfo. The agent is created with a proxy URI and used in the request options. ```javascript const ytdl = require("@distube/ytdl-core"); const agent = ytdl.createProxyAgent({ uri: "my.proxy.server" }); ytdl.getInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ``` -------------------------------- ### Example - proxy + cookies Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/agents.md Example showing how to create a proxy agent with cookies and pass it to ytdl.getBasicInfo. The cookies array is provided as the second argument to createProxyAgent. ```javascript const ytdl = require("@distube/ytdl-core"); const agent = ytdl.createProxyAgent({ uri: "my.proxy.server" }, [{ name: "cookie", value: "COOKIE_HERE" }]); ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ``` -------------------------------- ### getInfo example with playerClients Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/get-info.md Fetches video info using @distube/ytdl-core with language and player client options, then logs format details and best format. ```javascript const ytdl = require("@distube/ytdl-core"); const info = await ytdl.getInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ", { lang: "en", playerClients: ["WEB", "IOS"], // limit the player clients queried }); console.log(info.formats.map(f => ({ itag: f.itag, quality: f.qualityLabel, hasAudio: f.hasAudio }))); console.log("Best:", info.bestFormat.itag, "Full:", info.full); ``` -------------------------------- ### Install @distube/ytdl-core with npm Source: https://github.com/distubejs/ytdl-core/blob/master/README.md Use this command to install the latest version of @distube/ytdl-core. The page emphasizes ensuring the latest version is installed to keep up with the latest fixes. ```bash npm install @distube/ytdl-core@latest ``` -------------------------------- ### Full configuration example with createAgent, getInfo, and downloadFromInfo Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/configuration.md Shows the full configuration surface for @distube/ytdl-core: creating an agent with cookies and options, fetching info with playerClients and requestOptions, and downloading audio with quality/filter/chunk settings. The agent must be reused to keep a cookie session alive. ```javascript const ytdl = require("@distube/ytdl-core"); const agent = ytdl.createAgent([{ name: "cookie1", value: "..." }], { pipelining: 5, maxRedirections: 0, localAddress: "127.0.0.1", }); const info = await ytdl.getInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ", { lang: "en", agent, playerClients: ["IOS", "WEB"], requestOptions: { headers: { "X-Custom": "1" } }, rewriteRequest: (url, requestOptions) => ({ url, requestOptions }), }); ytdl.downloadFromInfo(info, { agent, quality: "highestaudio", filter: "audioonly", dlChunkSize: 0, highWaterMark: 1024 * 1024, begin: "5m", }).pipe(require("fs").createWriteStream("audio.m4a")); ``` -------------------------------- ### Cache usage example Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/cache.md Demonstrates creating a Cache with a 5-second timeout, using getOrSet to fetch and cache a value, and then deleting it. ```javascript const Cache = require("@distube/ytdl-core/lib/cache"); const cache = new Cache(5000); const hit1 = await cache.getOrSet("key", async () => fetchSomething()); // fetches const hit2 = await cache.getOrSet("key", async () => fetchSomething()); // cached for 5s console.log(hit1 === hit2); // true cache.delete("key"); console.log(cache.get("key")); // null ``` -------------------------------- ### sortFormats usage example Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/formats.md Example of using sortFormats to sort formats in place. Imports from the internal format-utils module. ```js const { sortFormats } = require("@distube/ytdl-core/lib/format-utils"); info.formats.sort(sortFormats); ``` -------------------------------- ### Download from info with ytdl.downloadFromInfo Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/index.md Example of using ytdl.downloadFromInfo with an info object from ytdl.getInfo. It checks if the video is live, finds an HLS format, and pipes the download to stdout. Requires info.full to be true. ```js const ytdl = require("@distube/ytdl-core"); const info = await ytdl.getInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ"); if (info.videoDetails.isLive) { // pick a live format manually, then download const liveFormat = info.formats.find(f => f.isHLS); ytdl.downloadFromInfo(info, { format: liveFormat }).pipe(process.stdout); } ``` -------------------------------- ### Example usage of URL and video-ID helpers Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/url-utils.md Example usage of the helper functions: extracting a video ID from a music.youtube.com URL, validating IDs, validating a youtu.be URL, and passing a raw ID through getVideoID. ```javascript const ytdl = require("@distube/ytdl-core"); const id = ytdl.getURLVideoID("https://music.youtube.com/watch?v=aqz-KE-bpKQ"); console.log(id); // "aqz-KE-bpKQ" console.log(ytdl.validateID("aqz-KE-bpKQ")); // true console.log(ytdl.validateID("not-valid")); // false console.log(ytdl.validateURL("https://youtu.be/aqz-KE-bpKQ")); // true console.log(ytdl.getVideoID("aqz-KE-bpKQ")); // "aqz-KE-bpKQ" (raw ID passthrough) ``` -------------------------------- ### chooseFormat example with highestaudio, itag, and fallback array Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/formats.md Shows how to select the best audio format, a specific itag (137), and a fallback array of itags. Requires info from ytdl.getInfo(). ```javascript const ytdl = require("@distube/ytdl-core"); const info = await ytdl.getInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ"); const bestAudio = ytdl.chooseFormat(info.formats, { quality: "highestaudio" }); console.log(`Best audio: itag ${bestAudio.itag}, bitrate ${bestAudio.audioBitrate}`); const byItag = ytdl.chooseFormat(info.formats, { quality: 137 }); console.log(`itag 137: ${byItag.qualityLabel}`); const fallback = ytdl.chooseFormat(info.formats, { quality: [137, 136, 135] }); ``` -------------------------------- ### createProxyAgent(options, cookies?) Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/agents.md Documentation for the createProxyAgent function, including parameters, return value, and usage examples. ```APIDOC ## `createProxyAgent(options, cookies?)` ### Description Creates an agent for making requests through a proxy, supporting both undici and node http-agent styles. Returns an object with `dispatcher`, `agent`, `jar`, and `localAddress` properties. ### Method Function ### Endpoint `createProxyAgent(options, cookies?)` ### Parameters - `options` (`ProxyAgent.Options | string`) - Required - undici `ProxyAgentOptions` (`{ uri, ... }`) or a plain proxy URI string. A string is rewritten to `{ uri: options }`. - `cookies` (`(Cookie | CK)[]`) - Optional - Cookie array as with `createAgent`. Defaults to `[]`. ### Return Value Returns an object with the following properties: - `dispatcher` - undici dispatcher composed with cookie handling. - `agent` - an `https-proxy-agent` `HttpsProxyAgent` instance used for miniget/m3u8stream downloads. - `jar` - a `CookieJar` instance. - `localAddress` - the local address from the options, if provided. ### Example — proxy ```js const ytdl = require("@distube/ytdl-core"); const agent = ytdl.createProxyAgent({ uri: "my.proxy.server" }); ytdl.getInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ``` ### Example — proxy + cookies ```js const ytdl = require("@distube/ytdl-core"); const agent = ytdl.createProxyAgent({ uri: "my.proxy.server" }, [{ name: "cookie", value: "COOKIE_HERE" }]); ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ``` ``` -------------------------------- ### Public API example: getBasicInfo Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/info-extras.md Fetches basic info for a YouTube video and logs author details, media object, and related videos count. ```javascript const ytdl = require("@distube/ytdl-core"); const info = await ytdl.getBasicInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ"); console.log(info.videoDetails.author.name, info.videoDetails.author.subscriber_count); console.log(info.videoDetails.media); // e.g. { category: "Music", year: ... } console.log(info.videoDetails.related_videos.length); // related videos ``` -------------------------------- ### decipherFormats usage example Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/sig.md Example usage of decipherFormats as used by getInfo. Requires info.html5player to be resolved first (getInfo does this internally). The options object is passed through to getFunctions. ```javascript const sig = require("@distube/ytdl-core/lib/sig"); const info = await ytdl.getBasicInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ"); // info.html5player must be resolved first (getInfo does this internally) const deciphered = await sig.decipherFormats( info.player_response.streamingData.formats, info.html5player, { agent }, ); console.log(Object.keys(deciphered)); ``` -------------------------------- ### getRandomIPv6 usage from README (module-private) Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/utils.md Shows the README example for IP rotation using getRandomIPv6. Note that getRandomIPv6 is module-private in v4.16.12 and resolves to undefined, so this code will not work as shown. Use createAgent with your own localAddress instead. ```javascript // Per README: create one Agent per IP address const { getRandomIPv6 } = require("@distube/ytdl-core/lib/utils"); // resolves to undefined in v4.16.12 const agentForARandomIP = ytdl.createAgent(undefined, { localAddress: getRandomIPv6("2001:2::/48"), }); ``` -------------------------------- ### Basic usage: download video and get info Source: https://github.com/distubejs/ytdl-core/blob/master/README.md Shows how to require the module, download a video to a file, and retrieve basic info and formats. Includes TypeScript import alternatives in comments. ```javascript const ytdl = require("@distube/ytdl-core"); // TypeScript: import ytdl from '@distube/ytdl-core'; with --esModuleInterop // TypeScript: import * as ytdl from '@distube/ytdl-core'; with --allowSyntheticDefaultImports // TypeScript: import ytdl = require('@distube/ytdl-core'); with neither of the above // Download a video ytdl("http://www.youtube.com/watch?v=aqz-KE-bpKQ").pipe(require("fs").createWriteStream("video.mp4")); // Get video info ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ").then(info => { console.log(info.videoDetails.title); }); // Get video info with download formats ytdl.getInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ").then(info => { console.log(info.formats); }); ``` -------------------------------- ### Use applyDefaultHeaders and applyDefaultAgent directly Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/utils.md Directly calls the internal option normalizers `applyDefaultHeaders` and `applyDefaultAgent` on an empty options object, then logs the resulting User-Agent header and confirms the default agent was installed. Useful for testing or understanding how these utilities mutate the options object before requests. ```javascript const utils = require("@distube/ytdl-core/lib/utils"); const options = {}; utils.applyDefaultHeaders(options); utils.applyDefaultAgent(options); console.log(options.requestOptions.headers["User-Agent"]); console.log(options.agent === require("@distube/ytdl-core/lib/agent").defaultAgent); // true ``` -------------------------------- ### chooseFormat error handling example Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/formats.md Demonstrates catching errors when no format matches the given quality and filter. The error message is "No such format found: highestvideo" or a TypeError from filterFormats. ```javascript const ytdl = require("@distube/ytdl-core"); try { ytdl.chooseFormat(info.formats, { quality: "highestvideo", filter: "audioonly" }); } catch (err) { console.error(err.message); // "No such format found: highestvideo" (or a TypeError from filterFormats) } ``` -------------------------------- ### Example - error handling Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/agents.md Example of error handling when createAgent is called with a non-array cookies argument, which throws an error with message 'cookies must be an array'. ```javascript const ytdl = require("@distube/ytdl-core"); try { ytdl.createAgent("not-an-array"); // throws "cookies must be an array" } catch (err) { console.error(err.message); } ``` -------------------------------- ### Proxy support: create proxy agent Source: https://github.com/distubejs/ytdl-core/blob/master/README.md Shows how to create a proxy agent and use it with getBasicInfo and getInfo. ```javascript const ytdl = require("@distube/ytdl-core"); const agent = ytdl.createProxyAgent({ uri: "my.proxy.server" }); ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ytdl.getInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ``` -------------------------------- ### filterFormats usage example Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/formats.md Example usage of filterFormats with the 'audioonly' string filter and a custom predicate for high resolution formats. Requires @distube/ytdl-core and uses ytdl.getInfo. ```js const ytdl = require("@distube/ytdl-core"); const info = await ytdl.getInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ"); const audioOnly = ytdl.filterFormats(info.formats, "audioonly"); const highRes = ytdl.filterFormats(info.formats, f => f.height >= 720); ``` -------------------------------- ### Cookies support: create agent with cookies Source: https://github.com/distubejs/ytdl-core/blob/master/README.md Shows how to create an agent with cookies and optional agent options, then use it with getBasicInfo and getInfo. Includes warnings about cookie handling. ```javascript const ytdl = require("@distube/ytdl-core"); // (Optional) Below are examples, NOT the recommended options const cookies = [ { name: "cookie1", value: "COOKIE1_HERE" }, { name: "cookie2", value: "COOKIE2_HERE" }, ]; // (Optional) http-cookie-agent / undici agent options // Below are examples, NOT the recommended options const agentOptions = { pipelining: 5, maxRedirections: 0, localAddress: "127.0.0.1", }; // agent should be created once if you don't want to change your cookie const agent = ytdl.createAgent(cookies, agentOptions); ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ytdl.getInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ``` -------------------------------- ### Error handling example for getURLVideoID Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/url-utils.md Example showing error handling for getURLVideoID: a non-YouTube domain throws Error "Not a YouTube domain", and an invalid ID in a youtu.be URL throws TypeError "Video id (12345) does not match expected format...". ```javascript const ytdl = require("@distube/ytdl-core"); try { ytdl.getURLVideoID("https://example.com/video"); } catch (err) { console.error(err.constructor.name, err.message); // Error "Not a YouTube domain" } try { ytdl.getURLVideoID("https://youtu.be/12345"); } catch (err) { console.error(err.constructor.name, err.message); // TypeError "Video id (12345) does not match expected format..." } ``` -------------------------------- ### Use both proxy and cookies Source: https://github.com/distubejs/ytdl-core/blob/master/README.md Shows how to create an agent that uses both a proxy and cookies, then use it with getBasicInfo and getInfo. ```javascript const ytdl = require("@distube/ytdl-core"); const agent = ytdl.createProxyAgent({ uri: "my.proxy.server" }, [{ name: "cookie", value: "COOKIE_HERE" }]); ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ytdl.getInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent }); ``` -------------------------------- ### Cache class signature Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/cache.md Shows the JavaScript class signature for Cache, which extends Map and includes methods for setting, getting, and deleting entries with a timeout. ```javascript module.exports = class Cache extends Map { constructor(timeout = 1000) { ... } set(key, value) { ... } get(key) { ... } getOrSet(key, fn) { ... } delete(key) { ... } clear() { ... } }; ``` -------------------------------- ### Environment variable example for YTDL_NO_UPDATE and YTDL_DEBUG_PATH Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/configuration.md Runs a Node.js app with environment variables to disable the update check (YTDL_NO_UPDATE=1) and set a debug output path (YTDL_DEBUG_PATH=/tmp/ytdl-debug). ```bash YTDL_NO_UPDATE=1 YTDL_DEBUG_PATH=/tmp/ytdl-debug node app.js ``` -------------------------------- ### IP rotation: create agents with random IPv6 Source: https://github.com/distubejs/ytdl-core/blob/master/README.md Shows how to create agents with random IPv6 addresses for IP rotation, using getRandomIPv6 and createAgent, then use them with getBasicInfo and getInfo. ```javascript const ytdl = require("@distube/ytdl-core"); const { getRandomIPv6 } = require("@distube/ytdl-core/lib/utils"); const agentForARandomIP = ytdl.createAgent(undefined, { localAddress: getRandomIPv6("2001:2::/48"), }); ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent: agentForARandomIP }); const agentForAnotherRandomIP = ytdl.createAgent(undefined, { localAddress: getRandomIPv6("2001:2::/48"), }); ytdl.getInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { agent: agentForAnotherRandomIP }); ``` -------------------------------- ### Error handling and progress with ytdl() Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/index.md Shows how to create a download stream with @distube/ytdl-core and listen for the 'info', 'progress', and 'error' events. Setting dlChunkSize to 0 disables chunked downloads. The error handler checks for HTTP 429 to report rate limiting by YouTube. ```js const ytdl = require("@distube/ytdl-core"); const stream = ytdl("http://www.youtube.com/watch?v=aqz-KE-bpKQ", { quality: "highestaudio", filter: "audioonly", dlChunkSize: 0, // disable chunked downloads }); stream.on("info", (info, format) => { console.log(`Downloading "${info.videoDetails.title}" (${format.qualityLabel || format.audioBitrate})`); }); stream.on("progress", (chunkLength, downloaded, total) => { const pct = total ? (downloaded / total) * 100 : 0; console.log(`${downloaded} / ${total} bytes (${pct.toFixed(1)}%)`); }); stream.on("error", err => { if (err.statusCode === 429) console.error("Rate limited by YouTube"); else console.error("Download failed:", err.message); }); ``` -------------------------------- ### downloadOptions interface Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/types.md Options for ytdl(link, options) and ytdl.downloadFromInfo. Extends getInfoOptions and chooseFormatOptions. The range field sets a byte range, begin is appended as &begin= on single-request downloads, and dlChunkSize controls byte-range chunking for audio/video-only formats (0 disables chunking). ```typescript interface downloadOptions extends getInfoOptions, chooseFormatOptions { range?: { start?: number; end?: number; }; begin?: string | number | Date; liveBuffer?: number; highWaterMark?: number; IPv6Block?: string; dlChunkSize?: number; } ``` -------------------------------- ### Error handling with getBasicInfo() and try/catch Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/get-info.md Uses async/await inside a try/catch to call getBasicInfo(). If the error message contains "is unavailable", it logs that the video is unavailable/unplayable; otherwise it logs the error message and statusCode. ```javascript const ytdl = require("@distube/ytdl-core"); try { const info = await ytdl.getBasicInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ"); } catch (err) { if (err.message.includes("is unavailable")) console.log("Video is unavailable/unplayable"); else console.error("Request failed:", err.message, err.statusCode); } ``` -------------------------------- ### Using addFormatMeta directly Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/formats.md Shows how to import and call addFormatMeta from the library's format-utils module. The function returns an enriched format object with derived fields like hasVideo, container, and isHLS. ```javascript const { addFormatMeta } = require("@distube/ytdl-core/lib/format-utils"); const enriched = addFormatMeta(rawFormat); console.log(enriched.hasVideo, enriched.container, enriched.isHLS); ``` -------------------------------- ### checkForUpdates() - update checker Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/utils.md Checks for updates at most every 12 hours, unless YTDL_NO_UPDATE is set or the version starts with 0.0.0-. On mismatch it prints a yellow warning; network errors print "Error checking for updates: " plus a note about YTDL_NO_UPDATE. Called at the top of the cached getBasicInfo/getInfo wrappers. ```javascript exports.checkForUpdates = () => { if ( !process.env.YTDL_NO_UPDATE && !pkg.version.startsWith("0.0.0-") && Date.now() - exports.lastUpdateCheck >= UPDATE_INTERVAL // 12 hours ) { exports.lastUpdateCheck = Date.now(); // GET https://api.github.com/repos/distubejs/ytdl-core/contents/package.json with a Chrome User-Agent // ... warn up to 5 times (updateWarnTimes < 5) when the published version differs } return null; }; ``` -------------------------------- ### ytdl.downloadFromInfo(info, options) Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/index.md Downloads a video using an info object previously obtained from ytdl.getInfo(). Useful when the caller wants to inspect the info object before deciding to download. ```APIDOC ## `ytdl.downloadFromInfo(info, options)` ### Description Downloads a video using an `info` object previously obtained from `ytdl.getInfo()` — useful when the caller wants to inspect `info` before deciding to download. ### Method FUNCTION ### Endpoint `ytdl.downloadFromInfo(info, options)` ### Parameters #### Parameters - **info** (`videoInfo`) - Required - The object returned by `ytdl.getInfo()`. Must have `info.full === true`. - **options** (`downloadOptions`) - Optional - Same as `ytdl()` options. Defaults to `{}`. ### Request Example ```js const ytdl = require("@distube/ytdl-core"); const info = await ytdl.getInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ"); if (info.videoDetails.isLive) { // pick a live format manually, then download const liveFormat = info.formats.find(f => f.isHLS); ytdl.downloadFromInfo(info, { format: liveFormat }).pipe(process.stdout); } ``` ### Response #### Success Response - Returns a `Readable` stream. #### Error Handling - **Throws** `Error("Cannot use \`ytdl.downloadFromInfo()\` when called with info from \`ytdl.getBasicInfo()\`")` synchronously if `info.full` is falsy. - The download itself starts on the next tick via `setImmediate`. ``` -------------------------------- ### Cookies support: read cookies from file Source: https://github.com/distubejs/ytdl-core/blob/master/README.md Shows how to read a cookies array from a JSON file using fs.readFileSync and create an agent with it. ```javascript const ytdl = require("@distube/ytdl-core"); const fs = require("fs"); const agent = ytdl.createAgent(JSON.parse(fs.readFileSync("cookies.json"))); ``` -------------------------------- ### getChapters(info) Source: https://github.com/distubejs/ytdl-core/blob/master/_autodocs/api-reference/info-extras.md Documentation for the getChapters function, which extracts chapter information from YouTube video info. ```APIDOC ## getChapters(info) ### Description Searches the player overlay response for chapter markers and returns an array of chapter objects with title and start time in seconds. Returns an empty array when no chapter marker exists. ### Parameters - **info** (object) - Required - The video info object obtained from `ytdl.getBasicInfo()` or `ytdl.getInfo()`. ### Returns - **Array<{title: string, start_time: number}>** - Array of chapter objects, where `start_time` is in seconds (derived from `timeRangeStartMillis / 1000`). Returns `[]` if no chapter marker exists. ### Example ```js const ytdl = require("@distube/ytdl-core"); const info = await ytdl.getBasicInfo("https://www.youtube.com/watch?v=aqz-KE-bpKQ"); const chapters = getChapters(info); console.log(chapters); ``` ```