import { EventEmitter } from 'node:events';
import { ChildProcess } from 'node:child_process';
import { PassThrough } from 'node:stream';

/**
 * yt-dlp command-line options mapped to TypeScript.
 * @see https://github.com/yt-dlp/yt-dlp#usage-and-options
 */
interface ArgsOptions {
    /** Print help text and exit. Maps to `--help`. */
    printHelp?: boolean;
    /** Print program version and exit. Maps to `--version`. */
    printVersion?: boolean;
    /** Update yt-dlp to the latest version. Maps to `--update`. */
    update?: boolean;
    /** Do not check for updates. Maps to `--no-update`. */
    noUpdate?: boolean;
    /** Update to a specific version. Maps to `--update-to TAG`. */
    updateTo?: string;
    /** Continue on download errors. Maps to `--ignore-errors`. */
    ignoreErrors?: boolean;
    /** Continue with next video after error. Maps to `--no-abort-on-error`. */
    noAbortOnError?: boolean;
    /** Abort on download error. Maps to `--abort-on-error`. */
    abortOnError?: boolean;
    /** Display current browser user-agent. Maps to `--dump-user-agent`. */
    dumpUserAgent?: boolean;
    /** List all supported extractors. Maps to `--list-extractors`. */
    listExtractors?: boolean;
    /** Output descriptions of all extractors. Maps to `--extractor-descriptions`. */
    extractorDescriptions?: boolean;
    /** Use only specific extractors. Maps to `--use-extractors NAMES`. */
    useExtractors?: string[];
    /** Use this prefix for search queries. Maps to `--default-search PREFIX`. */
    defaultSearch?: string;
    /** Don't read configuration files. Maps to `--ignore-config`. */
    ignoreConfig?: boolean;
    /** Don't load config from default locations. Maps to `--no-config-location`. */
    noConfigLocations?: boolean;
    /** Location of the main config file. Maps to `--config-locations PATH`. */
    configLocations?: string[];
    /** Directories to load plugins from. Maps to `--plugin-dirs PATH`. */
    pluginDirs?: string[];
    /** Disable loading plugins. Maps to `--no-plugin-dirs`. */
    noPluginDirs?: boolean;
    /** Don't extract videos of a playlist. Maps to `--flat-playlist`. */
    flatPlaylist?: boolean;
    /** Extract videos of a playlist. Maps to `--no-flat-playlist`. */
    noFlatPlaylist?: boolean;
    /** Download livestreams from the start. Maps to `--live-from-start`. */
    liveFromStart?: boolean;
    /** Don't download from the start. Maps to `--no-live-from-start`. */
    noLiveFromStart?: boolean;
    /** Wait seconds for a video to become available. Maps to `--wait-for-video SEC`. */
    waitForVideo?: number;
    /** Don't wait for video. Maps to `--no-wait-for-video`. */
    noWaitForVideo?: boolean;
    /** Mark videos watched on YouTube. Maps to `--mark-watched`. */
    markWatched?: boolean;
    /** Don't mark videos watched. Maps to `--no-mark-watched`. */
    noMarkWatched?: boolean;
    /** Color output (always, never, auto, no_color). Maps to `--color WHEN`. */
    color?: string;
    /** Options to adjust behavior. Maps to `--compat-options OPTS`. */
    compatOptions?: string[];
    /** Command aliases. Maps to `--alias ALIAS CMD`. */
    aliases?: string[];
    /**
     * JavaScript runtime for extractors requiring JS execution.
     * Supported values: 'deno', 'node', 'phantomjs', etc.
     * Maps to `--js-runtime RUNTIME`.
     * @see https://github.com/yt-dlp/yt-dlp/wiki/EJS
     */
    jsRuntime?: string;
    /** Use the specified HTTP/HTTPS/SOCKS proxy. Maps to `--proxy URL`. */
    proxy?: string;
    /** Time to wait before giving up (seconds). Maps to `--socket-timeout SEC`. */
    socketTimeout?: number;
    /** Client-side IP address to bind to. Maps to `--source-address IP`. */
    sourceAddress?: string;
    /** Make all connections via IPv4. Maps to `--force-ipv4`. */
    forceIpv4?: boolean;
    /** Make all connections via IPv6. Maps to `--force-ipv6`. */
    forceIpv6?: boolean;
    /** Client to impersonate for requests. Maps to `--impersonate CLIENT`. */
    impersonate?: string[];
    /** List available clients to impersonate. Maps to `--list-impersonate-targets`. */
    listImpersonateTargets?: boolean;
    /** Enable file:// URLs. Maps to `--enable-file-urls`. */
    enableFileUrls?: boolean;
    /** Proxy for geo verification. Maps to `--geo-verification-proxy URL`. */
    geoVerificationProxy?: string;
    /** How to fake X-Forwarded-For header. Maps to `--xff VALUE`. */
    xff?: string;
    /** Bypass geographic restriction. Maps to `--geo-bypass`. */
    geoBypass?: boolean;
    /** Force bypass with a two-letter country code. Maps to `--geo-bypass-country CODE`. */
    geoBypassCountry?: string;
    /** Force bypass with an IP block. Maps to `--geo-bypass-ip-block IP_BLOCK`. */
    geoBypassIpBlock?: string;
    /** Playlist items to download (e.g., "1,3,5-7"). Maps to `--playlist-items ITEM_SPEC`. */
    playlistItems?: string;
    /** Don't download files smaller than SIZE. Maps to `--min-filesize SIZE`. */
    minFilesize?: string;
    /** Don't download files larger than SIZE. Maps to `--max-filesize SIZE`. */
    maxFilesize?: string;
    /** Download only videos uploaded on this date. Maps to `--date DATE`. */
    date?: string;
    /** Download only videos uploaded before this date. Maps to `--datebefore DATE`. */
    dateBefore?: string;
    /** Download only videos uploaded after this date. Maps to `--dateafter DATE`. */
    dateAfter?: string;
    /** Generic video filter. Maps to `--match-filter FILTER`. */
    matchFilter?: string;
    /** Do not use any --match-filter. Maps to `--no-match-filters`. */
    noMatchFilters?: boolean;
    /** Stop on filter match. Maps to `--break-match-filters FILTER`. */
    breakMatchFilters?: string;
    /** Do not --break-match-filters. Maps to `--no-break-match-filters`. */
    noBreakMatchFilters?: boolean;
    /** Download only the video for a single URL. Maps to `--no-playlist`. */
    noPlaylist?: boolean;
    /** Download the playlist if URL is a video and playlist. Maps to `--yes-playlist`. */
    yesPlaylist?: boolean;
    /** Download only videos suitable for the given age. Maps to `--age-limit YEARS`. */
    ageLimit?: number;
    /** Download only videos not in the archive. Maps to `--download-archive FILE`. */
    downloadArchive?: string;
    /** Do not use archive file. Maps to `--no-download-archive`. */
    noDownloadArchive?: boolean;
    /** Maximum number of files to download. Maps to `--max-downloads NUMBER`. */
    maxDownloads?: number;
    /** Stop if video is in archive. Maps to `--break-on-existing`. */
    breakOnExisting?: boolean;
    /** Do not stop on existing. Maps to `--no-break-on-existing`. */
    noBreakOnExisting?: boolean;
    /** Reset per input URL. Maps to `--break-per-input`. */
    breakPerInput?: boolean;
    /** Do not reset per input. Maps to `--no-break-per-input`. */
    noBreakPerInput?: boolean;
    /** Skip rest of playlist after N errors. Maps to `--skip-playlist-after-errors N`. */
    skipPlaylistAfterErrors?: number;
    /** Playlist video to start at (1-indexed). Maps to `--playlist-start NUMBER`. */
    playlistStart?: number;
    /** Playlist video to end at (1-indexed). Maps to `--playlist-end NUMBER`. */
    playlistEnd?: number;
    /** Download only videos whose title matches regex. Maps to `--match-title REGEX`. */
    matchTitle?: string;
    /** Skip videos whose title matches regex. Maps to `--reject-title REGEX`. */
    rejectTitle?: string;
    /** Download ads as well. Maps to `--include-ads`. */
    includeAds?: boolean;
    /** Stop on rejected title. Maps to `--break-on-reject`. */
    breakOnReject?: boolean;
    /**
     * Number of fragments to download concurrently.
     * Maps to `-N, --concurrent-fragments N`.
     */
    concurrentFragments?: number;
    /**
     * Minimum download rate to avoid throttling (e.g., "100K").
     * Re-extracts video data if download rate falls below this.
     * Maps to `--throttled-rate RATE`.
     */
    throttledRate?: string;
    /** Number of retries for file access. Maps to `--file-access-retries RETRIES`. */
    fileAccessRetries?: number;
    /**
     * Time to sleep between retries in seconds.
     * Can be a number, "linear=START[:END[:STEP]]" or "exp=START[:END[:BASE]]".
     * Use retrySleepType for type-specific sleep.
     * Maps to `--retry-sleep [TYPE:]EXPR`.
     */
    retrySleep?: number | string;
    /**
     * Type-specific retry sleep configuration.
     * Keys: 'http', 'fragment', 'file_access', 'extractor'.
     * Maps to `--retry-sleep TYPE:EXPR`.
     */
    retrySleepByType?: {
        [type: string]: string;
    };
    /** Delete fragments after download. Maps to `--no-keep-fragments`. */
    noKeepFragments?: boolean;
    /** Automatically resize the download buffer. Maps to `--resize-buffer`. */
    resizeBuffer?: boolean;
    /** Don't automatically resize buffer. Maps to `--no-resize-buffer`. */
    noResizeBuffer?: boolean;
    /** Process playlist entries as received. Maps to `--lazy-playlist`. */
    lazyPlaylist?: boolean;
    /** Parse entire playlist before downloading. Maps to `--no-lazy-playlist`. */
    noLazyPlaylist?: boolean;
    /** Don't use mpegts container for HLS. Maps to `--no-hls-use-mpegts`. */
    noHlsUseMpegts?: boolean;
    /**
     * Download only matching sections (time range or chapters).
     * Examples: "*10:15-inf", "intro", "*from-url".
     * Maps to `--download-sections REGEX`.
     */
    downloadSections?: string;
    /**
     * External downloader to use.
     * Supports: native, aria2c, axel, curl, ffmpeg, httpie, wget.
     * Maps to `--downloader [PROTO:]NAME`.
     */
    downloader?: string;
    /** Arguments to pass to external downloader. Maps to `--downloader-args NAME:ARGS`. */
    downloaderArgs?: string;
    /** Number of retries (default 10). Maps to `-R, --retries RETRIES`. */
    retries?: number;
    /** Number of retries for a fragment. Maps to `--fragment-retries RETRIES`. */
    fragmentRetries?: number;
    /** Skip unavailable fragments. Maps to `--skip-unavailable-fragments`. */
    skipUnavailableFragments?: boolean;
    /** Abort download if a fragment is unavailable. Maps to `--abort-on-unavailable-fragments`. */
    abortOnUnavailableFragment?: boolean;
    /** Keep downloaded fragments on disk. Maps to `--keep-fragments`. */
    keepFragments?: boolean;
    /** Size of download buffer (e.g., "1024", "16K"). Maps to `--buffer-size SIZE`. */
    bufferSize?: string;
    /** Don't resume partial downloads. Maps to `--no-resume-dl`. */
    noResumeDl?: boolean;
    /** Force resume of partial downloads. Maps to `-c, --continue`. */
    continueDownload?: boolean;
    /** Do not resume partial downloads. Maps to `--no-continue`. */
    noContinue?: boolean;
    /** Maximum download rate (e.g., "50K", "4.2M"). Maps to `-r, --limit-rate RATE`. */
    limitRate?: string;
    /** Extract cookies from browser. Maps to `--cookies-from-browser BROWSER`. */
    cookiesFromBrowser?: string;
    /** Don't read cookies from files. Maps to `--no-cookies`. */
    noCookies?: boolean;
    /** Number of retries for known extractor errors. Maps to `--extractor-retries RETRIES`. */
    extractorRetries?: number;
    /** Process dynamic DASH manifests. Maps to `--allow-dynamic-mpd`. */
    allowDynamicMpd?: boolean;
    /** Use mpegts container for HLS. Maps to `--hls-use-mpegts`. */
    hlsUseMpegts?: boolean;
    /**
     * Size of a chunk for chunk-based HTTP downloading.
     * May help bypass throttling (experimental).
     * Maps to `--http-chunk-size SIZE`.
     */
    httpChunkSize?: string;
    /** Skip download (useful with --print). Maps to `--no-download`. */
    noDownload?: boolean;
    /** Download playlist videos in reverse order. Maps to `--playlist-reverse`. */
    playlistReverse?: boolean;
    /** Download playlist videos in random order. Maps to `--playlist-random`. */
    playlistRandom?: boolean;
    /** Set xattr filesize. Maps to `--xattr-set-filesize`. */
    xattrSetFilesize?: boolean;
    /** Split HLS at discontinuities. Maps to `--hls-split-discontinuity`. */
    hlsSplitDiscontinuity?: boolean;
    /** File containing URLs to download. Maps to `-a, --batch-file FILE`. */
    batchFile?: string;
    /** Don't read batch file. Maps to `--no-batch-file`. */
    noBatchFile?: boolean;
    /** Limit filename length to N characters. Maps to `--trim-filenames LENGTH`. */
    trimFileNames?: number;
    /** Don't restrict characters in filenames. Maps to `--no-restrict-filenames`. */
    noRestrictFilenames?: boolean;
    /** Don't force Windows-safe filenames. Maps to `--no-windows-filenames`. */
    noWindowsFilenames?: boolean;
    /** Force resume of partially downloaded files (deprecated). */
    continue?: boolean;
    /** Write .part files. Maps to `--part`. */
    part?: boolean;
    /** Don't use .part files. Maps to `--no-part`. */
    noPart?: boolean;
    /** Use file modification time from server. Maps to `--mtime`. */
    mtime?: boolean;
    /** Don't use server mtime. Maps to `--no-mtime`. */
    noMtime?: boolean;
    /** Write video description to .description file. Maps to `--write-description`. */
    writeDescription?: boolean;
    /** Don't write description file. Maps to `--no-write-description`. */
    noWriteDescription?: boolean;
    /** Write video metadata to .info.json file. Maps to `--write-info-json`. */
    writeInfoJson?: boolean;
    /** Don't write info json. Maps to `--no-write-info-json`. */
    noWriteInfoJson?: boolean;
    /** Write playlist metadata files. Maps to `--write-playlist-metafiles`. */
    writePlaylistMetafiles?: boolean;
    /** Don't write playlist metadata. Maps to `--no-write-playlist-metafiles`. */
    noWritePlaylistMetafiles?: boolean;
    /** Remove some private fields from infojson. Maps to `--clean-info-json`. */
    cleanInfoJson?: boolean;
    /** Don't clean infojson. Maps to `--no-clean-info-json`. */
    noCleanInfoJson?: boolean;
    /** Write video comments to infojson. Maps to `--write-comments`. */
    writeComments?: boolean;
    /** Don't write comments. Maps to `--no-write-comments`. */
    noWriteComments?: boolean;
    /** JSON file with video metadata. Maps to `--load-info-json FILE`. */
    loadInfoJson?: string;
    /** File to read cookies from. Maps to `--cookies FILE`. */
    cookies?: string;
    /** Do not read cookies from browser. Maps to `--no-cookies-from-browser`. */
    noCookiesFromBrowser?: boolean;
    /** Location to store cached data. Maps to `--cache-dir DIR`. */
    cacheDir?: string;
    /** Disable caching. Maps to `--no-cache-dir`. */
    noCacheDir?: boolean;
    /** Delete all filesystem cache files. Maps to `--rm-cache-dir`. */
    rmCacheDir?: boolean;
    /**
     * Paths for different file types.
     * Maps to `-P, --paths [TYPES:]PATH`.
     */
    paths?: {
        [key: string]: string;
    } | string;
    /** Output filename template. Maps to `-o, --output TEMPLATE`. */
    output?: string;
    /** Placeholder for unavailable template. Maps to `--output-na-placeholder TEXT`. */
    outputNaPlaceholder?: string;
    /** Restrict filenames to ASCII. Maps to `--restrict-filenames`. */
    restrictFilenames?: boolean;
    /** Force filenames to be Windows-safe. Maps to `--windows-filenames`. */
    windowsFilenames?: boolean;
    /** Don't overwrite existing files. Maps to `--no-overwrites`. */
    noOverwrites?: boolean;
    /** Overwrite all video and metadata files. Maps to `--force-overwrites`. */
    forceOverwrites?: boolean;
    /** Don't overwrite the video. Maps to `--no-force-overwrites`. */
    noForceOverwrites?: boolean;
    /** Start autonumber from given value. Maps to `--autonumber-start NUMBER`. */
    autonumberStart?: number;
    /** Don't use .part files. Maps to `--no-part-files`. */
    noPartFiles?: boolean;
    /** Write thumbnail image to disk. Maps to `--write-thumbnail`. */
    writeThumbnail?: boolean;
    /** Write all thumbnail formats to disk. Maps to `--write-all-thumbnails`. */
    writeAllThumbnails?: boolean;
    /** Don't write thumbnails. Maps to `--no-write-thumbnails`. */
    noWriteThumbnails?: boolean;
    /** Convert thumbnails to format. Maps to `--convert-thumbnails FORMAT`. */
    convertThumbnails?: string;
    /** Write internet shortcut file. Maps to `--write-link`. */
    writeLink?: boolean;
    /** Write .url Windows shortcut. Maps to `--write-url-link`. */
    writeUrlLink?: boolean;
    /** Write .webloc macOS shortcut. Maps to `--write-webloc-link`. */
    writeWeblocLink?: boolean;
    /** Write .lnk Windows shortcut. Maps to `--write-lnk-link`. */
    writeLnkLink?: boolean;
    /** Write .desktop Linux shortcut. Maps to `--write-desktop-link`. */
    writeDesktopLink?: boolean;
    /** Quiet mode, print only errors. Maps to `-q, --quiet`. */
    quiet?: boolean;
    /** Ignore warnings. Maps to `--no-warnings`. */
    noWarnings?: boolean;
    /** Simulate, don't download or write files. Maps to `-s, --simulate`. */
    simulate?: boolean;
    /** Don't simulate. Maps to `--no-simulate`. */
    noSimulate?: boolean;
    /** Ignore "no video formats" errors. Maps to `--ignore-no-formats-error`. */
    ignoreNoFormatsError?: boolean;
    /** Ignore EOF errors. Maps to `--ignore-eof-error`. */
    ignoreEoFError?: boolean;
    /** Don't ignore EOF errors. Maps to `--no-ignore-eof-error`. */
    noIgnoreEoFError?: boolean;
    /** Don't emit color codes. Maps to `--no-color`. */
    noColor?: boolean;
    /** Display HTTP traffic. Maps to `--print-traffic`. */
    printTraffic?: boolean;
    /** Display progress in console title. Maps to `--console-title`. */
    consoleTitle?: boolean;
    /** Print various debugging information. Maps to `-v, --verbose`. */
    verbose?: boolean;
    /** Activate quiet mode. Maps to `--no-quiet`. */
    noQuiet?: boolean;
    /** Don't ignore "no formats" errors. Maps to `--no-ignore-no-formats-error`. */
    noIgnoreNoFormatsError?: boolean;
    /** Don't display progress bar. Maps to `--no-progress`. */
    noProgress?: boolean;
    /** Display progress bar. Maps to `--progress`. */
    progress?: boolean;
    /** Simulate and print info as JSON (single video). Maps to `-J, --dump-single-json`. */
    dumpSingleJson?: boolean;
    /** Simulate and print info as JSON. Maps to `-j, --dump-json`. */
    dumpJson?: boolean;
    /** Print JSON (equivalent to -j). Maps to `--print-json`. */
    printJson?: boolean;
    /** Don't download video. Maps to `--skip-download`. */
    skipDownload?: boolean;
    /** Quiet mode, print given template. Maps to `-O, --print [WHEN:]TEMPLATE`. */
    print?: string;
    /** Print template to file. Maps to `--print-to-file [WHEN:]TEMPLATE FILE`. */
    printToFile?: string;
    /** Force write to archive. Maps to `--force-write-archive`. */
    forceWriteArchive?: boolean;
    /** Output progress on a new line. Maps to `--newline`. */
    newline?: boolean;
    /** Template for progress outputs. Maps to `--progress-template TEMPLATE`. */
    progressTemplate?: string;
    /** Time between progress updates in seconds. Maps to `--progress-delta SEC`. */
    progressDelta?: number;
    /** Print the yt-dlp command line. Maps to `--print-command-line`. */
    debugPrintCommandLine?: boolean;
    /** Write downloaded pages to files. Maps to `--write-pages`. */
    writePages?: boolean;
    /** Dump parsed web pages. Maps to `--dump-pages`. */
    dumpPages?: boolean;
    /** Force character encoding. Maps to `--encoding ENCODING`. */
    encoding?: string;
    /** Use an unencrypted connection. Maps to `--legacy-server-connect`. */
    legacyServerConnect?: boolean;
    /** Suppress HTTPS certificate validation. Maps to `--no-check-certificates`. */
    noCheckCertificates?: boolean;
    /** Use an unencrypted connection. Maps to `--prefer-insecure`. */
    preferInsecure?: boolean;
    /** Specify additional HTTP headers. Maps to `--add-header FIELD:VALUE`. */
    addHeaders?: {
        [key: string]: string;
    };
    /** Specify custom binary path. Maps to `--bin-path PATH`. */
    binPath?: string;
    /** Work around bidi issue. Maps to `--bidi-workaround`. */
    bidiWorkaround?: boolean;
    /** Seconds to sleep between requests. Maps to `--sleep-requests SEC`. */
    sleepRequests?: number;
    /** Seconds to sleep before each download. Maps to `--sleep-interval SEC`. */
    sleepInterval?: number;
    /** Max seconds to sleep. Maps to `--max-sleep-interval SEC`. */
    maxSleepInterval?: number;
    /** Seconds to sleep before subtitle download. Maps to `--sleep-subtitles SEC`. */
    sleepSubtitles?: number;
    /** Video format code. Maps to `-f, --format FORMAT`. */
    format?: string;
    /** Sort formats by given fields. Maps to `-S, --format-sort SORTORDER`. */
    formatSort?: string[];
    /** Force format sorting. Maps to `--format-sort-force`. */
    formatSortForce?: boolean;
    /** Don't force format sorting. Maps to `--no-format-sort-force`. */
    noFormatSortForce?: boolean;
    /** Preferred audio format (mp3, wav, etc.). Maps to `--audio-format FORMAT`. */
    audioFormat?: string;
    /** Preferred video format. Maps to `--video-format FORMAT`. */
    videoFormat?: string;
    /** Prefer free container formats. Maps to `--prefer-free-formats`. */
    preferFreeFormats?: boolean;
    /** Don't prefer free formats. Maps to `--no-prefer-free-formats`. */
    noPreferFreeFormats?: boolean;
    /** Force keyframes at cuts. Maps to `--yt-dlp-force-keyframes`. */
    ytdlpForceKeyframes?: boolean;
    /** Container for merging formats (mp4, mkv, etc.). Maps to `--merge-output-format FORMAT`. */
    mergeOutputFormat?: string;
    /** Merge multiple video streams. Maps to `--video-multistreams`. */
    videoMultiStreams?: boolean;
    /** Don't merge multiple video streams. Maps to `--no-video-multistreams`. */
    noVideoMultiStreams?: boolean;
    /** Merge multiple audio streams. Maps to `--audio-multistreams`. */
    audioMultiStreams?: boolean;
    /** Don't merge multiple audio streams. Maps to `--no-audio-multistreams`. */
    noAudioMultiStreams?: boolean;
    /** Check that formats are downloadable. Maps to `--check-formats`. */
    checkFormats?: boolean;
    /** Check all formats. Maps to `--check-all-formats`. */
    checkAllFormats?: boolean;
    /** Don't check formats. Maps to `--no-check-formats`. */
    noCheckFormats?: boolean;
    /** Write subtitle files. Maps to `--write-subs`. */
    writeSubs?: boolean;
    /** Write auto-generated subtitle files. Maps to `--write-auto-subs`. */
    writeAutoSubs?: boolean;
    /** Write all available subtitles. Maps to `--write-all-subs`. */
    writeAllSubs?: boolean;
    /** Don't write subtitle files. Maps to `--no-write-subs`. */
    noWriteSubs?: boolean;
    /** List available subtitles. Maps to `--list-subs`. */
    listSubs?: boolean;
    /** Subtitle format (srt, vtt, ass, etc.). Maps to `--sub-format FORMAT`. */
    subFormat?: string;
    /** Languages of subtitles to download. Maps to `--sub-langs LANGS`. */
    subLangs?: string[];
    /** Login username. Maps to `-u, --username USERNAME`. */
    username?: string;
    /** Login password. Maps to `-p, --password PASSWORD`. */
    password?: string;
    /** Two-factor auth code. Maps to `-2, --twofactor CODE`. */
    twoFactor?: string;
    /** Use .netrc authentication. Maps to `-n, --netrc`. */
    netrc?: boolean;
    /** Video password (vimeo, etc.). Maps to `--video-password PASSWORD`. */
    videoPassword?: string;
    /** Location of .netrc file. Maps to `--netrc-location PATH`. */
    netrcLocation?: string;
    /** Command to get netrc credentials. Maps to `--netrc-cmd COMMAND`. */
    netrcCmd?: string;
    /** Client certificate file. Maps to `--client-certificate CERTFILE`. */
    clientCertificate?: string;
    /** Client certificate key file. Maps to `--client-certificate-key KEYFILE`. */
    clientCertificateKey?: string;
    /** Client certificate password. Maps to `--client-certificate-password PASSWORD`. */
    clientCertificatePassword?: string;
    /** List available MSOs. Maps to `--ap-list-mso`. */
    apListMso?: boolean;
    /** Adobe Pass MSO. Maps to `--ap-mso MSO`. */
    apMso?: string;
    /** Adobe Pass username. Maps to `--ap-username USERNAME`. */
    apUsername?: string;
    /** Adobe Pass password. Maps to `--ap-password PASSWORD`. */
    apPassword?: string;
    /** Extract and save audio. Maps to `-x, --extract-audio`. */
    extractAudio?: boolean;
    /** Audio quality (0-9 VBR or specific bitrate). Maps to `--audio-quality QUALITY`. */
    audioQuality?: string;
    /** Remux video to another container. Maps to `--remux-video FORMAT`. */
    remuxVideo?: string;
    /** Re-encode video to another format. Maps to `--recode-video FORMAT`. */
    recodeVideo?: string;
    /** Additional args for post processors. Maps to `--postprocessor-args NAME:ARGS`. */
    postprocessorArgs?: {
        [key: string]: string[];
    };
    /** Keep the original video. Maps to `-k, --keep-video`. */
    keepVideo?: boolean;
    /** Delete the original video. Maps to `--no-keep-video`. */
    noKeepVideo?: boolean;
    /** Overwrite post-processed files. Maps to `--post-overwrites`. */
    postOverwrites?: boolean;
    /** Don't overwrite post-processed files. Maps to `--no-post-overwrites`. */
    noPostOverwrites?: boolean;
    /** Embed subtitles in the video. Maps to `--embed-subs`. */
    embedSubs?: boolean;
    /** Don't embed subtitles. Maps to `--no-embed-subs`. */
    noEmbedSubs?: boolean;
    /** Embed thumbnail in the video. Maps to `--embed-thumbnail`. */
    embedThumbnail?: boolean;
    /** Don't embed thumbnail. Maps to `--no-embed-thumbnail`. */
    noEmbedThumbnail?: boolean;
    /** Embed metadata in the file. Maps to `--embed-metadata`. */
    embedMetadata?: boolean;
    /** Don't embed metadata. Maps to `--no-embed-metadata`. */
    noEmbedMetadata?: boolean;
    /** Embed chapters in the video. Maps to `--embed-chapters`. */
    embedChapters?: boolean;
    /** Don't embed chapters. Maps to `--no-embed-chapters`. */
    noEmbedChapters?: boolean;
    /** Embed info.json in video. Maps to `--embed-info-json`. */
    embedInfoJson?: boolean;
    /** Don't embed info.json. Maps to `--no-embed-info-json`. */
    noEmbedInfoJson?: boolean;
    /** Parse and modify metadata. Maps to `--parse-metadata FROM:TO`. */
    parseMetadata?: {
        [key: string]: string;
    };
    /** Replace text in a metadata field. Maps to `--replace-in-metadata FIELDS REGEX REPLACE`. */
    replaceInMetadata?: {
        [key: string]: [string, string];
    };
    /** Write extended attributes. Maps to `--xattrs`. */
    xattrs?: boolean;
    /** Concatenate playlist into a single file. Maps to `--concat-playlist POLICY`. */
    concatPlaylist?: string;
    /** Fix file problems (never, warn, detect_or_warn, force). Maps to `--fixup POLICY`. */
    fixup?: string;
    /** Location of FFmpeg binary. Maps to `--ffmpeg-location PATH`. */
    ffmpegLocation?: string;
    /** Execute command on file. Maps to `--exec CMD`. */
    exec?: string;
    /** Don't execute command. Maps to `--no-exec`. */
    noExec?: boolean;
    /** Convert subtitles to format. Maps to `--convert-subs FORMAT`. */
    convertSubs?: string;
    /** Split video by chapters. Maps to `--split-chapters`. */
    splitChapters?: boolean;
    /** Don't split by chapters. Maps to `--no-split-chapters`. */
    noSplitChapters?: boolean;
    /** Remove chapters matching regex. Maps to `--remove-chapters REGEX`. */
    removeChapters?: string;
    /** Don't remove chapters. Maps to `--no-remove-chapters`. */
    noRemoveChapters?: boolean;
    /** Force keyframes around chapters for accurate cuts. Maps to `--force-keyframes-at-cuts`. */
    forceKeyframesAtCuts?: boolean;
    /** Don't force keyframes. Maps to `--no-force-keyframes-at-cuts`. */
    noForceKeyframesAtCuts?: boolean;
    /** Enable a plugin-based postprocessor. Maps to `--use-postprocessor NAME`. */
    usePostProcessor?: string[];
    /**
     * SponsorBlock categories to create chapters for.
     * Available: sponsor, intro, outro, selfpromo, preview, filler, interaction, etc.
     * Maps to `--sponsorblock-mark CATS`.
     */
    sponsorblockMark?: string[];
    /**
     * SponsorBlock categories to remove from video.
     * Available: sponsor, intro, outro, selfpromo, preview, filler, etc.
     * Maps to `--sponsorblock-remove CATS`.
     */
    sponsorblockRemove?: string[];
    /** Template for SponsorBlock chapter titles. Maps to `--sponsorblock-chapter-title TEMPLATE`. */
    sponsorblockChapterTitle?: string;
    /** Disable all SponsorBlock options. Maps to `--no-sponsorblock`. */
    noSponsorblock?: boolean;
    /** SponsorBlock API URL. Maps to `--sponsorblock-api URL`. */
    sponsorblockApi?: string;
    /**
     * Pass arguments to specific extractors.
     * Maps to `--extractor-args IE_KEY:ARGS`.
     * @example { youtube: ['player_skip=webpage', 'max_comments=100'] }
     */
    extractorArgs?: {
        [key: string]: string[];
    };
    /** Don't process dynamic DASH manifests. Maps to `--ignore-dynamic-mpd`. */
    ignoreDynamicMpd?: boolean;
    /** Don't split HLS at discontinuities. Maps to `--no-hls-split-discontinuity`. */
    noHlsSplitDiscontinuity?: boolean;
    /** HTTP Referer header. Maps to `--referer URL`. */
    referer?: string;
    /** Custom User-Agent header. Maps to `--user-agent UA`. */
    userAgent?: string;
    /** Additional HTTP headers. Maps to `--headers FIELD:VALUE`. */
    headers?: {
        [key: string]: string;
    };
    /** List all available formats. Maps to `-F, --list-formats`. */
    listFormats?: boolean;
    /** List all available thumbnails. Maps to `--list-thumbnails`. */
    listThumbnails?: boolean;
    /**
     * Additional yt-dlp options to append.
     * @example ['--cookies', 'cookies.txt']
     */
    additionalOptions?: string[];
    /**
     * Raw yt-dlp arguments (appended last).
     * @example ['--match-filter', 'duration > 60']
     */
    rawArgs?: string[];
}

