import * as child_process from 'child_process';

interface ArgsOptions {
    printHelp?: boolean;
    printVersion?: boolean;
    update?: boolean;
    noUpdate?: boolean;
    updateTo?: string;
    ignoreErrors?: boolean;
    noAbortOnError?: boolean;
    abortOnError?: boolean;
    dumpUserAgent?: boolean;
    listExtractors?: boolean;
    extractorDescriptions?: boolean;
    useExtractors?: string[];
    defaultSearch?: string;
    ignoreConfig?: boolean;
    noConfigLocations?: boolean;
    configLocations?: string[];
    pluginDirs?: string[];
    noPluginDirs?: boolean;
    flatPlaylist?: boolean;
    noFlatPlaylist?: boolean;
    liveFromStart?: boolean;
    noLiveFromStart?: boolean;
    waitForVideo?: number;
    noWaitForVideo?: boolean;
    markWatched?: boolean;
    noMarkWatched?: boolean;
    color?: string;
    compatOptions?: string[];
    aliases?: string[];
    proxy?: string;
    socketTimeout?: number;
    sourceAddress?: string;
    forceIpv4?: boolean;
    forceIpv6?: boolean;
    impersonate?: string[];
    listImpersonateTargets?: boolean;
    enableFileUrls?: boolean;
    geoVerificationProxy?: string;
    xff?: string;
    playlistItems?: string;
    minFilesize?: string;
    maxFilesize?: string;
    date?: string;
    dateBefore?: string;
    dateAfter?: string;
    matchFilter?: string;
    noMatchFilters?: boolean;
    breakMatchFilters?: string;
    noBreakMatchFilters?: boolean;
    noPlaylist?: boolean;
    yesPlaylist?: boolean;
    ageLimit?: number;
    downloadArchive?: string;
    noDownloadArchive?: boolean;
    maxDownloads?: number;
    breakOnExisting?: boolean;
    noBreakOnExisting?: boolean;
    breakPerInput?: boolean;
    noBreakPerInput?: boolean;
    skipPlaylistAfterErrors?: number;
    concurrentFragments?: number;
    throttledRate?: string;
    fileAccessRetries?: number;
    retrySleep?: number;
    noKeepFragments?: boolean;
    resizeBuffer?: boolean;
    noResizeBuffer?: boolean;
    lazyPlaylist?: boolean;
    noLazyPlaylist?: boolean;
    noHlsUseMpegts?: boolean;
    downloadSections?: string;
    downloader?: string;
    downloaderArgs?: string;
    playlistStart?: number;
    playlistEnd?: number;
    matchTitle?: string;
    rejectTitle?: string;
    includeAds?: boolean;
    limitRate?: string;
    breakOnReject?: boolean;
    noDownload?: boolean;
    playlistReverse?: boolean;
    playlistRandom?: boolean;
    xattrSetFilesize?: boolean;
    hlsSplitDiscontinuity?: boolean;
    geoBypass?: boolean;
    geoBypassCountry?: string;
    geoBypassIpBlock?: string;
    batchFile?: string;
    retries?: number;
    fragmentRetries?: number;
    skipUnavailableFragments?: boolean;
    abortOnUnavailableFragment?: boolean;
    keepFragments?: boolean;
    bufferSize?: string;
    noResumeDl?: boolean;
    continueDownload?: boolean;
    noContinue?: boolean;
    cookiesFromBrowser?: string;
    noCookies?: boolean;
    extractorRetries?: number;
    allowDynamicMpd?: boolean;
    hlsUseMpegts?: boolean;
    httpChunkSize?: string;
    trimFileNames?: number;
    noRestrictFilenames?: boolean;
    noWindowsFilenames?: boolean;
    continue?: boolean;
    part?: boolean;
    noPart?: boolean;
    mtime?: boolean;
    noMtime?: boolean;
    writeDescription?: boolean;
    noWriteDescription?: boolean;
    writeInfoJson?: boolean;
    noWriteInfoJson?: boolean;
    writePlaylistMetafiles?: boolean;
    noWritePlaylistMetafiles?: boolean;
    cleanInfoJson?: boolean;
    noCleanInfoJson?: boolean;
    writeComments?: boolean;
    noWriteComments?: boolean;
    loadInfoJson?: string;
    cookies?: string;
    noCookiesFromBrowser?: boolean;
    cacheDir?: string;
    noCacheDir?: boolean;
    rmCacheDir?: boolean;
    paths?: {
        [key: string]: string;
    } | string;
    output?: string;
    outputNaPlaceholder?: string;
    restrictFilenames?: boolean;
    windowsFilenames?: boolean;
    noOverwrites?: boolean;
    forceOverwrites?: boolean;
    noForceOverwrites?: boolean;
    autonumberStart?: number;
    noPartFiles?: boolean;
    noBatchFile?: boolean;
    writeThumbnail?: boolean;
    writeAllThumbnails?: boolean;
    noWriteThumbnails?: boolean;
    convertThumbnails?: string;
    writeLink?: boolean;
    writeUrlLink?: boolean;
    writeWeblocLink?: boolean;
    writeLnkLink?: boolean;
    writeDesktopLink?: boolean;
    quiet?: boolean;
    noWarnings?: boolean;
    simulate?: boolean;
    noSimulate?: boolean;
    ignoreNoFormatsError?: boolean;
    ignoreEoFError?: boolean;
    noIgnoreEoFError?: boolean;
    noColor?: boolean;
    printTraffic?: boolean;
    consoleTitle?: boolean;
    verbose?: boolean;
    noQuiet?: boolean;
    noIgnoreNoFormatsError?: boolean;
    noProgress?: boolean;
    progress?: boolean;
    dumpSingleJson?: boolean;
    dumpJson?: boolean;
    printJson?: boolean;
    skipDownload?: boolean;
    print?: string;
    printToFile?: string;
    forceWriteArchive?: boolean;
    newline?: boolean;
    progressTemplate?: string;
    progressDelta?: number;
    encoding?: string;
    legacyServerConnect?: boolean;
    noCheckCertificates?: boolean;
    preferInsecure?: boolean;
    addHeaders?: {
        [key: string]: string;
    };
    binPath?: string;
    bidiWorkaround?: boolean;
    sleepRequests?: number;
    sleepInterval?: number;
    maxSleepInterval?: number;
    sleepSubtitles?: number;
    format?: string;
    formatSort?: string[];
    formatSortForce?: boolean;
    noFormatSortForce?: boolean;
    audioFormat?: string;
    videoFormat?: string;
    preferFreeFormats?: boolean;
    noPreferFreeFormats?: boolean;
    ytdlpForceKeyframes?: boolean;
    mergeOutputFormat?: string;
    videoMultiStreams?: boolean;
    noVideoMultiStreams?: boolean;
    audioMultiStreams?: boolean;
    noAudioMultiStreams?: boolean;
    checkFormats?: boolean;
    checkAllFormats?: boolean;
    noCheckFormats?: boolean;
    writeSubs?: boolean;
    writeAutoSubs?: boolean;
    writeAllSubs?: boolean;
    noWriteSubs?: boolean;
    listSubs?: boolean;
    subFormat?: string;
    subLangs?: string[];
    username?: string;
    password?: string;
    twoFactor?: string;
    netrc?: boolean;
    videoPassword?: string;
    netrcLocation?: string;
    netrcCmd?: string;
    apListMso?: boolean;
    clientCertificate?: string;
    clientCertificateKey?: string;
    clientCertificatePassword?: string;
    apMso?: string;
    apUsername?: string;
    apPassword?: string;
    extractAudio?: boolean;
    audioQuality?: string;
    remuxVideo?: string;
    recodeVideo?: string;
    postprocessorArgs?: {
        [key: string]: string[];
    };
    keepVideo?: boolean;
    noKeepVideo?: boolean;
    postOverwrites?: boolean;
    noPostOverwrites?: boolean;
    embedSubs?: boolean;
    noEmbedSubs?: boolean;
    embedThumbnail?: boolean;
    noEmbedThumbnail?: boolean;
    embedMetadata?: boolean;
    noEmbedMetadata?: boolean;
    embedChapters?: boolean;
    noEmbedChapters?: boolean;
    embedInfoJson?: boolean;
    noEmbedInfoJson?: boolean;
    parseMetadata?: {
        [key: string]: string;
    };
    replaceInMetadata?: {
        [key: string]: [string, string];
    };
    xattrs?: boolean;
    concatPlaylist?: string;
    fixup?: string;
    ffmpegLocation?: string;
    exec?: string;
    noExec?: boolean;
    convertSubs?: string;
    splitChapters?: boolean;
    noSplitChapters?: boolean;
    removeChapters?: string;
    noRemoveChapters?: boolean;
    forceKeyframesAtCuts?: boolean;
    noForceKeyframesAtCuts?: boolean;
    usePostProcessor?: string[];
    sponsorblockMark?: string[];
    sponsorblockRemove?: string[];
    sponsorblockChapterTitle?: string;
    noSponsorblock?: boolean;
    sponsorblockApi?: string;
    extractorArgs?: {
        [key: string]: string[];
    };
    ignoreDynamicMpd?: boolean;
    dumpPages?: boolean;
    noHlsSplitDiscontinuity?: boolean;
    referer?: string;
    userAgent?: string;
    headers?: {
        [key: string]: string;
    };
    debugPrintCommandLine?: boolean;
    writePages?: boolean;
    listFormats?: boolean;
    listThumbnails?: boolean;
    additionalOptions?: string[];
}
interface YtDlpOptions {
    binaryPath?: string;
    ffmpegPath?: string;
}
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;
    average_rating: number;
    categories: string[];
    tags: string[];
}
interface VideoThumbnail {
    id: number;
    width?: string | number;
    height?: string | number;
    url: string;
}
interface VideoFormat {
    format_id: string;
    ext: string;
    url: string;
    width?: number;
    height?: number;
    resolution?: string;
    filesize?: number;
    tbr?: number;
    protocol: string;
    vcodec: string;
    acodec: string;
}
interface VideoProgress {
    status: 'downloading' | 'finished';
    downloaded: number;
    downloaded_str: string;
    total: number;
    total_str: string;
    speed: number;
    speed_str: string;
    eta: number;
    eta_str: string;
    percentage: number;
    percentage_str: string;
}
type VideoQuality = '2160p' | '1440p' | '1080p' | '720p' | '480p' | '360p' | '240p' | '144p' | 'highest' | 'lowest';
type DownloadQualityOptions = {
    videoonly: VideoQuality;
    audioonly: 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
    audioandvideo: 'highest' | 'lowest';
    mergevideo: VideoQuality;
};
type DownloadTypeOptions = {
    videoonly: 'mp4' | 'webm';
    audioandvideo: 'mp4' | 'webm';
    mergevideo: 'mkv' | 'mp4' | 'ogg' | 'webm' | 'flv';
    audioonly: 'aac' | 'flac' | 'mp3' | 'm4a' | 'opus' | 'vorbis' | 'wav' | 'alac';
};
type DownloadKeyWord = keyof DownloadQualityOptions;
type StreamKeyWord = keyof StreamQualityOptions;
type StreamQualityOptions = {
    videoonly: VideoQuality;
    audioonly: 'highest' | 'lowest';
    audioandvideo: 'highest' | 'lowest';
};
interface DownloadOptions<F extends DownloadKeyWord> extends Omit<ArgsOptions, 'format' | 'progressTemplate'> {
    format?: {
        filter: F;
        quality?: DownloadQualityOptions[F];
        type?: DownloadTypeOptions[F];
    } | string;
    onProgress?: (p: VideoProgress) => void;
}
interface StreamOptions<F extends StreamKeyWord> extends Omit<ArgsOptions, 'format' | 'progressTemplate' | 'output'> {
    format?: {
        filter: F;
        quality?: StreamQualityOptions[F];
    } | string;
    onProgress?: (p: VideoProgress) => void;
}
type PipeResponse = {
    pipe: (destination: NodeJS.WritableStream, options?: {
        end?: boolean;
    }) => NodeJS.WritableStream;
    pipeAsync: (destination: NodeJS.WritableStream, options?: {
        end?: boolean;
    }) => Promise<NodeJS.WritableStream>;
};
interface FileMetadata {
    name: string;
    type: string;
    size?: number;
}
interface GetFileOptions<F extends DownloadKeyWord> extends DownloadOptions<F> {
    filename?: string;
    metadata?: FileMetadata;
}

