npaw-plugin-nwf
Version:
NPAW's Plugin
112 lines (111 loc) • 5.57 kB
TypeScript
import { SwarmIdentity } from './SwarmIdentity';
import { ManifestSegmentMatch, SegmentMatchProvider, SegmentResolveInput } from './P2PSegmentIdResolver';
/**
* Synchronous loader hook for DASH SingleFile (SegmentBase) materialization.
* Parity with iOS `DashSingleFileIndexLoader`: given the resource URL and a
* byte-range, returns the raw bytes containing the SIDX box (or undefined on
* failure). Tests install a sync stub; browser runtimes install the async
* variant below instead.
*/
export type DashSingleFileIndexLoader = (url: string, range?: string) => Uint8Array | undefined;
/**
* Asynchronous loader hook for browser runtimes where fetching the index is
* necessarily async. When present and the sync loader isn't, the registry
* fires materialization in the background on the first resolve() miss;
* subsequent resolves benefit from the hydrated exact-match table.
*/
export type DashSingleFileIndexLoaderAsync = (url: string, range?: string) => Promise<Uint8Array | undefined>;
/**
* P2PManifestRegistry — HLS + DASH manifest-aware segment identity provider.
*
* Wire-compatible (canonical keys, SwarmIdentity descriptors, URL
* normalization) with iOS `P2PManifestRegistry.swift` and Android
* `P2pManifestRegistry.kt`. MVP covers:
* - HLS master (variants / alt media / i-frame)
* - HLS media playlists (MEDIA-SEQUENCE, DISCONTINUITY, EXTINF, PDT, MAP, BYTERANGE)
* - DASH SegmentTemplate ($Number$ / $Time$) + SegmentTimeline durations
* - DASH SegmentList (init + SegmentURL enumeration)
* - Rendition bandwidth (HLS BANDWIDTH, DASH bandwidth attr)
* - SwarmIdentity: VIDEO_ID > HLS_MASTER/DASH_MPD > URL_FALLBACK
*
* Deferred (tracked for future phases, not blockers for cross-platform
* interop with typical live streams):
* - DASH SegmentBase + SIDX lazy materialization
* - I-frame playlist media resolution
*/
export default class P2PManifestRegistry implements SegmentMatchProvider {
private exactMatches;
private exactMatchKeysByManifest;
private dashMatchersByManifest;
private dashSingleFileContextsByManifest;
private hlsContextsByPlaylistUrl;
private hlsContextKeysByManifest;
private renditionBandwidthBps;
private defaultPresentationId?;
private _currentSwarmIdentity?;
private dashSingleFileIndexLoader?;
private dashSingleFileIndexLoaderAsync?;
/** Manifest-request headers captured on registerManifest, used by SIDX materialization. */
private manifestRequestHeadersByManifest;
currentSwarmIdentity(): SwarmIdentity | undefined;
bandwidthForRendition(rendition: string): number | undefined;
setDashSingleFileIndexLoader(loader: DashSingleFileIndexLoader): void;
/**
* Install the async browser-style loader. Used when materializing SIDX in a
* real browser runtime where blocking fetches aren't possible. If not set,
* `resolve()` falls back to a default `window.fetch`-based loader.
*/
setDashSingleFileIndexLoaderAsync(loader: DashSingleFileIndexLoaderAsync): void;
/**
* Register an explicit `VIDEO_ID` swarm identity. Highest priority: once set,
* it wins over any manifest-derived identity. Mirrors iOS/Android public API.
*/
setVideoId(videoId: string, rawResourceUrl?: string): void;
buildUrlFallbackSwarmIdentity(manifestUrl: string): SwarmIdentity | undefined;
resolve(input: SegmentResolveInput): ManifestSegmentMatch | undefined;
private hasSingleFileContextFor;
registerManifest(manifestUrl: string, manifestBody: string, manifestRequestHeaders?: Array<[string, string]>): void;
clear(): void;
private isDashManifest;
private isHlsManifest;
private isHlsMasterManifest;
private currentOrCreatePresentationId;
private selectSwarmIdentity;
private addExactMatch;
private clearExactMatchesForManifest;
private clearHlsContextsForManifest;
private registerHlsManifest;
private registerHlsMaster;
private registerHlsPlaylistContext;
private registerHlsMediaPlaylist;
private buildHlsMasterSwarmIdentity;
private registerDashManifest;
private registerDashInitialization;
private createDashTemplateMatcher;
private registerDashSegmentList;
/**
* I1: Register a DASH SegmentBase+indexRange context. Sub-segments aren't
* known until the SIDX box has been fetched; the context is materialized
* lazily on the first byte-range `resolve()` miss against `resourceUrl`.
* Parity with iOS `registerDashSingleFileContext`.
*/
private registerDashSingleFileContext;
/**
* Synchronously materialize every DashSingleFileContext that matches the
* target resource. Each call fetches the SIDX bytes via the injected sync
* loader, parses them and writes sub-segment exact-matches so the next
* `resolve()` of the same range succeeds. Returns true when any context was
* materialized so the caller can re-check the exact-match table.
*/
private materializeDashSingleFileRanges;
/**
* Async equivalent of `materializeDashSingleFileRanges`. Fires per-context
* fetches in parallel; each fetched SIDX is parsed and registered as soon
* as it returns. Does NOT block `resolve()` — callers get the initial miss
* and subsequent resolves benefit from the hydrated table.
*/
private materializeDashSingleFileRangesAsync;
/** Shared SIDX-bytes-to-exact-matches translation used by both sync + async paths. */
private writeSidxAsExactMatches;
private buildDashMpdSwarmIdentity;
}