/**
 * Global configuration options for YtDlp instance.
 */
interface YtDlpOptions {
    binaryPath?: string;
    ffmpegPath?: string;
}
/**
 * Detailed information about a video.
 * Returned by `getInfo` or `dumpSingleJson`.
 */
interface VideoInfo {
    id: string;
    title: string;
    formats: VideoFormat[];
    thumbnails: VideoThumbnail[];
    thumbnail: string;
    description: string;
    upload_date: string;
    uploader: string;
    uploader_id: string;
    uploader_url: string;
    channel_id: string;
    channel_url: string;
    duration: number;
    view_count: number;
    categories: string[];
    tags: string[];
    subtitles: Subtitles;
    automatic_captions: Subtitles;
    _type: 'video';
    average_rating: number;
    age_limit: number;
    webpage_url: string;
    playable_in_embed: boolean;
    live_status: string;
    media_type: object;
    release_timestamp: object;
    _format_sort_fields: object;
    comment_count: number;
    chapters: {
        start_time: number;
        title: string;
        end_time: number;
    }[];
    heatmap: object;
    like_count: number;
    channel: string;
    channel_follower_count: number;
    channel_is_verified: boolean;
    timestamp: number;
    availability: string;
    original_url: string;
    webpage_url_basename: string;
    webpage_url_domain: string;
    extractor: string;
    extractor_key: string;
    playlist: object;
    playlist_index: object;
    display_id: string;
    fulltitle: string;
    duration_string: string;
    release_year: object;
    is_live: boolean;
    was_live: boolean;
    requested_subtitles: object;
    _has_drm: object;
    epoch: number;
    requested_downloads: object[];
    asr: number;
    filesize: number;
    format_id: string;
    format_note: string;
    source_preference: number;
    fps: number;
    audio_channels: number;
    height: number;
    quality: number;
    has_drm: boolean;
    tbr: number;
    filesize_approx: number;
    url: string;
    width: number;
    language: string;
    language_preference: number;
    preference: object;
    ext: string;
    vcodec: string;
    acodec: string;
    dynamic_range: string;
    downloader_options: {
        [v: string]: string | number;
    };
    protocol: string;
    video_ext: string;
    audio_ext: string;
    vbr: object;
    abr: object;
    resolution: string;
    aspect_ratio: number;
    http_headers: {
        [v: string]: string;
    };
    format: string;
    _version: object;
}
interface Subtitles {
    [k: string]: {
        ext: string;
        url: string;
        name: string;
    }[];
}
type InfoType = 'video' | 'playlist';
/**
 * Information about a playlist.
 */
