/** * FileSource - Uses LRU cache for chunked file access with preloading * * For local File objects, we read the file in chunks and cache them * using an LRU cache. Chunks are preloaded sequentially to fill the cache. */ import type { SourceAdapter } from "./SourceAdapter"; import { LRUCache } from "../cache/LRUCache"; export declare class FileSource implements SourceAdapter { private file; private cache; private size; private position; private preloadPromise; private sourceKey; private currentTime; private duration; private preloadOffset; private preloadAbort; private totalBytesRead; private lastSpeedBytes; private lastSpeedTime; private currentReadSpeed; private readStartTime; private onRevokedCallback; private revokedFired; private preloadComplete; private onPreloadCompleteCallback; constructor(file: File, cache?: LRUCache | null); /** * Register a callback fired the first time a file read times out (likely * revocation by mobile browser). Lets the host surface a re-pick UI. */ setOnRevoked(cb: (info: { offset: number; length: number; reason: string; }) => void): void; /** * Register a one-shot callback fired when the initial preload pass settles. * If preload is already complete, fires synchronously. */ setOnPreloadComplete(cb: () => void): void; /** * True once the initial preload pass has settled (success, error, or abort). */ isPreloadComplete(): boolean; /** * Get the total size of the source in bytes */ getSize(): Promise; /** * Update preload position based on current playback time * @param currentTime Current playback time in seconds * @param duration Total duration in seconds */ updatePreloadPosition(currentTime: number, duration: number): void; /** * Read data from the source at the given offset * @param offset Byte offset to start reading from * @param length Number of bytes to read * @returns ArrayBuffer containing the requested data */ read(offset: number, length: number): Promise; /** * Seek to a position (for sources that need state) * @param offset The byte offset to seek to * @returns The actual offset seeked to */ seek(offset: number): number; /** * Get the current read position */ getPosition(): number; /** * Get disk read stats for nerd stats overlay */ getDiskStats(): { totalBytes: number; currentSpeed: number; elapsed: number; }; /** * Close the source and release resources */ close(): void; /** * Get a unique identifier for this source (used for caching) */ getKey(): string; /** * Start preloading chunks into cache * This method is idempotent - multiple calls will share the same preload promise */ private startPreload; /** * Preload chunks around current position (ahead for playback, behind for seeking) */ private preloadChunks; /** * Check if preloading should stop (cache full) */ private shouldStopPreload; /** * Read a chunk from file and cache it * * Mobile browsers (iOS Safari, Android Chrome) can revoke the underlying File * handle after long backgrounding or under memory pressure. The Blob then * silently hangs on read instead of rejecting, which stalls the demuxer * forever. Race against a timeout and surface a clear error so the UI can * prompt the user to re-pick the file. */ private readChunkFromFile; /** * Read from file (not cached) and optionally cache it */ /** * Read from file (not cached) and optionally cache it * Enforces strict CHUNK_SIZE alignment to prevent cache duplication */ private readFromFile; /** * Construct result from overlapping cached chunks */ private constructFromOverlapping; } /** * Factory function to create a FileSource */ export declare function createFileSource(file: File, cache?: LRUCache | null): Promise; //# sourceMappingURL=FileSource.d.ts.map