246 lines
7.9 KiB
TypeScript
246 lines
7.9 KiB
TypeScript
interface AppConfig {
|
|
client_id?: string;
|
|
client_secret?: string;
|
|
download_path?: string;
|
|
streamers?: string[];
|
|
theme?: string;
|
|
download_mode?: 'parts' | 'full';
|
|
part_minutes?: number;
|
|
language?: 'de' | 'en';
|
|
filename_template_vod?: string;
|
|
filename_template_parts?: string;
|
|
filename_template_clip?: string;
|
|
smart_queue_scheduler?: boolean;
|
|
performance_mode?: 'stability' | 'balanced' | 'speed';
|
|
prevent_duplicate_downloads?: boolean;
|
|
persist_queue_on_restart?: boolean;
|
|
metadata_cache_minutes?: number;
|
|
parallel_downloads?: number;
|
|
auto_resume_queue_on_startup?: boolean;
|
|
downloaded_vod_ids?: string[];
|
|
streamlink_quality?: string;
|
|
notify_on_each_completion?: boolean;
|
|
streamlink_disable_ads?: boolean;
|
|
[key: string]: unknown;
|
|
}
|
|
|
|
interface VOD {
|
|
id: string;
|
|
title: string;
|
|
created_at: string;
|
|
duration: string;
|
|
thumbnail_url: string;
|
|
url: string;
|
|
view_count: number;
|
|
stream_id?: string;
|
|
}
|
|
|
|
interface CustomClip {
|
|
startSec: number;
|
|
durationSec: number;
|
|
startPart: number;
|
|
filenameFormat: 'simple' | 'timestamp' | 'template' | 'parts';
|
|
filenameTemplate?: string;
|
|
}
|
|
|
|
interface MergeGroupItem {
|
|
url: string;
|
|
title: string;
|
|
date: string;
|
|
streamer: string;
|
|
duration_str: string;
|
|
}
|
|
|
|
interface MergeGroup {
|
|
items: MergeGroupItem[];
|
|
mergePhase: 'downloading' | 'merging' | 'splitting' | 'cleanup' | 'done';
|
|
currentItemIndex: number;
|
|
downloadedFiles: Record<number, string>;
|
|
mergedFile?: string;
|
|
splitFiles?: string[];
|
|
totalDurationSec?: number;
|
|
}
|
|
|
|
interface QueueItem {
|
|
id: string;
|
|
title: string;
|
|
url: string;
|
|
date: string;
|
|
streamer: string;
|
|
duration_str: string;
|
|
status: 'pending' | 'downloading' | 'paused' | 'completed' | 'error';
|
|
progress: number;
|
|
currentPart?: number;
|
|
totalParts?: number;
|
|
speed?: string;
|
|
eta?: string;
|
|
downloadedBytes?: number;
|
|
totalBytes?: number;
|
|
progressStatus?: string;
|
|
last_error?: string;
|
|
customClip?: CustomClip;
|
|
mergeGroup?: MergeGroup;
|
|
outputFiles?: string[];
|
|
}
|
|
|
|
interface DownloadProgress {
|
|
id: string;
|
|
progress: number;
|
|
speed: string;
|
|
speedBytesPerSec?: number;
|
|
eta: string;
|
|
status: string;
|
|
currentPart?: number;
|
|
totalParts?: number;
|
|
downloadedBytes?: number;
|
|
totalBytes?: number;
|
|
}
|
|
|
|
interface RuntimeMetricsSnapshot {
|
|
cacheHits: number;
|
|
cacheMisses: number;
|
|
duplicateSkips: number;
|
|
retriesScheduled: number;
|
|
retriesExhausted: number;
|
|
integrityFailures: number;
|
|
downloadsStarted: number;
|
|
downloadsCompleted: number;
|
|
downloadsFailed: number;
|
|
downloadedBytesTotal: number;
|
|
lastSpeedBytesPerSec: number;
|
|
avgSpeedBytesPerSec: number;
|
|
activeItemId: string | null;
|
|
activeItemTitle: string | null;
|
|
lastErrorClass: string | null;
|
|
lastRetryDelaySeconds: number;
|
|
timestamp: string;
|
|
queue: {
|
|
pending: number;
|
|
downloading: number;
|
|
paused: number;
|
|
completed: number;
|
|
error: number;
|
|
total: number;
|
|
};
|
|
caches: {
|
|
loginToUserId: number;
|
|
vodList: number;
|
|
clipInfo: number;
|
|
};
|
|
config: {
|
|
performanceMode: 'stability' | 'balanced' | 'speed';
|
|
smartScheduler: boolean;
|
|
metadataCacheMinutes: number;
|
|
duplicatePrevention: boolean;
|
|
};
|
|
}
|
|
|
|
interface VideoInfo {
|
|
duration: number;
|
|
width: number;
|
|
height: number;
|
|
fps: number;
|
|
}
|
|
|
|
interface ClipDialogData {
|
|
url: string;
|
|
title: string;
|
|
date: string;
|
|
streamer: string;
|
|
duration: string;
|
|
}
|
|
|
|
interface UpdateInfo {
|
|
version: string;
|
|
releaseDate?: string;
|
|
releaseName?: string;
|
|
releaseNotes?: string;
|
|
}
|
|
|
|
interface UpdateDownloadProgress {
|
|
percent: number;
|
|
bytesPerSecond: number;
|
|
transferred: number;
|
|
total: number;
|
|
}
|
|
|
|
interface PreflightChecks {
|
|
internet: boolean;
|
|
streamlink: boolean;
|
|
ffmpeg: boolean;
|
|
ffprobe: boolean;
|
|
downloadPathWritable: boolean;
|
|
}
|
|
|
|
interface PreflightResult {
|
|
ok: boolean;
|
|
autoFixApplied: boolean;
|
|
checks: PreflightChecks;
|
|
messages: string[];
|
|
timestamp: string;
|
|
}
|
|
|
|
interface ApiBridge {
|
|
getConfig(): Promise<AppConfig>;
|
|
saveConfig(config: Partial<AppConfig>): Promise<AppConfig>;
|
|
login(): Promise<boolean>;
|
|
getUserId(username: string): Promise<string | null>;
|
|
getVODs(userId: string, forceRefresh?: boolean): Promise<VOD[]>;
|
|
getQueue(): Promise<QueueItem[]>;
|
|
addToQueue(item: Omit<QueueItem, 'id' | 'status' | 'progress'>): Promise<QueueItem[]>;
|
|
removeFromQueue(id: string): Promise<QueueItem[]>;
|
|
reorderQueue(orderIds: string[]): Promise<QueueItem[]>;
|
|
clearCompleted(): Promise<QueueItem[]>;
|
|
retryFailedDownloads(): Promise<QueueItem[]>;
|
|
retryQueueItem(id: string): Promise<QueueItem[]>;
|
|
createMergeGroup(itemIds: string[]): Promise<QueueItem[]>;
|
|
startDownload(): Promise<boolean>;
|
|
pauseDownload(): Promise<boolean>;
|
|
cancelDownload(): Promise<boolean>;
|
|
isDownloading(): Promise<boolean>;
|
|
downloadClip(url: string): Promise<{ success: boolean; error?: string }>;
|
|
selectFolder(): Promise<string | null>;
|
|
selectVideoFile(): Promise<string | null>;
|
|
selectMultipleVideos(): Promise<string[] | null>;
|
|
saveVideoDialog(defaultName: string): Promise<string | null>;
|
|
openFolder(path: string): Promise<void>;
|
|
openFile(path: string): Promise<boolean>;
|
|
showInFolder(path: string): Promise<boolean>;
|
|
openDebugLogFile(): Promise<boolean>;
|
|
checkFolderWritable(path: string): Promise<boolean>;
|
|
getVideoInfo(filePath: string): Promise<VideoInfo | null>;
|
|
extractFrame(filePath: string, timeSeconds: number): Promise<string | null>;
|
|
cutVideo(inputFile: string, startTime: number, endTime: number): Promise<{ success: boolean; outputFile: string | null }>;
|
|
mergeVideos(inputFiles: string[], outputFile: string): Promise<{ success: boolean; outputFile: string | null }>;
|
|
getVersion(): Promise<string>;
|
|
checkUpdate(): Promise<{ checking?: boolean; error?: boolean; skipped?: 'ready-to-install' | 'in-progress' | 'throttled' | 'error' | string }>;
|
|
downloadUpdate(): Promise<{ downloading?: boolean; error?: boolean; skipped?: 'ready-to-install' | 'in-progress' | 'error' | string }>;
|
|
installUpdate(): Promise<void>;
|
|
openExternal(url: string): Promise<void>;
|
|
runPreflight(autoFix: boolean): Promise<PreflightResult>;
|
|
getDebugLog(lines: number): Promise<string>;
|
|
getRuntimeMetrics(): Promise<RuntimeMetricsSnapshot>;
|
|
exportRuntimeMetrics(): Promise<{ success: boolean; cancelled?: boolean; error?: string; filePath?: string }>;
|
|
resetDownloadedVodIds(): Promise<{ success: boolean; removedCount: number }>;
|
|
markVodDownloaded(vodId: string, mark: boolean): Promise<{ success: boolean }>;
|
|
exportConfig(): Promise<{ success: boolean; cancelled?: boolean; error?: string; filePath?: string }>;
|
|
importConfig(): Promise<{ success: boolean; cancelled?: boolean; error?: string; filePath?: string }>;
|
|
onDownloadProgress(callback: (progress: DownloadProgress) => void): void;
|
|
onQueueUpdated(callback: (queue: QueueItem[]) => void): void;
|
|
onQueueDuplicateSkipped(callback: (payload: { title: string; streamer: string; url: string }) => void): void;
|
|
onDownloadStarted(callback: () => void): void;
|
|
onDownloadFinished(callback: () => void): void;
|
|
onCutProgress(callback: (percent: number) => void): void;
|
|
onMergeProgress(callback: (percent: number) => void): void;
|
|
onUpdateChecking(callback: () => void): void;
|
|
onUpdateAvailable(callback: (info: UpdateInfo) => void): void;
|
|
onUpdateNotAvailable(callback: () => void): void;
|
|
onUpdateDownloadProgress(callback: (progress: UpdateDownloadProgress) => void): void;
|
|
onUpdateDownloaded(callback: (info: UpdateInfo) => void): void;
|
|
onUpdateError(callback: (payload: { message: string }) => void): void;
|
|
}
|
|
|
|
interface Window {
|
|
api: ApiBridge;
|
|
}
|