interface PlaylistInfo {
    id: string;
    title: string;
    _type: 'playlist';
    entries: VideoInfo[];
    webpage_url: string;
    original_url: string;
    webpage_url_basename: string;
    webpage_url_domain: null | string;
    extractor: string;
    extractor_key: string;
    release_year: null | string;
    playlist_count: number;
    epoch: number;
}
/**
 * Video thumbnail information.
 */
interface VideoThumbnail {
    id: number;
    width?: string | number;
    height?: string | number;
    url: string;
}
/**
 * Video format information.
 */
interface VideoFormat {
    format_id: string;
    format_note?: string;
    ext: string;
    url: string;
    width?: number;
    height?: number;
    resolution?: string;
    filesize?: number;
    tbr?: number;
    protocol: string;
    vcodec: string;
    acodec: string;
}
/**
 * Progress update data emitted during download.
 */
interface VideoProgress {
    /** Output filename (may be '-' when streaming to stdout) */
    filename: string;
    /** Current status: 'downloading' during download, 'finished' when complete */
    status: 'downloading' | 'finished';
    /** Downloaded bytes (may be undefined when streaming) */
    downloaded?: number;
    /** Formatted downloaded bytes string */
    downloaded_str?: string;
    /** Total bytes (may be undefined when file size is unknown) */
    total?: number;
    /** Formatted total bytes string */
    total_str?: string;
    /** Download speed in bytes/sec (may be undefined) */
    speed?: number;
    /** Formatted speed string */
    speed_str?: string;
    /** Estimated time remaining in seconds */
    eta?: number;
    /** Formatted ETA string */
    eta_str?: string;
    /** Download percentage (0-100, may be undefined when total is unknown) */
    percentage?: number;
    /** Formatted percentage string */
    percentage_str?: string;
}
type VideoQuality = 'best' | '2160p' | '1440p' | '1080p' | '720p' | '480p' | '360p' | '240p' | '144p' | 'highest' | 'lowest';
type QualityOptions = {
    videoonly: VideoQuality;
    audioonly: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
    audioandvideo: 'highest' | 'lowest';
    mergevideo: VideoQuality;
};
type AudioFormat = 'aac' | 'flac' | 'mp3' | 'm4a' | 'opus' | 'vorbis' | 'wav' | 'alac';
type TypeOptions = {
    videoonly: 'mp4' | 'webm';
    audioandvideo: 'mp4' | 'webm';
    mergevideo: 'mkv' | 'mp4' | 'ogg' | 'webm' | 'flv';
    audioonly: AudioFormat;
};
type FormatKeyWord = keyof QualityOptions;
type FormatArgs<F extends string = string> = F extends FormatKeyWord ? {
    filter: F;
    quality?: QualityOptions[F];
    type?: TypeOptions[F];
} | F : string;
interface FormatOptions<F extends FormatKeyWord> extends Omit<ArgsOptions, 'format' | 'progressTemplate'> {
    format?: FormatArgs<F> | string;
    onProgress?: (p: VideoProgress) => void;
    /**
     * Callback fired with video info before download starts.
     * Uses yt-dlp's `before_dl` print hook.
     */
    beforeDownload?: (info: DownloadedVideoInfo) => void;
}
/**
 * Metadata for a downloaded file.
 */
