UNPKG

@bililive-tools/manager

Version:
134 lines (133 loc) 6.15 kB
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 };