import { Emitter } from "mitt";
import { ChannelId, Message } from "./common.js";
import { RecorderCache } from "./cache.js";
import { RecorderCreateOpts, Recorder, SerializedRecorder, RecordHandle, DebugLog, Progress } from "./recorder.js";
import type { XmlStreamStats } from "./xml_stream_controller.js";
import { AnyObject, UnknownObject } from "./utils.js";
import { StreamManager } from "./downloader/streamManager.js";
export interface ProviderCheckConfig {
    /** 检查循环间隔（毫秒） */
    autoCheckInterval?: number;
    /** 最大并发检查线程数 */
    maxThreadCount?: number;
    /** 每次检查之间的等待时间（毫秒） */
    waitTime?: number;
}
export interface RecorderProvider<E extends AnyObject> {
    id: string;
    name: string;
    siteURL: string;
    matchURL: (this: RecorderProvider<E>, channelURL: string) => boolean;
    resolveChannelInfoFromURL: (this: RecorderProvider<E>, channelURL: string) => Promise<{
        id: ChannelId;
        title: string;
        owner: string;
        uid?: number | string;
        avatar?: string;
    } | null>;
    createRecorder: (this: RecorderProvider<E>, opts: Omit<RecorderCreateOpts<E>, "providerId">) => Recorder<E>;
    fromJSON: <T extends SerializedRecorder<E>>(this: RecorderProvider<E>, json: T) => Recorder<E>;
    setFFMPEGOutputArgs: (this: RecorderProvider<E>, args: string[]) => void;
}
declare const configurableProps: readonly ["savePathRule", "autoRemoveSystemReservedChars", "autoCheckInterval", "maxThreadCount", "waitTime", "ffmpegOutputArgs", "biliBatchQuery", "recordRetryImmediately", "providerCheckConfig"];
type ConfigurableProp = (typeof configurableProps)[number];
export interface RecorderManager<ME extends UnknownObject, P extends RecorderProvider<AnyObject> = RecorderProvider<UnknownObject>, PE extends AnyObject = GetProviderExtra<P>, E extends AnyObject = ME & PE> extends Emitter<{
    error: {
        source: string;
        err: unknown;
    };
    RecordStart: {
        recorder: SerializedRecorder<E>;
        recordHandle: RecordHandle;
    };
    RecordSegment: {
        recorder: SerializedRecorder<E>;
        recordHandle?: RecordHandle;
    };
    videoFileCreated: {
        recorder: SerializedRecorder<E>;
        filename: string;
        cover?: string;
        rawFilename?: string;
    };
    videoFileCompleted: {
        recorder: SerializedRecorder<E>;
        filename: string;
        stats?: XmlStreamStats;
    };
    RecorderProgress: {
        recorder: SerializedRecorder<E>;
        progress: Progress;
    };
    RecoderLiveStart: {
        recorder: Recorder<E>;
    };
    RecordStop: {
        recorder: SerializedRecorder<E>;
        recordHandle: RecordHandle;
        reason?: string;
    };
    Message: {
        recorder: SerializedRecorder<E>;
        message: Message;
    };
    RecorderUpdated: {
        recorder: SerializedRecorder<E>;
        keys: (string | keyof Recorder<E>)[];
    };
    RecorderAdded: SerializedRecorder<E>;
    RecorderRemoved: SerializedRecorder<E>;
    RecorderDebugLog: DebugLog & {
        recorder: Recorder<E>;
    };
    Updated: ConfigurableProp[];
}> {
    providers: P[];
    getChannelURLMatchedRecorderProviders: (this: RecorderManager<ME, P, PE, E>, channelURL: string) => P[];
    recorders: Recorder<E>[];
    addRecorder: (this: RecorderManager<ME, P, PE, E>, opts: RecorderCreateOpts<E>) => Recorder<E>;
    removeRecorder: (this: RecorderManager<ME, P, PE, E>, recorder: Recorder<E>) => void;
    getRecorder: (this: RecorderManager<ME, P, PE, E>, id: string) => Recorder<E> | null;
    startRecord: (this: RecorderManager<ME, P, PE, E>, id: string, opts?: {
        ignoreDataLimit?: boolean;
    }) => Promise<Recorder<E> | undefined>;
    stopRecord: (this: RecorderManager<ME, P, PE, E>, id: string) => Promise<Recorder<E> | undefined>;
    cutRecord: (this: RecorderManager<ME, P, PE, E>, id: string) => Promise<Recorder<E> | undefined>;
    autoCheckInterval: number;
    maxThreadCount: number;
    waitTime: number;
    isCheckLoopRunning: boolean;
    startCheckLoop: (this: RecorderManager<ME, P, PE, E>) => void;
    stopCheckLoop: (this: RecorderManager<ME, P, PE, E>) => void;
    savePathRule: string;
    autoRemoveSystemReservedChars: boolean;
    ffmpegOutputArgs: string;
    /** b站使用批量查询接口 */
    biliBatchQuery: boolean;
    /** 下播延迟检查 */
    recordRetryImmediately: boolean;
    /** 缓存系统 */
    cache: RecorderCache;
    /** 每个 provider 的检查配置 */
    providerCheckConfig: Record<string, ProviderCheckConfig>;
    /** 获取指定 provider 的检查配置（自动 fallback 到全局配置） */
    getProviderCheckConfig: (this: RecorderManager<ME, P, PE, E>, providerId: string) => Required<ProviderCheckConfig>;
}
export type RecorderManagerCreateOpts<ME extends AnyObject = UnknownObject, P extends RecorderProvider<AnyObject> = RecorderProvider<UnknownObject>, PE extends AnyObject = GetProviderExtra<P>, E extends AnyObject = ME & PE> = Partial<Pick<RecorderManager<ME, P, PE, E>, ConfigurableProp>> & {
    providers: P[];
    /** 自定义缓存实现，不提供则使用默认的内存缓存 */
    cache?: RecorderCache;
    /** 每个 provider 的检查配置，key 为 provider.id */
    providerCheckConfig?: Record<string, ProviderCheckConfig>;
};
export declare function createRecorderManager<ME extends AnyObject = UnknownObject, P extends RecorderProvider<AnyObject> = RecorderProvider<UnknownObject>, PE extends AnyObject = GetProviderExtra<P>, E extends AnyObject = ME & PE>(opts: RecorderManagerCreateOpts<ME, P, PE, E>): RecorderManager<ME, P, PE, E>;
export declare function genSavePathFromRule<ME extends AnyObject, P extends RecorderProvider<AnyObject>, PE extends AnyObject, E extends AnyObject>(manager: RecorderManager<ME, P, PE, E>, recorder: Recorder<E>, extData: {
    owner: string;
    title: string;
    startTime: number;
    liveStartTime: Date;
    recordStartTime: Date;
    extraMs?: boolean;
}): string;
export type GetProviderExtra<P> = P extends RecorderProvider<infer E> ? E : never;
export { StreamManager };