interface FileMetadata {
    name: string;
    type: string;
    size?: number;
}
interface GetFileOptions<F extends FormatKeyWord> extends FormatOptions<F> {
    filename?: string;
    metadata?: FileMetadata;
}
/**
 * Options for fetching video information.
 */
interface InfoOptions {
    /**
     * If `true`, returns a flat list with limited information for playlist items.
     * If `false`, fetches full information for each video in the playlist.
     * @default true
     */
    flatPlaylist?: boolean;
    /**
     * A string of cookies to use for authentication.
     */
    cookies?: string;
    /**
     * Use cookies automatically fetched from the browser.
     */
    cookiesFromBrowser?: string;
    /**
     * Disable using cookies from the browser.
     */
    noCookiesFromBrowser?: boolean;
    /**
     * Disable cookies entirely (overrides other cookie options).
     */
    noCookies?: boolean;
}
type FormatTableRow = {
    formatId: string;
    extension: string;
    resolution: string;
    note: string;
    raw: string;
};
type FormatTable = {
    headers: string[];
    rows: FormatTableRow[];
    raw: string;
};
/**
 * Result of `getFormats`. Can be JSON info or a parsed table.
 */
type FormatsResult = {
    source: 'json';
    info: VideoInfo | PlaylistInfo;
    formats: VideoFormat[];
} | {
    source: 'table';
    table: FormatTable;
};
/**
 * Result of the `update` command.
 */