declare const BIN_DIR: string;
declare class YtDlp {
    private readonly binaryPath;
    private readonly ffmpegPath?;
    constructor(opt?: YtDlpOptions);
    private getDefaultBinaryPath;
    checkInstallationAsync(options?: {
        ffmpeg?: boolean;
    }): Promise<boolean>;
    checkInstallation(options?: {
        ffmpeg?: boolean;
    }): boolean;
    execAsync(url: string, options?: ArgsOptions & {
        onData?: (d: string) => void;
        onProgress?: (p: VideoProgress) => void;
    }): Promise<string>;
    exec(url: string, options?: ArgsOptions): child_process.ChildProcessWithoutNullStreams;
    private _execute;
    private _executeAsync;
    private buildArgs;
    download<F extends DownloadKeyWord>(url: string, options?: Omit<DownloadOptions<F>, 'onProgress'>): child_process.ChildProcessWithoutNullStreams;
    downloadAsync<F extends DownloadKeyWord>(url: string, options?: DownloadOptions<F>): Promise<string>;
    stream<F extends StreamKeyWord>(url: string, options?: StreamOptions<F>): PipeResponse;
    getInfoAsync(url: string): Promise<VideoInfo>;
    getThumbnailsAsync(url: string): Promise<VideoThumbnail[]>;
    getTitleAsync(url: string): Promise<string>;
    downloadFFmpeg(): Promise<string | undefined>;
    getFileAsync<F extends DownloadKeyWord>(url: string, options?: GetFileOptions<F> & {
        onProgress?: (p: VideoProgress) => void;
    }): Promise<File>;
}

export { type ArgsOptions, BIN_DIR, type DownloadOptions, type StreamOptions, type VideoInfo, type VideoProgress, type VideoThumbnail, YtDlp, type YtDlpOptions };
