@distube/ytdl-core
Version:
DisTube fork of ytdl-core. YouTube video downloader in pure javascript.
1,018 lines (917 loc) • 28 kB
TypeScript
declare module "tough-cookie" {
export const version: string;
export const PrefixSecurityEnum: Readonly<{
DISABLED: string;
SILENT: string;
STRICT: string;
}>;
/**
* Parse a cookie date string into a Date.
* Parses according to RFC6265 Section 5.1.1, not Date.parse().
*/
export function parseDate(string: string): Date;
/**
* Format a Date into a RFC1123 string (the RFC6265-recommended format).
*/
export function formatDate(date: Date): string;
/**
* Transforms a domain-name into a canonical domain-name.
* The canonical domain-name is a trimmed, lowercased, stripped-of-leading-dot
* and optionally punycode-encoded domain-name (Section 5.1.2 of RFC6265).
* For the most part, this function is idempotent (can be run again on its output without ill effects).
*/
export function canonicalDomain(str: string): string;
/**
* Answers "does this real domain match the domain in a cookie?".
* The str is the "current" domain-name and the domStr is the "cookie" domain-name.
* Matches according to RFC6265 Section 5.1.3, but it helps to think of it as a "suffix match".
*
* The canonicalize parameter will run the other two parameters through canonicalDomain or not.
*/
export function domainMatch(str: string, domStr: string, canonicalize?: boolean): boolean;
/**
* Given a current request/response path, gives the Path apropriate for storing in a cookie.
* This is basically the "directory" of a "file" in the path, but is specified by Section 5.1.4 of the RFC.
*
* The path parameter MUST be only the pathname part of a URI (i.e. excludes the hostname, query, fragment, etc.).
* This is the .pathname property of node's uri.parse() output.
*/
export function defaultPath(path: string): string;
/**
* Answers "does the request-path path-match a given cookie-path?" as per RFC6265 Section 5.1.4.
* Returns a boolean.
*
* This is essentially a prefix-match where cookiePath is a prefix of reqPath.
*/
export function pathMatch(reqPath: string, cookiePath: string): boolean;
/**
* alias for Cookie.parse(cookieString[, options])
*/
export function parse(cookieString: string, options?: Cookie.ParseOptions): Cookie | undefined;
/**
* alias for Cookie.fromJSON(string)
*/
export function fromJSON(string: string): Cookie;
export function getPublicSuffix(hostname: string): string | null;
export function cookieCompare(a: Cookie, b: Cookie): number;
export function permuteDomain(domain: string, allowSpecialUseDomain?: boolean): string[];
export function permutePath(path: string): string[];
export class Cookie {
static parse(cookieString: string, options?: Cookie.ParseOptions): Cookie | undefined;
static fromJSON(strOrObj: string | object): Cookie | null;
constructor(properties?: Cookie.Properties);
key: string;
value: string;
expires: Date | "Infinity";
maxAge: number | "Infinity" | "-Infinity";
domain: string | null;
path: string | null;
secure: boolean;
httpOnly: boolean;
extensions: string[] | null;
creation: Date | null;
creationIndex: number;
hostOnly: boolean | null;
pathIsDefault: boolean | null;
lastAccessed: Date | null;
sameSite: string;
toString(): string;
cookieString(): string;
setExpires(exp: Date | string): void;
setMaxAge(number: number): void;
expiryTime(now?: number): number;
expiryDate(now?: number): Date;
TTL(now?: Date): number | typeof Infinity;
isPersistent(): boolean;
canonicalizedDomain(): string | null;
cdomain(): string | null;
inspect(): string;
toJSON(): { [key: string]: any };
clone(): Cookie;
validate(): boolean | string;
}
export namespace Cookie {
interface ParseOptions {
loose?: boolean | undefined;
}
interface Properties {
key?: string | undefined;
value?: string | undefined;
expires?: Date | "Infinity" | undefined;
maxAge?: number | "Infinity" | "-Infinity" | undefined;
domain?: string | undefined;
path?: string | undefined;
secure?: boolean | undefined;
httpOnly?: boolean | undefined;
extensions?: string[] | undefined;
creation?: Date | undefined;
creationIndex?: number | undefined;
hostOnly?: boolean | undefined;
pathIsDefault?: boolean | undefined;
lastAccessed?: Date | undefined;
sameSite?: string | undefined;
}
interface Serialized {
[key: string]: any;
}
}
export class CookieJar {
static deserialize(serialized: CookieJar.Serialized | string, store?: Store): Promise<CookieJar>;
static deserialize(
serialized: CookieJar.Serialized | string,
store: Store,
cb: (err: Error | null, object: CookieJar) => void,
): void;
static deserialize(
serialized: CookieJar.Serialized | string,
cb: (err: Error | null, object: CookieJar) => void,
): void;
static deserializeSync(serialized: CookieJar.Serialized | string, store?: Store): CookieJar;
static fromJSON(string: string): CookieJar;
constructor(store?: Store, options?: CookieJar.Options);
setCookie(
cookieOrString: Cookie | string,
currentUrl: string,
options?: CookieJar.SetCookieOptions,
): Promise<Cookie>;
setCookie(
cookieOrString: Cookie | string,
currentUrl: string,
options: CookieJar.SetCookieOptions,
cb: (err: Error | null, cookie: Cookie) => void,
): void;
setCookie(
cookieOrString: Cookie | string,
currentUrl: string,
cb: (err: Error | null, cookie: Cookie) => void,
): void;
setCookieSync(cookieOrString: Cookie | string, currentUrl: string, options?: CookieJar.SetCookieOptions): Cookie;
getCookies(currentUrl: string, options?: CookieJar.GetCookiesOptions): Promise<Cookie[]>;
getCookies(
currentUrl: string,
options: CookieJar.GetCookiesOptions,
cb: (err: Error | null, cookies: Cookie[]) => void,
): void;
getCookies(currentUrl: string, cb: (err: Error | null, cookies: Cookie[]) => void): void;
getCookiesSync(currentUrl: string, options?: CookieJar.GetCookiesOptions): Cookie[];
getCookieString(currentUrl: string, options?: CookieJar.GetCookiesOptions): Promise<string>;
getCookieString(
currentUrl: string,
options: CookieJar.GetCookiesOptions,
cb: (err: Error | null, cookies: string) => void,
): void;
getCookieString(currentUrl: string, cb: (err: Error | null, cookies: string) => void): void;
getCookieStringSync(currentUrl: string, options?: CookieJar.GetCookiesOptions): string;
getSetCookieStrings(currentUrl: string, options?: CookieJar.GetCookiesOptions): Promise<string[]>;
getSetCookieStrings(
currentUrl: string,
options: CookieJar.GetCookiesOptions,
cb: (err: Error | null, cookies: string[]) => void,
): void;
getSetCookieStrings(currentUrl: string, cb: (err: Error | null, cookies: string[]) => void): void;
getSetCookieStringsSync(currentUrl: string, options?: CookieJar.GetCookiesOptions): string[];
serialize(): Promise<CookieJar.Serialized>;
serialize(cb: (err: Error | null, serializedObject: CookieJar.Serialized) => void): void;
serializeSync(): CookieJar.Serialized;
toJSON(): CookieJar.Serialized;
clone(store?: Store): Promise<CookieJar>;
clone(store: Store, cb: (err: Error | null, newJar: CookieJar) => void): void;
clone(cb: (err: Error | null, newJar: CookieJar) => void): void;
cloneSync(store?: Store): CookieJar;
removeAllCookies(): Promise<void>;
removeAllCookies(cb: (err: Error | null) => void): void;
removeAllCookiesSync(): void;
}
export namespace CookieJar {
interface Options {
allowSpecialUseDomain?: boolean | undefined;
looseMode?: boolean | undefined;
rejectPublicSuffixes?: boolean | undefined;
prefixSecurity?: string | undefined;
}
interface SetCookieOptions {
http?: boolean | undefined;
secure?: boolean | undefined;
now?: Date | undefined;
ignoreError?: boolean | undefined;
}
interface GetCookiesOptions {
http?: boolean | undefined;
secure?: boolean | undefined;
now?: Date | undefined;
expire?: boolean | undefined;
allPaths?: boolean | undefined;
}
interface Serialized {
version: string;
storeType: string;
rejectPublicSuffixes: boolean;
cookies: Cookie.Serialized[];
}
}
export abstract class Store {
synchronous: boolean;
findCookie(domain: string, path: string, key: string, cb: (err: Error | null, cookie: Cookie | null) => void): void;
findCookies(
domain: string,
path: string,
allowSpecialUseDomain: boolean,
cb: (err: Error | null, cookie: Cookie[]) => void,
): void;
putCookie(cookie: Cookie, cb: (err: Error | null) => void): void;
updateCookie(oldCookie: Cookie, newCookie: Cookie, cb: (err: Error | null) => void): void;
removeCookie(domain: string, path: string, key: string, cb: (err: Error | null) => void): void;
removeCookies(domain: string, path: string, cb: (err: Error | null) => void): void;
getAllCookies(cb: (err: Error | null, cookie: Cookie[]) => void): void;
}
export class MemoryCookieStore extends Store {
findCookie(domain: string, path: string, key: string, cb: (err: Error | null, cookie: Cookie | null) => void): void;
findCookie(domain: string, path: string, key: string): Promise<Cookie | null>;
findCookies(
domain: string,
path: string,
allowSpecialUseDomain: boolean,
cb: (err: Error | null, cookie: Cookie[]) => void,
): void;
findCookies(domain: string, path: string, cb: (err: Error | null, cookie: Cookie[]) => void): void;
findCookies(domain: string, path: string, allowSpecialUseDomain?: boolean): Promise<Cookie[]>;
putCookie(cookie: Cookie, cb: (err: Error | null) => void): void;
putCookie(cookie: Cookie): Promise<void>;
updateCookie(oldCookie: Cookie, newCookie: Cookie, cb: (err: Error | null) => void): void;
updateCookie(oldCookie: Cookie, newCookie: Cookie): Promise<void>;
removeCookie(domain: string, path: string, key: string, cb: (err: Error | null) => void): void;
removeCookie(domain: string, path: string, key: string): Promise<void>;
removeCookies(domain: string, path: string, cb: (err: Error | null) => void): void;
removeCookies(domain: string, path: string): Promise<void>;
getAllCookies(cb: (err: Error | null, cookie: Cookie[]) => void): void;
getAllCookies(): Promise<Cookie[]>;
}
}
declare module "@distube/ytdl-core" {
import { Dispatcher, ProxyAgent, request } from "undici";
import { Cookie as CK, CookieJar } from "tough-cookie";
import { CookieAgent } from "http-cookie-agent/undici";
import { Readable } from "stream";
namespace ytdl {
type Filter =
| "audioandvideo"
| "videoandaudio"
| "video"
| "videoonly"
| "audio"
| "audioonly"
| ((format: videoFormat) => boolean);
interface Agent {
dispatcher: Dispatcher;
jar: CookieJar;
localAddress?: string;
}
interface getInfoOptions {
lang?: string;
requestCallback?: () => {};
rewriteRequest?: (
url: string,
requestOptions: Parameters<typeof request>[1],
) => { url: string; requestOptions: Parameters<typeof request>[1] };
fetch?: (url: string, requestOptions: Parameters<typeof request>[1]) => Promise<Response>;
requestOptions?: Parameters<typeof request>[1];
agent?: Agent;
playerClients?: Array<"WEB_EMBEDDED" | "TV" | "IOS" | "ANDROID" | "WEB">;
}
interface chooseFormatOptions {
quality?:
| "lowest"
| "highest"
| "highestaudio"
| "lowestaudio"
| "highestvideo"
| "lowestvideo"
| (string & {})
| number
| string[]
| number[];
filter?: Filter;
format?: videoFormat;
}
interface downloadOptions extends getInfoOptions, chooseFormatOptions {
range?: {
start?: number;
end?: number;
};
begin?: string | number | Date;
liveBuffer?: number;
highWaterMark?: number;
IPv6Block?: string;
dlChunkSize?: number;
}
interface videoFormat {
itag: number;
url: string;
mimeType?: string;
bitrate?: number;
audioBitrate?: number;
width?: number;
height?: number;
initRange?: { start: string; end: string };
indexRange?: { start: string; end: string };
lastModified: string;
contentLength: string;
quality: "tiny" | "small" | "medium" | "large" | "hd720" | "hd1080" | "hd1440" | "hd2160" | "highres" | string;
qualityLabel:
| "144p"
| "144p 15fps"
| "144p60 HDR"
| "240p"
| "240p60 HDR"
| "270p"
| "360p"
| "360p60 HDR"
| "480p"
| "480p60 HDR"
| "720p"
| "720p60"
| "720p60 HDR"
| "1080p"
| "1080p60"
| "1080p60 HDR"
| "1440p"
| "1440p60"
| "1440p60 HDR"
| "2160p"
| "2160p60"
| "2160p60 HDR"
| "4320p"
| "4320p60";
projectionType?: "RECTANGULAR";
fps?: number;
averageBitrate?: number;
audioQuality?: "AUDIO_QUALITY_LOW" | "AUDIO_QUALITY_MEDIUM";
colorInfo?: {
primaries: string;
transferCharacteristics: string;
matrixCoefficients: string;
};
highReplication?: boolean;
approxDurationMs?: string;
targetDurationSec?: number;
maxDvrDurationSec?: number;
audioSampleRate?: string;
audioChannels?: number;
// Added by ytdl-core
container: "flv" | "3gp" | "mp4" | "webm" | "ts";
hasVideo: boolean;
hasAudio: boolean;
codecs: string;
videoCodec?: string;
audioCodec?: string;
isLive: boolean;
isHLS: boolean;
isDashMPD: boolean;
}
interface thumbnail {
url: string;
width: number;
height: number;
}
interface captionTrack {
baseUrl: string;
name: {
simpleText:
| "Afrikaans"
| "Albanian"
| "Amharic"
| "Arabic"
| "Armenian"
| "Azerbaijani"
| "Bangla"
| "Basque"
| "Belarusian"
| "Bosnian"
| "Bulgarian"
| "Burmese"
| "Catalan"
| "Cebuano"
| "Chinese (Simplified)"
| "Chinese (Traditional)"
| "Corsican"
| "Croatian"
| "Czech"
| "Danish"
| "Dutch"
| "English"
| "English (auto-generated)"
| "Esperanto"
| "Estonian"
| "Filipino"
| "Finnish"
| "French"
| "Galician"
| "Georgian"
| "German"
| "Greek"
| "Gujarati"
| "Haitian Creole"
| "Hausa"
| "Hawaiian"
| "Hebrew"
| "Hindi"
| "Hmong"
| "Hungarian"
| "Icelandic"
| "Igbo"
| "Indonesian"
| "Irish"
| "Italian"
| "Japanese"
| "Javanese"
| "Kannada"
| "Kazakh"
| "Khmer"
| "Korean"
| "Kurdish"
| "Kyrgyz"
| "Lao"
| "Latin"
| "Latvian"
| "Lithuanian"
| "Luxembourgish"
| "Macedonian"
| "Malagasy"
| "Malay"
| "Malayalam"
| "Maltese"
| "Maori"
| "Marathi"
| "Mongolian"
| "Nepali"
| "Norwegian"
| "Nyanja"
| "Pashto"
| "Persian"
| "Polish"
| "Portuguese"
| "Punjabi"
| "Romanian"
| "Russian"
| "Samoan"
| "Scottish Gaelic"
| "Serbian"
| "Shona"
| "Sindhi"
| "Sinhala"
| "Slovak"
| "Slovenian"
| "Somali"
| "Southern Sotho"
| "Spanish"
| "Spanish (Spain)"
| "Sundanese"
| "Swahili"
| "Swedish"
| "Tajik"
| "Tamil"
| "Telugu"
| "Thai"
| "Turkish"
| "Ukrainian"
| "Urdu"
| "Uzbek"
| "Vietnamese"
| "Welsh"
| "Western Frisian"
| "Xhosa"
| "Yiddish"
| "Yoruba"
| "Zulu"
| string;
};
vssId: string;
languageCode:
| "af"
| "sq"
| "am"
| "ar"
| "hy"
| "az"
| "bn"
| "eu"
| "be"
| "bs"
| "bg"
| "my"
| "ca"
| "ceb"
| "zh-Hans"
| "zh-Hant"
| "co"
| "hr"
| "cs"
| "da"
| "nl"
| "en"
| "eo"
| "et"
| "fil"
| "fi"
| "fr"
| "gl"
| "ka"
| "de"
| "el"
| "gu"
| "ht"
| "ha"
| "haw"
| "iw"
| "hi"
| "hmn"
| "hu"
| "is"
| "ig"
| "id"
| "ga"
| "it"
| "ja"
| "jv"
| "kn"
| "kk"
| "km"
| "ko"
| "ku"
| "ky"
| "lo"
| "la"
| "lv"
| "lt"
| "lb"
| "mk"
| "mg"
| "ms"
| "ml"
| "mt"
| "mi"
| "mr"
| "mn"
| "ne"
| "no"
| "ny"
| "ps"
| "fa"
| "pl"
| "pt"
| "pa"
| "ro"
| "ru"
| "sm"
| "gd"
| "sr"
| "sn"
| "sd"
| "si"
| "sk"
| "sl"
| "so"
| "st"
| "es"
| "su"
| "sw"
| "sv"
| "tg"
| "ta"
| "te"
| "th"
| "tr"
| "uk"
| "ur"
| "uz"
| "vi"
| "cy"
| "fy"
| "xh"
| "yi"
| "yo"
| "zu"
| string;
kind: string;
rtl?: boolean;
isTranslatable: boolean;
}
interface audioTrack {
captionTrackIndices: number[];
}
interface translationLanguage {
languageCode: captionTrack["languageCode"];
languageName: captionTrack["name"];
}
interface VideoDetails {
videoId: string;
title: string;
shortDescription: string;
lengthSeconds: string;
keywords?: string[];
channelId: string;
isOwnerViewing: boolean;
isCrawlable: boolean;
thumbnails: thumbnail[];
averageRating: number;
allowRatings: boolean;
viewCount: string;
author: string;
isPrivate: boolean;
isUnpluggedCorpus: boolean;
isLiveContent: boolean;
isLive: boolean;
}
interface Media {
category: string;
category_url: string;
game?: string;
game_url?: string;
year?: number;
song?: string;
artist?: string;
artist_url?: string;
writers?: string;
licensed_by?: string;
thumbnails: thumbnail[];
}
interface Author {
id: string;
name: string;
avatar: string; // to remove later
thumbnails?: thumbnail[];
verified: boolean;
user?: string;
channel_url: string;
external_channel_url?: string;
user_url?: string;
subscriber_count?: number;
}
interface MicroformatRenderer {
thumbnail: {
thumbnails: thumbnail[];
};
embed: {
iframeUrl: string;
flashUrl: string;
width: number;
height: number;
flashSecureUrl: string;
};
title: {
simpleText: string;
};
description: {
simpleText: string;
};
lengthSeconds: string;
ownerProfileUrl: string;
ownerGplusProfileUrl?: string;
externalChannelId: string;
isFamilySafe: boolean;
availableCountries: string[];
isUnlisted: boolean;
hasYpcMetadata: boolean;
viewCount: string;
category: string;
publishDate: string;
ownerChannelName: string;
liveBroadcastDetails?: {
isLiveNow: boolean;
startTimestamp: string;
endTimestamp?: string;
};
uploadDate: string;
}
interface storyboard {
templateUrl: string;
thumbnailWidth: number;
thumbnailHeight: number;
thumbnailCount: number;
interval: number;
columns: number;
rows: number;
storyboardCount: number;
}
interface Chapter {
title: string;
start_time: number;
}
interface MoreVideoDetails
extends Omit<VideoDetails, "author" | "thumbnail" | "shortDescription">,
Omit<MicroformatRenderer, "title" | "description"> {
published: number;
video_url: string;
age_restricted: boolean;
likes: number | null;
media: Media;
author: Author;
thumbnails: thumbnail[];
storyboards: storyboard[];
chapters: Chapter[];
description: string | null;
}
interface videoInfo {
iv_load_policy?: string;
iv_allow_in_place_switch?: string;
iv_endscreen_url?: string;
iv_invideo_url?: string;
iv3_module?: string;
rmktEnabled?: string;
uid?: string;
vid?: string;
focEnabled?: string;
baseUrl?: string;
storyboard_spec?: string;
serialized_ad_ux_config?: string;
player_error_log_fraction?: string;
sffb?: string;
ldpj?: string;
videostats_playback_base_url?: string;
innertube_context_client_version?: string;
t?: string;
fade_in_start_milliseconds: string;
timestamp: string;
ad3_module: string;
relative_loudness: string;
allow_below_the_player_companion: string;
eventid: string;
token: string;
atc: string;
cr: string;
apply_fade_on_midrolls: string;
cl: string;
fexp: string[];
apiary_host: string;
fade_in_duration_milliseconds: string;
fflags: string;
ssl: string;
pltype: string;
enabled_engage_types: string;
hl: string;
is_listed: string;
gut_tag: string;
apiary_host_firstparty: string;
enablecsi: string;
csn: string;
status: string;
afv_ad_tag: string;
idpj: string;
sfw_player_response: string;
account_playback_token: string;
encoded_ad_safety_reason: string;
tag_for_children_directed: string;
no_get_video_log: string;
ppv_remarketing_url: string;
fmt_list: string[][];
ad_slots: string;
fade_out_duration_milliseconds: string;
instream_long: string;
allow_html5_ads: string;
core_dbp: string;
ad_device: string;
itct: string;
root_ve_type: string;
excluded_ads: string;
aftv: string;
loeid: string;
cver: string;
shortform: string;
dclk: string;
csi_page_type: string;
ismb: string;
gpt_migration: string;
loudness: string;
ad_tag: string;
of: string;
probe_url: string;
vm: string;
afv_ad_tag_restricted_to_instream: string;
gapi_hint_params: string;
cid: string;
c: string;
oid: string;
ptchn: string;
as_launched_in_country: string;
avg_rating: string;
fade_out_start_milliseconds: string;
midroll_prefetch_size: string;
allow_ratings: string;
thumbnail_url: string;
iurlsd: string;
iurlmq: string;
iurlhq: string;
iurlmaxres: string;
ad_preroll: string;
tmi: string;
trueview: string;
host_language: string;
innertube_api_key: string;
show_content_thumbnail: string;
afv_instream_max: string;
innertube_api_version: string;
mpvid: string;
allow_embed: string;
ucid: string;
plid: string;
midroll_freqcap: string;
ad_logging_flag: string;
ptk: string;
vmap: string;
watermark: string[];
dbp: string;
ad_flags: string;
html5player: string;
formats: videoFormat[];
related_videos: relatedVideo[];
no_embed_allowed?: boolean;
player_response: {
playabilityStatus: {
status: string;
playableInEmbed: boolean;
miniplayer: {
miniplayerRenderer: {
playbackMode: string;
};
};
contextParams: string;
};
streamingData: {
expiresInSeconds: string;
formats: {}[];
adaptiveFormats: {}[];
};
captions?: {
playerCaptionsRenderer: {
baseUrl: string;
visibility: string;
};
playerCaptionsTracklistRenderer: {
captionTracks: captionTrack[];
audioTracks: audioTrack[];
translationLanguages: translationLanguage[];
defaultAudioTrackIndex: number;
};
};
microformat: {
playerMicroformatRenderer: MicroformatRenderer;
};
videoDetails: VideoDetails;
playerConfig: {
audioConfig: {
loudnessDb: number;
perceptualLoudnessDb: number;
enablePerFormatLoudness: boolean;
};
streamSelectionConfig: { maxBitrate: string };
mediaCommonConfig: { dynamicReadaheadConfig: {}[] };
webPlayerConfig: { webPlayerActionsPorting: {}[] };
};
};
videoDetails: MoreVideoDetails;
}
interface relatedVideo {
id?: string;
title?: string;
published?: string;
author: Author | "string"; // to remove the `string` part later
ucid?: string; // to remove later
author_thumbnail?: string; // to remove later
short_view_count_text?: string;
view_count?: string;
length_seconds?: number;
video_thumbnail?: string; // to remove later
thumbnails: thumbnail[];
richThumbnails: thumbnail[];
isLive: boolean;
}
interface Cookie {
name: string;
value: string;
expirationDate?: number;
domain?: string;
path?: string;
secure?: boolean;
httpOnly?: boolean;
hostOnly?: boolean;
sameSite?: string;
}
function getBasicInfo(url: string, options?: getInfoOptions): Promise<videoInfo>;
function getInfo(url: string, options?: getInfoOptions): Promise<videoInfo>;
function downloadFromInfo(info: videoInfo, options?: downloadOptions): Readable;
function chooseFormat(format: videoFormat | videoFormat[], options?: chooseFormatOptions): videoFormat | never;
function filterFormats(formats: videoFormat | videoFormat[], filter?: Filter): videoFormat[];
function validateID(string: string): boolean;
function validateURL(string: string): boolean;
function getURLVideoID(string: string): string | never;
function getVideoID(string: string): string | never;
function createProxyAgent(options: ProxyAgent.Options | string): Agent;
function createProxyAgent(options: ProxyAgent.Options | string, cookies?: (Cookie | CK)[]): Agent;
function createAgent(): Agent;
function createAgent(cookies?: (Cookie | CK)[]): Agent;
function createAgent(cookies?: (Cookie | CK)[], opts?: CookieAgent.Options): Agent;
const version: number;
}
function ytdl(link: string, options?: ytdl.downloadOptions): Readable;
export = ytdl;
}