type UpdateResult = {
    method: 'built-in' | 'download';
    binaryPath: string;
    version?: string;
    verified?: boolean;
};
/**
 * Video information returned after download (post-processing complete).
 */
interface DownloadedVideoInfo {
    /** Video identifier */
    id: string;
    /** Video title */
    title: string;
    /** Video title ignoring live timestamp and generic title */
    fulltitle?: string;
    /** Video filename extension */
    ext?: string;
    /** A secondary title of the video */
    alt_title?: string;
    /** The description of the video */
    description?: string;
    /** An alternative identifier for the video */
    display_id?: string;
    /** Full name of the video uploader */
    uploader?: string;
    /** Nickname or id of the video uploader */
    uploader_id?: string;
    /** URL to the video uploader's profile */
    uploader_url?: string;
    /** License name the video is licensed under */
    license?: string;
    /** The creators of the video */
    creators?: string[];
    /** The creators of the video; comma-separated */
    creator?: string;
    /** UNIX timestamp of the moment the video became available */
    timestamp?: number;
    /** Video upload date in UTC (YYYYMMDD) */
    upload_date?: string;
    /** UNIX timestamp of the moment the video was released */
    release_timestamp?: number;
    /** The date (YYYYMMDD) when the video was released in UTC */
    release_date?: string;
    /** Year (YYYY) when the video or album was released */
    release_year?: number;
    /** UNIX timestamp of the moment the video was last modified */
    modified_timestamp?: number;
    /** The date (YYYYMMDD) when the video was last modified in UTC */
    modified_date?: string;
    /** Full name of the channel the video is uploaded on */
    channel?: string;
    /** Id of the channel */
    channel_id?: string;
    /** URL of the channel */
    channel_url?: string;
    /** Number of followers of the channel */
    channel_follower_count?: number;
    /** Whether the channel is verified on the platform */
    channel_is_verified?: boolean;
    /** Physical location where the video was filmed */
    location?: string;
    /** Length of the video in seconds */
    duration?: number;
    /** Length of the video (HH:mm:ss) */
    duration_string?: string;
    /** How many users have watched the video on the platform */
    view_count?: number;
    /** How many users are currently watching the video */
    concurrent_view_count?: number;
    /** Number of positive ratings of the video */
    like_count?: number;
    /** Number of negative ratings of the video */
    dislike_count?: number;
    /** Number of reposts of the video */
    repost_count?: number;
    /** Average rating given by users */
    average_rating?: number;
    /** Number of comments on the video */
    comment_count?: number;
    /** Number of times the video has been saved or bookmarked */
    save_count?: number;
    /** Age restriction for the video (years) */
    age_limit?: number;
    /** One of "not_live", "is_live", "is_upcoming", "was_live", "post_live" */
    live_status?: string;
    /** Whether this video is a live stream or a fixed-length video */
    is_live?: boolean;
    /** Whether this video was originally a live stream */
    was_live?: boolean;
    /** Whether the video is allowed to play in embedded players */
    playable_in_embed?: string;
    /** Whether the video is "private", "premium_only", "subscriber_only", "needs_auth", "unlisted" or "public" */
    availability?: string;
    /** The type of media as classified by the site */
    media_type?: string;
    /** Time in seconds where the reproduction should start */
    start_time?: number;
    /** Time in seconds where the reproduction should end */
    end_time?: number;
    /** Name of the extractor */
    extractor?: string;
    /** Key name of the extractor */
    extractor_key?: string;
    /** Unix epoch of when the information extraction was completed */
    epoch?: number;
    /** Number that will be increased with each download */
    autonumber?: number;
    /** Number that will be increased with each video */
    video_autonumber?: number;
    /** Total number of extracted items in the playlist */
    n_entries?: number;
    /** Identifier of the playlist that contains the video */
    playlist_id?: string;
    /** Name of the playlist that contains the video */
    playlist_title?: string;
    /** playlist_title if available or else playlist_id */
    playlist?: string;
    /** Total number of items in the playlist */
    playlist_count?: number;
    /** Index of the video in the playlist */
    playlist_index?: string;
    /** Position of the video in the playlist download queue */
    playlist_autonumber?: number;
    /** Full name of the playlist uploader */
    playlist_uploader?: string;
    /** Nickname or id of the playlist uploader */
    playlist_uploader_id?: string;
    /** Display name of the channel that uploaded the playlist */
    playlist_channel?: string;
    /** Identifier of the channel that uploaded the playlist */
    playlist_channel_id?: string;
    /** URL of the playlist webpage */
    playlist_webpage_url?: string;
    /** A URL to the video webpage */
    webpage_url?: string;
    /** The basename of the webpage URL */
    webpage_url_basename?: string;
    /** The domain of the webpage URL */
    webpage_url_domain?: string;
    /** The URL given by the user */
    original_url?: string;
    /** List of categories the video belongs to */
    categories?: string[];
    /** List of tags assigned to the video */
    tags?: string[];
    /** List of cast members */
    cast?: string[];
    /** Final filepath after post-processing */
    filepath?: string;
}
/**
 * Result returned by downloadAsync.
 */
interface DownloadResult {
    /** Raw command output */
    output: string;
    /** Downloaded video/audio file path */
    filePaths: string[];
    /** Video information after download (including post-processing) */
    info?: DownloadedVideoInfo[];
}
/**
 * Result emitted by the 'finish' event on DownloadProcess.
 */
interface DownloadFinishResult {
    /** Raw command output */
    output: string;
    /** Downloaded video/audio file paths */
    filePaths: string[];
    /** Video information after download (including post-processing) */
    info: DownloadedVideoInfo[];
    /** Stderr output */
    stderr: string;
}
/**
 * Information about available subtitles.
 */
interface SubtitleInfo {
    language: string;
    languages: string[];
    ext: string;
    autoCaption: boolean;
}

/**
 * Converts ArgsOptions into a string array of command-line arguments for yt-dlp.
 * @param options - yt-dlp options
 * @returns Array of command-line arguments
 */
declare function createArgs(options: ArgsOptions): string[];

declare function extractThumbnails(consoleOutput: string): VideoThumbnail[];

declare function parseFormatOptions<T extends FormatKeyWord>(format?: FormatOptions<T>['format'] | string): string[];
declare function getContentType(format?: FormatOptions<FormatKeyWord>['format']): string;
declare function getFileExtension(format?: FormatOptions<FormatKeyWord>['format']): string;

/**
 * Progress Utilities
 * Provides functions for parsing and formatting yt-dlp progress output.
 * @module utils/progress
 */

/**
 * Parses a yt-dlp progress template string into a structured VideoProgress object.
 * @param str - Raw progress output string from yt-dlp
 * @returns Parsed VideoProgress object, or undefined if parsing fails
 * @example
 * const progress = stringToProgress('~ytdlp-progress-{"status":"downloading",...}');
 * if (progress) {
 *   console.log(`${progress.percentage_str} complete`);
 * }
 */
declare function stringToProgress(str: string): VideoProgress | undefined;

declare function downloadFFmpeg(out?: string): Promise<string | undefined>;
declare function findFFmpegBinary(): string | undefined;

/**
 * HTTP Request Utilities
 * Provides functions for making HTTP/HTTPS requests and downloading files.
 * @module utils/request
 */

