/** * VAVTrackStream — progressive loader for one VAV UV-appearance `.af` track. * Framework-agnostic (no three, no WebCodecs): it streams the track with a plain `fetch`, fills * a preallocated buffer, and answers "is frame i decodable yet?" from the manifest's frame index. * * Samples are stored in decode order at contiguous offsets, so availability is a prefix test: * frame i is decodable once `offset + length <= receivedBytes`. That lets playback start after * the first GOP instead of after the whole download — no range requests, no MSE, any static host. * * It also builds the pre-parsed manifest object {@link AFDecoder} consumes (`{ manifest }`), * with per-frame `data` views into the shared buffer — zero-copy, same contract as `parseAF`. * * @module VAVTrackStream */ import { type AFManifest } from '../Video/AFContainer.cjs'; import type { VAVTrackContainer } from './VAVManifest.cjs'; /** Minimal streaming fetch response consumed by {@link VAVTrackStream}. */ export interface VAVTrackFetchResponse { readonly ok: boolean; readonly status: number; readonly headers?: { get(name: string): string | null; }; readonly body?: ReadableStream | null; arrayBuffer?: () => Promise; } /** Injectable fetch contract used by tests and non-browser runtimes. */ export type VAVTrackFetch = (input: string, init?: RequestInit) => PromiseLike; /** Construction options for one progressively fetched track. */ export interface VAVTrackStreamOptions { frameRate?: number; fetchImpl?: VAVTrackFetch; } interface VAVTrackWaiter { end: number; resolve: () => void; } /** * Stream one VAV track and track per-frame byte availability. * * @class VAVTrackStream * @short Progressive `.af` track fetch with frame-availability queries. * @category VAV */ export declare class VAVTrackStream { url: string; track: VAVTrackContainer; receivedBytes: number; totalBytes: number; _buffer: Uint8Array; _waiters: VAVTrackWaiter[]; _aborter: AbortController | null; _disposed: boolean; _suspended: boolean; _completed: boolean; _generation: number; _fetchImpl: VAVTrackFetch; _resumePromise: Promise | null; _resolveDone: () => void; _rejectDone: (error: unknown) => void; manifest: AFManifest; done: Promise; /** * @param {string} url - Absolute or manifest-relative track URL (already resolved). * @param {Object} track - The normalized track descriptor from {@link parseVAVManifest}. * @param {Object} [options={}] * @param {number} [options.frameRate=30] - Clip frame rate (drives derived timestamps). * @param {Function} [options.fetchImpl=fetch] - Injectable fetch (tests). */ constructor(url: string, track: VAVTrackContainer, { frameRate, fetchImpl }?: VAVTrackStreamOptions); private _startFetch; _run(fetchImpl: VAVTrackFetch, start: number, generation: number): Promise; /** Abort the active request while retaining received bytes and every manifest frame view. */ suspend(): void; /** Continue a suspended request from the retained byte prefix (with safe HTTP 200 fallback). */ resume(): Promise; _receive(chunk: Uint8Array): void; /** * Whether frame `index`'s encoded bytes have fully arrived. * * @param {number} index - Frame index. * @returns {boolean} */ frameAvailable(index: number): boolean; /** * Number of contiguous decodable frames from the start of the clip. * * @returns {number} */ availableFrames(): number; /** * Resolve once frame `index` is decodable (immediately if it already is). * * @param {number} index - Frame index. * @returns {Promise} */ whenFrameAvailable(index: number): Promise; /** * Seconds of playback buffered ahead of frame `fromFrame` (capped at clip end). * * @param {number} fromFrame - Playhead frame index. * @param {number} frameRate - Clip frame rate. * @returns {number} */ bufferedSecondsAhead(fromFrame: number, frameRate: number): number; /** * Abort the fetch and settle waiters (resolved, not rejected — callers re-check * availability, and a teardown must not surface unhandled rejections). Frame `data` views * stay valid (the buffer is owned by this instance) but no further bytes will arrive. */ dispose(): void; } export {};