/**
 * Downloads a file from a URL to the local filesystem with progress reporting.
 * @param url - URL of the file to download
 * @param outputPath - Local path to save the file
 * @throws Error if download fails or HTTP status is not 200
 * @example
 * await downloadFile('https://example.com/file.zip', '/tmp/file.zip');
 */
declare function downloadFile(url: string, outputPath: string): Promise<void>;

declare function downloadYtDlp(out?: string): Promise<string>;
declare function downloadYtDlpVerified(out?: string): Promise<{
    path: string;
    verified: boolean;
    checksum?: string;
}>;
declare function findYtdlpBinary(): string | undefined;

declare const BIN_DIR: string;

/**
 * Base builder class for yt-dlp operations
 * Provides shared fluent API methods for Download and Stream builders
 */

/**
 * Abstract base builder class with shared fluent API methods.
 * Extended by Download and Stream builders.
 *
 * Note: This class extends EventEmitter without generics to avoid TypeScript
 * compatibility issues. Subclasses should use declaration merging or casting
 * for type-safe event handling.
 */
declare abstract class BaseBuilder extends EventEmitter {
    protected binaryPath: string;
    protected ffmpegPath?: string;
    protected videoUrl: string;
    protected formatValue?: FormatArgs<FormatKeyWord> | string;
    protected extraArgs: ArgsOptions;
    protected rawArgs: string[];
    protected process?: ChildProcess;
    constructor(url: string, options?: {
        binaryPath?: string;
        ffmpegPath?: string;
    });
    /**
     * Set the binary path for yt-dlp
     */
    setBinaryPath(path: string): this;
    /**
     * Set the FFmpeg binary path
     */
    setFfmpegPath(path: string): this;
    /**
     * Set the format filter (mergevideo, audioonly, videoonly, audioandvideo)
     */
    format<F extends FormatKeyWord>(format: FormatArgs<F> | string): this;
    /**
     * Set the format filter (mergevideo, audioonly, videoonly, audioandvideo)
     */
    filter<F extends FormatKeyWord>(filter: F): this;
    /**
     * Set the format quality (0-10, 0 is best)
     */
    quality<F extends FormatKeyWord>(quality: QualityOptions[F]): this;
    /**
     * Set the format type (audioonly, videoonly, audioandvideo)
     */
    type<F extends FormatKeyWord>(type: TypeOptions[F]): this;
    options(options: ArgsOptions): this;
    /**
     * Limit download rate (e.g., '1M', '500K')
     */
    rateLimit(rate: string): this;
    /**
     * Set cookies string
     */
    cookies(cookies: string): this;
    /**
     * Set cookies from browser
     */
    cookiesFromBrowser(browser: string): this;
    /**
     * Set proxy URL
     */
    proxy(url: string): this;
    /**
     * Add custom arguments
     */
    addOption(key: keyof ArgsOptions, value: unknown): this;
    /**
     * Add raw command line arguments
     */
    addArgs(...args: string[]): this;
    /**
     * Enable audio extraction
     */
    extractAudio(format?: string): this;
    /**
     * Set audio format for extraction
     */
    audioFormat(format: string): this;
    /**
     * Set audio quality (0-10, 0 is best)
     */
    audioQuality(quality: string): this;
    /**
     * Embed thumbnail in the file
     */
    embedThumbnail(): this;
    /**
     * Embed subtitles in the file
     */
    embedSubs(): this;
    /**
     * Embed metadata in the file
     */
    embedMetadata(): this;
    /**
     * Write subtitles to file
     */
    writeSubs(): this;
    /**
     * Write auto-generated subtitles
     */
    writeAutoSubs(): this;
    /**
     * Set subtitle languages
     */
    subLangs(langs: string[]): this;
    /**
     * Write thumbnail to file
     */
    writeThumbnail(): this;
    /**
     * Set username for authentication
     */
    username(user: string): this;
    /**
     * Set password for authentication
     */
    password(pass: string): this;
    /**
     * Set playlist start index
     */
    playlistStart(index: number): this;
    /**
     * Set playlist end index
     */
    playlistEnd(index: number): this;
    /**
     * Set specific playlist items
     */
    playlistItems(items: string): this;
    /**
     * Build format-related arguments from current settings
     */
    protected buildFormatArgs(): string[];
    /**
     * Build base yt-dlp arguments (common to all operations)
     */
    protected buildBaseArgs(extra?: string[]): string[];
    /**
     * Enable debug printing of the command line before execution
     */
    debugPrint(enable?: boolean): this;
    /**
     * Get the full command string (for debugging).
     * Can be used before calling run() to see exactly what will be executed.
     *
     * @example
     * ```typescript
     * const builder = ytdlp.download(url).filter('mergevideo');
     * console.log(builder.getCommand()); // Shows: /path/to/yt-dlp --format ... url
     * ```
     */
    getCommand(): string;
    /**
     * Get the command arguments array (for debugging).
     * Returns only the arguments without the binary path.
     *
     * @example
     * ```typescript
     * const builder = ytdlp.download(url).filter('mergevideo');
     * console.log(builder.getArguments()); // ['--format', '...', 'url']
     * ```
     */
    getArguments(): string[];
    /**
     * Returns the full command string.
     * Alias for getCommand(), useful for string interpolation.
     *
     * @example
     * ```typescript
     * const builder = ytdlp.download(url);
     * console.log(`Executing: ${builder}`); // Uses toString()
     * ```
     */
    toString(): string;
    /**
     * Print the command line to stderr if debugPrintCommandLine is enabled
     * Should be called before spawning the process
     */
    protected printDebugCommandLine(args: string[]): void;
    /**
     * Validates that binary path is set
     */
    protected validateBinaryPath(): void;
    /**
     * Kill the running process
     */
    kill(signal?: NodeJS.Signals | number): boolean;
    /**
     * Get the process ID
     */
    get pid(): number | undefined;
    /**
     * Build the command arguments (to be implemented by subclasses)
     */
    protected abstract buildArgs(): string[];
}

/**
 * Fluent builder classes for yt-dlp operations
 * Provides FFmpeg-like chaining API
 */

/**
 * Event map for download builder events
 */
interface DownloadBuilderEvents {
    start: [command: string];
    progress: [progress: VideoProgress];
    beforeDownload: [info: DownloadedVideoInfo];
    stdout: [data: string];
    stderr: [data: string];
    error: [error: Error];
    finish: [result: DownloadFinishResult];
}
/**
 * Fluent builder for yt-dlp download operations
 *
 * @example
 * ```typescript
 * import { Download } from 'ytdlp-nodejs';
 *
 * const result = await new Download()
 *   .url('https://youtube.com/watch?v=...')
 *   .filter('mergevideo')
 *   .quality('1080p')
 *   .type('mp4')
 *   .output('./downloads')
 *   .on('progress', (p) => console.log(`${p.percentage}%`))
 *   .run();
 *
 * console.log('Downloaded:', result.filePaths);
 * ```
 */
declare class Download extends BaseBuilder {
    private outputDir?;
    private outputPath?;
    private resultPromise?;
    constructor(url: string, options?: {
        binaryPath?: string;
        ffmpegPath?: string;
    });
    /**
     * Add a typed event listener
     */
    on<K extends keyof DownloadBuilderEvents>(event: K, listener: (...args: DownloadBuilderEvents[K]) => void): this;
    /**
     * Add a one-time typed event listener
     */
    once<K extends keyof DownloadBuilderEvents>(event: K, listener: (...args: DownloadBuilderEvents[K]) => void): this;
    /**
     * Emit a typed event
     */
    emit<K extends keyof DownloadBuilderEvents>(event: K, ...args: DownloadBuilderEvents[K]): boolean;
    /**
     * Set the output directory
     */
    output(path: string): this;
    /**
     * Set the output template (yt-dlp -o option)
     */
    setOutputTemplate(template: string): this;
    /**
     * Skip download (useful for metadata extraction)
     */
    skipDownload(): this;
    /**
     * Build the command arguments
     */
    protected buildArgs(): string[];
    /**
     * Run the download
     */
    run(): Promise<DownloadFinishResult>;
    /**
     * Make the builder directly awaitable
     */
    then<TResult1 = DownloadFinishResult, TResult2 = never>(onfulfilled?: ((value: DownloadFinishResult) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
    /**
     * Catch errors
     */
    catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<DownloadFinishResult | TResult>;
    /**
     * Finally handler
     */
    finally(onfinally?: (() => void) | null): Promise<DownloadFinishResult>;
}
/**
 * Factory function to create a new Download builder
 */
declare function createDownload(url: string, options?: {
    binaryPath?: string;
    ffmpegPath?: string;
}): Download;

/**
 * Fluent builder class for yt-dlp stream operations
 * Provides FFmpeg-like chaining API for streaming
 */

/**
 * Event map for stream builder events
 */
interface StreamBuilderEvents {
    start: [command: string];
    progress: [progress: VideoProgress];
    beforeDownload: [info: DownloadedVideoInfo];
    data: [chunk: Buffer];
    stderr: [data: string];
    error: [error: Error];
    end: [];
}
/**
 * Result type for stream operations
 */
interface StreamResult {
    /** Total bytes streamed */
    bytes: number;
    /** Duration in milliseconds */
    duration: number;
}
/**
 * Fluent builder for yt-dlp stream operations
 *
 * @example
 * ```typescript
 * import { YtDlp } from 'ytdlp-nodejs';
 * import { createWriteStream } from 'fs';
 *
 * const ytdlp = new YtDlp();
 *
 * // Stream to file - pipe() is awaitable
 * const result = await ytdlp
 *   .stream('https://youtube.com/watch?v=...')
 *   .filter('mergevideo')
 *   .quality('720p')
 *   .type('mp4')
 *   .on('progress', (p) => console.log(p.percentage_str))
 *   .pipe(createWriteStream('video.mp4'));
 *
 * console.log('Bytes:', result.bytes);
 * ```
 */
declare class Stream extends BaseBuilder {
    private passThrough?;
    private totalBytes;
    private started;
    constructor(url: string, options?: {
        binaryPath?: string;
        ffmpegPath?: string;
    });
    /**
     * Add a typed event listener
     */
    on<K extends keyof StreamBuilderEvents>(event: K, listener: (...args: StreamBuilderEvents[K]) => void): this;
    /**
     * Add a one-time typed event listener
     */
    once<K extends keyof StreamBuilderEvents>(event: K, listener: (...args: StreamBuilderEvents[K]) => void): this;
    /**
     * Emit a typed event
     */
    emit<K extends keyof StreamBuilderEvents>(event: K, ...args: StreamBuilderEvents[K]): boolean;
    /**
     * Build the command arguments
     */
    protected buildArgs(): string[];
    /**
     * Start the stream process
     */
    private startStream;
    /**
     * Pipe the stream to a writable destination and wait for completion.
     * This method is awaitable - returns a Promise.
     *
     * @example
     * ```typescript
     * const result = await ytdlp
     *   .stream(url)
     *   .filter('mergevideo')
     *   .pipe(createWriteStream('video.mp4'));
     * ```
     */
    pipe<T extends NodeJS.WritableStream>(destination: T, options?: {
        end?: boolean;
    }): Promise<StreamResult>;
    /**
     * Alias for pipe() - for backward compatibility
     */
    pipeAsync<T extends NodeJS.WritableStream>(destination: T, options?: {
        end?: boolean;
    }): Promise<StreamResult>;
    /**
     * Collect the entire stream into a Buffer
     */
    toBuffer(): Promise<Buffer>;
    /**
     * Get the underlying PassThrough stream
     */
    getStream(): PassThrough;
}
/**
 * Factory function to create a new Stream builder
 */
declare function createStream(url: string, options?: {
    binaryPath?: string;
    ffmpegPath?: string;
}): Stream;

/**
 * Fluent builder class for yt-dlp exec operations
 * Provides FFmpeg-like chaining API for executing arbitrary yt-dlp commands
 * Combines features from Download and Stream builders
 */

/**
 * Event map for exec builder events
 */
interface ExecBuilderEvents {
    start: [command: string];
    progress: [progress: VideoProgress];
    beforeDownload: [info: DownloadedVideoInfo];
    afterDownload: [info: DownloadedVideoInfo];
    stdout: [data: string];
    stderr: [data: string];
    data: [chunk: Buffer];
    error: [error: Error];
    complete: [result: ExecBuilderResult];
    end: [];
}
/**
 * Result type for exec operations (when not piping)
 */
interface ExecBuilderResult {
    /** Standard output from the command */
    stdout: string;
    /** Standard error output from the command */
    stderr: string;
    /** Exit code (null if process was terminated by signal) */
    exitCode: number | null;
    /** Full command that was executed */
    command: string;
    /** Downloaded video info (if available) */
    info?: DownloadedVideoInfo[];
    /** Output (if available) */
    output: string;
    /** File paths (if available) */
    filePaths?: string[];
}
/**
 * Result type for pipe operations
 */
interface ExecPipeResult {
    /** Total bytes streamed */
    bytes: number;
    /** Duration in milliseconds */
    duration: number;
    /** Downloaded video info (if available) */
    info?: DownloadedVideoInfo;
    /** Output (if available) */
    output: string;
}
/**
 * Fluent builder for yt-dlp exec operations
 *
 * Use this builder when you need to execute arbitrary yt-dlp commands
 * with full control over arguments, streaming, and download events.
 *
 * @example
 * ```typescript
 * import { Exec } from 'ytdlp-nodejs';
 *
 * // Execute command and get output
 * const result = await new Exec()
 *   .url('https://youtube.com/watch?v=...')
 *   .addArgs('--dump-single-json')
 *   .addArgs('--flat-playlist')
 *   .on('progress', (p) => console.log(p.status))
 *   .exec();
 *
 * console.log('Output:', result.stdout);
 * ```
 *
 * @example
 * ```typescript
 * import { createWriteStream } from 'fs';
 *
 * // Pipe to file (like Stream builder)
 * const result = await new Exec()
 *   .url('https://youtube.com/watch?v=...')
 *   .filter('mergevideo')
 *   .quality('720p')
 *   .type('mp4')
 *   .on('beforeDownload', (info) => console.log('Starting:', info.title))
 *   .on('afterDownload', (info) => console.log('Finished:', info.filepath))
 *   .pipe(createWriteStream('video.mp4'));
 *
 * console.log('Bytes:', result.bytes);
 * ```
 *
 * @example
 * ```typescript
 * // Get video title only
 * const result = await new Exec()
 *   .url('https://youtube.com/watch?v=...')
 *   .addArgs('--print', 'title')
 *   .exec();
 *
 * console.log('Title:', result.stdout.trim());
 * ```
 */
declare class Exec extends BaseBuilder {
    private passThrough?;
    private totalBytes;
    private started;
    private beforeDownloadInfo?;
    private afterDownloadInfo?;
    private output;
    private resultPromise?;
    constructor(url: string, options?: {
        binaryPath?: string;
        ffmpegPath?: string;
    });
    /**
     * Add a typed event listener
     */
    on<K extends keyof ExecBuilderEvents>(event: K, listener: (...args: ExecBuilderEvents[K]) => void): this;
    /**
     * Add a one-time typed event listener
     */
    once<K extends keyof ExecBuilderEvents>(event: K, listener: (...args: ExecBuilderEvents[K]) => void): this;
    /**
     * Emit a typed event
     */
    emit<K extends keyof ExecBuilderEvents>(event: K, ...args: ExecBuilderEvents[K]): boolean;
    /**
     * Build the command arguments
     */
    protected buildArgs(): string[];
    /**
     * Start the exec process (for pipe mode)
     */
    private startStream;
    /**
     * Pipe the stream to a writable destination and wait for completion.
     * This method is awaitable - returns a Promise.
     *
     * @example
     * ```typescript
     * import { createWriteStream } from 'fs';
     *
     * const result = await new Exec()
     *   .url(url)
     *   .filter('mergevideo')
     *   .on('beforeDownload', (info) => console.log('Starting:', info.title))
     *   .pipe(createWriteStream('video.mp4'));
     * ```
     */
    pipe<T extends NodeJS.WritableStream>(destination: T, options?: {
        end?: boolean;
    }): Promise<ExecPipeResult>;
    /**
     * Alias for pipe() - for backward compatibility
     */
    pipeAsync<T extends NodeJS.WritableStream>(destination: T, options?: {
        end?: boolean;
    }): Promise<ExecPipeResult>;
    /**
     * Collect the entire stream into a Buffer
     */
    toBuffer(): Promise<Buffer>;
    /**
     * Get the underlying PassThrough stream
     */
    getStream(): PassThrough;
    /**
     * Execute the yt-dlp command and return the result (non-pipe mode)
     */
    exec(): Promise<ExecBuilderResult>;
    /**
     * Alias for exec() - for convenience
     */
    run(): Promise<ExecBuilderResult>;
    /**
     * Make the builder directly awaitable
     */
    then<TResult1 = ExecBuilderResult, TResult2 = never>(onfulfilled?: ((value: ExecBuilderResult) => TResult1 | PromiseLike<TResult1>) | null, onrejected?: ((reason: unknown) => TResult2 | PromiseLike<TResult2>) | null): Promise<TResult1 | TResult2>;
    /**
     * Catch errors
     */
    catch<TResult = never>(onrejected?: ((reason: unknown) => TResult | PromiseLike<TResult>) | null): Promise<ExecBuilderResult | TResult>;
    /**
     * Finally handler
     */
    finally(onfinally?: (() => void) | null): Promise<ExecBuilderResult>;
}
/**
 * Factory function to create a new Exec builder
 */
declare function createExec(url: string, options?: {
    binaryPath?: string;
    ffmpegPath?: string;
}): Exec;

/**
 * Main YtDlp class - provides a high-level interface for yt-dlp operations.
 *
 * @example
 * ```typescript
 * const ytdlp = new YtDlp();
 * const info = await ytdlp.getInfoAsync('https://youtube.com/watch?v=...');
 * ```
 */
declare class YtDlp {
    binaryPath: string;
    ffmpegPath?: string;
    /**
     * Creates a new YtDlp instance.
     * @param opt - Configuration options for binary paths
     */
    constructor(opt?: YtDlpOptions);
    /**
     * Asynchronously checks if yt-dlp and optionally FFmpeg are installed.
     * @param options - Check options
     * @returns Promise resolving to true if binaries are available
     */
    checkInstallationAsync(options?: {
        ffmpeg?: boolean;
    }): Promise<boolean>;
    /**
     * Synchronously checks if yt-dlp and optionally FFmpeg are installed.
     * @param options - Check options
     * @returns true if binaries are available
     */
    checkInstallation(options?: {
        ffmpeg?: boolean;
    }): boolean;
    /**
     * Fetches video or playlist info.
     * @param url - Video or playlist URL
     * @param options - Info options
     * @returns Promise resolving to VideoInfo or PlaylistInfo
     */
    getInfoAsync<T extends InfoType>(url: string, options?: InfoOptions): Promise<T extends 'video' ? VideoInfo : PlaylistInfo>;
    /**
     * Executes yt-dlp asynchronously with the provided URL and options.
     * Uses the Exec builder internally for better control and event handling.
     *
     * @param url - Video URL
     * @param options - Execution options with optional callbacks
     * @returns Promise resolving to command output
     */
    execAsync(url: string, options?: ArgsOptions & {
        onData?: (d: string) => void;
        onProgress?: (p: VideoProgress) => void;
        onBeforeDownload?: (p: DownloadedVideoInfo) => void;
        pipeTo?: NodeJS.WritableStream;
    }): Promise<ExecBuilderResult | ExecPipeResult>;
    /**
     * Executes yt-dlp synchronously with typed events.
     *
     * Note: For a more modern fluent API with pipe support and better event handling,
     * consider using `execBuilder()` instead which returns an Exec builder instance.
     *
     * @param url - Video URL
     * @param options - Execution options
     * @returns ExecEmitter with typed 'progress', 'data', and 'close' events
     */
    exec(url: string, options?: ArgsOptions): Exec;
    /**
     * Downloads a video with fluent builder API.
     * Chain methods like .format(), .quality(), .on() and call .run() to execute.
     *
     * @param url - Video URL
     * @param options - Optional initial format options
     * @returns Download builder with fluent API
     *
     * @example
     * ```typescript
     * // With fluent API
     * const result = await ytdlp
     *   .download('https://youtube.com/watch?v=...')
     *   .filter('mergevideo')
     *   .quality('1080p')
     *   .on('progress', (p) => console.log(p.percentage_str))
     *   .run();
     *
     * // With initial options
     * const result = await ytdlp
     *   .download('https://youtube.com/watch?v=...', {
     *     format: { filter: 'mergevideo', quality: '1080p' }
     *   })
     *   .on('progress', (p) => console.log(p.percentage_str))
     *   .run();
     * ```
     */
    download<F extends FormatKeyWord>(url: string, options?: Omit<FormatOptions<F>, 'onProgress' | 'beforeDownload'>): Download;
    /**
     * Downloads a video asynchronously.
     * @param url - Video URL
     * @param options - Download options with progress callback
     * @returns Promise resolving to DownloadResult with file paths
     */
    downloadAsync<F extends FormatKeyWord>(url: string, options?: FormatOptions<F>): Promise<DownloadResult>;
    /**
     * Creates a stream with fluent builder API.
     * Chain methods to configure and use .pipe() or .pipeAsync() to stream.
     *
     * @param url - Video URL
     * @param options - Optional initial format options
     * @returns Stream builder with fluent API
     *
     * @example
     * ```typescript
     * import { createWriteStream } from 'fs';
     *
     * // Fluent builder API
     * await ytdlp
     *   .stream('https://youtube.com/watch?v=...')
     *   .filter('audioandvideo')
     *   .quality('highest')
     *   .type('mp4')
     *   .on('progress', (p) => console.log(p.percentage_str))
     *   .pipeAsync(createWriteStream('video.mp4'));
     *
     * // With initial options
     * await ytdlp
     *   .stream(url, { format: { filter: 'audioandvideo' } })
     *   .pipeAsync(createWriteStream('video.mp4'));
     * ```
     */
    stream<F extends FormatKeyWord>(url: string, options?: Omit<FormatOptions<F>, 'onProgress'>): Stream;
    /**
     * Creates an exec builder with fluent API for arbitrary yt-dlp commands.
     * Combines features from Download and Stream builders.
     *
     * Supports both execution modes (get stdout/stderr) and pipe mode (stream to file).
     *
     * @param url - Video URL
     * @param options - Optional initial format options
     * @returns Exec builder with fluent API
     *
     * @example
     * ```typescript
     * import { createWriteStream } from 'fs';
     *
     * // Execute arbitrary command and get output
     * const result = await ytdlp
     *   .execBuilder('https://youtube.com/watch?v=...')
     *   .addArgs('--dump-single-json')
     *   .exec();
     *
     * console.log('Output:', result.stdout);
     *
     * // Pipe to file with download events
     * await ytdlp
     *   .execBuilder('https://youtube.com/watch?v=...')
     *   .filter('mergevideo')
     *   .quality('720p')
     *   .on('beforeDownload', (info) => console.log('Starting:', info.title))
     *   .on('afterDownload', (info) => console.log('Finished:', info.filepath))
     *   .pipe(createWriteStream('video.mp4'));
     * ```
     */
    execBuilder<F extends FormatKeyWord>(url: string, options?: Omit<FormatOptions<F>, 'onProgress'>): Exec;
    /**
     * Downloads audio only.
     * @param url - Video URL
     * @param format - Audio format (mp3, wav, flac, etc.)
     * @param options - Additional options
     */
    downloadAudio(url: string, format?: AudioFormat, options?: ArgsOptions): Promise<DownloadResult>;
    /**
     * Downloads video with specific quality.
     * @param url - Video URL
     * @param quality - Video quality (e.g., "1080p", "720p", "best")
     * @param options - Additional options
     */
    downloadVideo(url: string, quality?: VideoQuality, options?: ArgsOptions): Promise<DownloadResult>;
    /**
     * Gets available subtitles.
     * @param url - Video URL
     * @param options - Additional options
     */
    getSubtitles(url: string, options?: ArgsOptions): Promise<SubtitleInfo[]>;
    /**
     * Fetches video comments.
     * @param url - Video URL
     * @param maxComments - Maximum comments to fetch
     * @param options - Additional options
     */
    getComments(url: string, maxComments?: number, options?: ArgsOptions): Promise<unknown[]>;
    /**
     * Gets direct media URLs.
     * @param url - Video URL
     * @param options - Args options
     * @returns Promise resolving to array of URLs
     */
    getDirectUrlsAsync(url: string, options?: ArgsOptions): Promise<string[]>;
    /**
     * Gets formats, preferring JSON with fallback to table parsing.
     * @param url - Video URL
     * @param options - Args options
     * @returns Promise resolving to FormatsResult
     */
    getFormatsAsync(url: string, options?: ArgsOptions): Promise<FormatsResult>;
    /**
     * Fetches video thumbnails.
     * @param url - Video URL
     * @returns Promise resolving to array of VideoThumbnail
     */
    getThumbnailsAsync(url: string): Promise<VideoThumbnail[]>;
    /**
     * Fetches video title.
     * @param url - Video URL
     * @returns Promise resolving to title string
     */
    getTitleAsync(url: string): Promise<string>;
    /**
     * Gets yt-dlp version.
     * @returns Promise resolving to version string
     */
    getVersionAsync(): Promise<string>;
    /**
     * Downloads FFmpeg binaries.
     * @returns Promise resolving when download is complete
     */
    downloadFFmpeg(): Promise<string | undefined>;
    /**
     * Gets video/audio content as a File object.
     * Downloads the media to memory and returns a File object.
     * @param url - Video URL
     * @param options - File options with progress callback
     * @returns Promise resolving to File object
     */
    getFileAsync<F extends FormatKeyWord>(url: string, options?: GetFileOptions<F> & {
        onProgress?: (p: VideoProgress) => void;
        onBeforeDownload?: (p: DownloadedVideoInfo) => void;
    }): Promise<File>;
    /**
     * Gets media URLs using --print urls.
     * @param url - Video URL
     * @param options - Args options
     * @returns Promise resolving to array of URLs
     */
    getUrlsAsync(url: string, options?: ArgsOptions): Promise<string[]>;
    /**
     * Updates yt-dlp to the latest version.
     * @param options - Update options
     * @returns Promise resolving to UpdateResult
     */
    updateYtDlpAsync(options?: {
        preferBuiltIn?: boolean;
        verifyChecksum?: boolean;
        outDir?: string;
    }): Promise<UpdateResult>;
    /**
     * Gets version using a specific binary path.
     * @param binaryPath - Path to the yt-dlp binary
     * @returns Promise resolving to version string
     */
    private getVersionAsyncUsingBinary;
}
/**
 * Helper utilities exported for advanced usage.
 */
declare const helpers: {
    downloadFFmpeg: typeof downloadFFmpeg;
    findFFmpegBinary: typeof findFFmpegBinary;
    PROGRESS_STRING: string;
    getContentType: typeof getContentType;
    getFileExtension: typeof getFileExtension;
    parseFormatOptions: typeof parseFormatOptions;
    stringToProgress: typeof stringToProgress;
    createArgs: typeof createArgs;
    extractThumbnails: typeof extractThumbnails;
    downloadFile: typeof downloadFile;
    BIN_DIR: string;
    downloadYtDlp: typeof downloadYtDlp;
    downloadYtDlpVerified: typeof downloadYtDlpVerified;
    findYtdlpBinary: typeof findYtdlpBinary;
};

export { type ArgsOptions, BIN_DIR, Download, type DownloadBuilderEvents, type DownloadFinishResult, type DownloadResult, type DownloadedVideoInfo, Exec, type ExecBuilderEvents, type ExecBuilderResult, type ExecPipeResult, type FormatOptions, type FormatTable, type FormatsResult, type PlaylistInfo, type QualityOptions, Stream, type StreamBuilderEvents, type StreamResult, type TypeOptions, type UpdateResult, type VideoFormat, type VideoInfo, type VideoProgress, type VideoThumbnail, YtDlp, type YtDlpOptions, createDownload, createExec, createStream as createStreamBuilder, helpers };
