@meshstream/p2p-web 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ export type WebP2pProtocol = "hls" | "dash" | "mp4" | "mp3";
2
+ export type WebP2pBrowser = "safari" | "chrome" | "firefox" | "edge" | "unknown";
3
+ export type WebP2pOs = "ios" | "macos" | "android" | "windows" | "unknown";
4
+ export type WebP2pUnavailableReason = "WEBRTC_UNSUPPORTED" | "MSE_UNSUPPORTED" | "SAFARI_HLS_MSE_UNSUPPORTED";
5
+ export type WebP2pRecommendedMode = "p2p" | "cdn" | "native-hls-cdn";
6
+ export interface WebP2pCapabilityInput {
7
+ protocol?: WebP2pProtocol;
8
+ userAgent?: string;
9
+ hasWebSocket?: boolean;
10
+ hasRtcPeerConnection?: boolean;
11
+ hasRtcDataChannel?: boolean;
12
+ hasMediaSource?: boolean;
13
+ hasServiceWorker?: boolean;
14
+ hasSecureContext?: boolean;
15
+ }
16
+ export interface WebP2pCapabilityResult {
17
+ supported: boolean;
18
+ recommendedMode: WebP2pRecommendedMode;
19
+ browser: WebP2pBrowser;
20
+ os: WebP2pOs;
21
+ reason?: WebP2pUnavailableReason;
22
+ mseSupported?: boolean;
23
+ webrtcSupported?: boolean;
24
+ serviceWorkerSupported?: boolean;
25
+ secureContext?: boolean;
26
+ }
27
+ export declare function detectWebP2pCapability(input?: WebP2pCapabilityInput): WebP2pCapabilityResult;
@@ -0,0 +1,100 @@
1
+ export interface SdkTrackerNode {
2
+ url: string;
3
+ region?: string | null;
4
+ isp?: string | null;
5
+ weight?: number;
6
+ }
7
+ export interface SdkTrackerPoolStatus {
8
+ readinessCheckEnabled?: boolean;
9
+ totalCount?: number;
10
+ readyCount?: number;
11
+ selectedCount?: number;
12
+ matchedCount?: number;
13
+ fallbackToUnfiltered?: boolean;
14
+ unhealthyCount?: number;
15
+ degraded?: boolean;
16
+ selectionMode?: string;
17
+ preferredLocality?: string;
18
+ }
19
+ export interface SdkBootstrapStatus {
20
+ accountEnabled?: boolean;
21
+ applicationEnabled?: boolean;
22
+ keyEnabled?: boolean;
23
+ platformEnabled?: boolean;
24
+ effectiveP2pEnabled?: boolean;
25
+ reason?: "OK" | "APP_DISABLED" | "KEY_DISABLED" | "PLATFORM_DISABLED" | "P2P_DISABLED" | string;
26
+ }
27
+ export interface SdkQuotaStatus {
28
+ mode?: "metered" | "sponsored" | "contract-daily" | "contract-unlimited" | string;
29
+ status?: "available" | "exhausted" | "unlimited" | "disabled" | string;
30
+ source?: "gift" | "daily-plan" | "topup" | "contract" | string | null;
31
+ remainingBytes?: number | null;
32
+ resetAtMs?: number | null;
33
+ expiresAtMs?: number | null;
34
+ }
35
+ export interface SdkConfigResponse {
36
+ configVersion?: string;
37
+ appId?: string;
38
+ applicationId?: string;
39
+ /** Authoritative tenant registration/data-home region. */
40
+ homeRegion?: string;
41
+ /** Config API replica that accepted the bootstrap request. */
42
+ edgeRegion?: string;
43
+ keyId?: string;
44
+ keyName?: string;
45
+ keyEnabled?: boolean;
46
+ keyPlatform?: string;
47
+ p2pEnabled?: boolean;
48
+ ttlSeconds?: number;
49
+ refreshAfterSeconds?: number;
50
+ applyMode?: "next-session" | string;
51
+ status?: SdkBootstrapStatus;
52
+ quota?: SdkQuotaStatus;
53
+ accessUrl?: string;
54
+ trackerUrls: string[];
55
+ /** Authoritative primary selected by Config API after locality and health filtering. */
56
+ primaryTrackerUrl?: string;
57
+ iceServers?: string[];
58
+ trackerNodes?: SdkTrackerNode[];
59
+ trackerPool?: SdkTrackerPoolStatus;
60
+ reportUrl?: string;
61
+ scheduling?: {
62
+ homeRegion?: string | null;
63
+ region?: string | null;
64
+ country?: string | null;
65
+ countrySource?: string;
66
+ };
67
+ playbackAuth?: SdkPlaybackAuthPolicy;
68
+ defaults?: {
69
+ uploadSlots?: number;
70
+ downloadSlots?: number;
71
+ reportIntervalMs?: number;
72
+ swarmBucketCount?: number;
73
+ swarmBucketId?: number;
74
+ };
75
+ }
76
+ export interface SdkPlaybackAuthPolicy {
77
+ mode: "none" | "signed-url" | string;
78
+ signatureQueryKeys?: string[];
79
+ expiresQueryKeys?: string[];
80
+ clockSkewSeconds?: number;
81
+ }
82
+ export interface SdkConfigRequest {
83
+ bootstrapUrl?: string;
84
+ key?: string;
85
+ platform?: "web" | string;
86
+ contentId?: string;
87
+ expectedPeers?: number;
88
+ }
89
+ export interface LoadSdkConfigOptions {
90
+ forceRefresh?: boolean;
91
+ fetcher?: typeof fetch;
92
+ now?: () => number;
93
+ timeoutMs?: number;
94
+ }
95
+ export declare const DEFAULT_BOOTSTRAP_URL = "https://api.meshstream.net/config-api/v1/sdk/bootstrap";
96
+ export declare const DEFAULT_BOOTSTRAP_TIMEOUT_MS = 3000;
97
+ export declare function loadSdkConfig(request: SdkConfigRequest, options?: LoadSdkConfigOptions): Promise<SdkConfigResponse | undefined>;
98
+ export declare function normalizeSdkConfig(config: Partial<SdkConfigResponse>): SdkConfigResponse;
99
+ export declare function isSdkP2pConfigUsable(config: SdkConfigResponse | undefined): config is SdkConfigResponse;
100
+ export declare function normalizeTtlSeconds(config: Pick<SdkConfigResponse, "refreshAfterSeconds" | "ttlSeconds">): number;
@@ -0,0 +1,116 @@
1
+ import type { WebP2pCapabilityResult } from "./capabilities.js";
2
+ import type { SdkConfigResponse } from "./config.js";
3
+ import { type P2pEventListener } from "./hls.js";
4
+ import { type P2pDiagnostics, type P2pStats } from "./report.js";
5
+ import { type OriginHeaders, type OriginHeadersProvider } from "./origin-headers.js";
6
+ export interface DashP2pConfig {
7
+ shakaPlayer: ShakaPlayerLike;
8
+ shakaLibrary?: unknown;
9
+ streamUrl: string;
10
+ /** Shaka supports both HLS and DASH. Used for telemetry only. */
11
+ protocol?: "hls" | "dash";
12
+ contentId?: string;
13
+ originHeaders?: OriginHeaders;
14
+ originHeadersProvider?: OriginHeadersProvider;
15
+ sdkConfig?: Pick<SdkConfigResponse, "applicationId" | "keyId" | "reportUrl" | "trackerUrls" | "primaryTrackerUrl" | "iceServers" | "playbackAuth" | "defaults">;
16
+ trackerUrl?: string;
17
+ trackerUrls?: string[];
18
+ appId?: string;
19
+ sessionId?: string;
20
+ iceServers?: RTCIceServer[];
21
+ p2pEnabled?: boolean;
22
+ /** Optional integration override. `0` starts CDN requests immediately. */
23
+ httpDownloadInitialTimeoutMs?: number;
24
+ uploadSlots?: number;
25
+ downloadSlots?: number;
26
+ networkType?: string;
27
+ liveWindowBucket?: string;
28
+ capability?: WebP2pCapabilityResult;
29
+ sessionTokenManager?: {
30
+ getAuthorizationHeader(): Promise<string | undefined>;
31
+ diagnostics?(): {
32
+ attempts: number;
33
+ successes: number;
34
+ failures: number;
35
+ durationMs: number;
36
+ };
37
+ };
38
+ }
39
+ export interface ShakaPlayerLike {
40
+ configure?(key: string, value: unknown): void;
41
+ getNetworkingEngine?(): unknown;
42
+ getVariantTracks?(): Array<{
43
+ active?: boolean;
44
+ bandwidth?: number;
45
+ }>;
46
+ getMediaElement?(): HTMLMediaElement | null;
47
+ isLive?(): boolean;
48
+ addEventListener?(event: string, listener: EventListenerOrEventListenerObject): void;
49
+ removeEventListener?(event: string, listener: EventListenerOrEventListenerObject): void;
50
+ load(url: string): Promise<unknown>;
51
+ destroy?(): Promise<unknown> | void;
52
+ }
53
+ type PublicEvent = "peer-connect" | "peer-close" | "p2p-download" | "p2p-upload" | "http-download" | "tracker-error" | "segment-error";
54
+ type Listener = (payload: unknown) => void;
55
+ export declare class DashP2pClient {
56
+ private engine;
57
+ private readonly shakaPlayer;
58
+ private readonly shakaLibrary?;
59
+ private readonly engineConfig;
60
+ private readonly trackerCandidates;
61
+ private failoverInFlight;
62
+ private activeTrackerIndex;
63
+ private disposed;
64
+ private engineGeneration;
65
+ readonly swarmId: string;
66
+ private readonly streamUrl;
67
+ private readonly protocol;
68
+ private readonly contentId?;
69
+ private readonly appId?;
70
+ private readonly keyId?;
71
+ private readonly uploadSlots;
72
+ private readonly downloadSlots;
73
+ private readonly reportIntervalMs;
74
+ private readonly capability?;
75
+ private readonly reportUrl?;
76
+ private readonly sessionId;
77
+ private readonly sessionTokenManager?;
78
+ private readonly startedAtMs;
79
+ private readonly listeners;
80
+ private readonly eventListeners;
81
+ private readonly activePeers;
82
+ private readonly pagehideHandler;
83
+ private reportTimer;
84
+ private reportInFlight;
85
+ private pendingFinalReport;
86
+ private hasReportedContext;
87
+ private eventTimer;
88
+ private p2pEnabled;
89
+ private p2pReady;
90
+ private peerOptimizedWindows;
91
+ /** Remains unknown until Shaka has loaded media metadata from its manifest. */
92
+ private playbackIsLive;
93
+ private readonly mediaMetadataHandler;
94
+ private readonly stats;
95
+ private readonly diagnosticState;
96
+ constructor(config: DashP2pConfig);
97
+ on(event: PublicEvent, listener: Listener): void;
98
+ off(event: PublicEvent, listener: Listener): void;
99
+ addEventListener(listener: P2pEventListener): void;
100
+ removeEventListener(listener: P2pEventListener): void;
101
+ setP2pEnabled(enabled: boolean): void;
102
+ statistics(): P2pStats;
103
+ diagnostics(): P2pDiagnostics;
104
+ dispose(): void;
105
+ private emit;
106
+ private bindEvents;
107
+ private createEngine;
108
+ private failoverTracker;
109
+ private trackDownloadedBytes;
110
+ private notify;
111
+ private notifyPlaybackState;
112
+ private startStatsReporting;
113
+ private applyPeerOptimizedWindows;
114
+ private reportStats;
115
+ }
116
+ export {};
package/dist/dash.d.ts ADDED
@@ -0,0 +1,110 @@
1
+ import type { WebP2pCapabilityResult } from "./capabilities.js";
2
+ import type { LoadSdkConfigOptions, SdkConfigRequest, SdkConfigResponse } from "./config.js";
3
+ import type { DashP2pConfig, ShakaPlayerLike } from "./dash-p2p.js";
4
+ import { type DashJsP2pConfig } from "./dashjs-p2p.js";
5
+ import { reportWebP2pFallback } from "./fallback.js";
6
+ import type { P2pEventListener } from "./hls.js";
7
+ import { type MeshStreamP2pFallbackReason } from "./player.js";
8
+ import { type P2pDiagnostics, type P2pStats } from "./report.js";
9
+ import { type MeshStreamQoeSnapshot } from "./qoe.js";
10
+ import { type OriginHeaders, type OriginHeadersProvider } from "./origin-headers.js";
11
+ export type MeshStreamDashPlaybackMode = "p2p-hls" | "p2p-dash" | "cdn-hls" | "cdn-dash" | "unsupported";
12
+ export interface MeshStreamDashPlayerOptions {
13
+ url: string;
14
+ video: HTMLMediaElement;
15
+ contentId?: string;
16
+ mimeType?: "m3u8" | "mpd";
17
+ originHeaders?: OriginHeaders;
18
+ originHeadersProvider?: OriginHeadersProvider;
19
+ bootstrapUrl?: string;
20
+ key?: string;
21
+ networkType?: string;
22
+ liveWindowBucket?: string;
23
+ autoplay?: boolean;
24
+ p2pEnabled?: boolean;
25
+ iceServers?: RTCIceServer[];
26
+ /** Optional test/integration override. Keep zero for immediate CDN cold starts. */
27
+ httpDownloadInitialTimeoutMs?: number;
28
+ /** Existing dash.js instance. When supplied, P2P is bound through XHRLoader. */
29
+ dashjsInstance?: DashLike;
30
+ /** Existing Shaka instance. MeshStream binds P2P but never destroys it. */
31
+ shakaInstance?: ShakaPlayerLike;
32
+ dependencies?: MeshStreamDashPlayerDependencies;
33
+ }
34
+ export interface MeshStreamDashStartResult {
35
+ mode: MeshStreamDashPlaybackMode;
36
+ capability: WebP2pCapabilityResult;
37
+ sdkConfig?: SdkConfigResponse;
38
+ fallbackReason?: MeshStreamP2pFallbackReason;
39
+ }
40
+ export interface MeshStreamDashPlayerDependencies {
41
+ loadSdkConfig?: (request: SdkConfigRequest, options?: LoadSdkConfigOptions) => Promise<SdkConfigResponse | undefined>;
42
+ detectCapability?: () => WebP2pCapabilityResult;
43
+ createDash?: () => DashLike | Promise<DashLike>;
44
+ createShakaPlayer?: (video: HTMLMediaElement) => ShakaPlayerLike | Promise<ShakaPlayerLike>;
45
+ createCdnShakaPlayer?: () => ShakaPlayerLike | Promise<ShakaPlayerLike>;
46
+ createP2pClient?: (config: DashP2pConfig) => DashP2pClientLike | Promise<DashP2pClientLike>;
47
+ createDashJsP2pClient?: (config: DashJsP2pConfig) => DashP2pClientLike | Promise<DashP2pClientLike>;
48
+ reportFallback?: typeof reportWebP2pFallback;
49
+ }
50
+ export interface DashLike {
51
+ initialize(video: HTMLMediaElement, url: string, autoplay?: boolean): void;
52
+ extend?: (parentName: string, childInstance: (this: {
53
+ parent?: unknown;
54
+ }) => unknown, override: boolean) => void;
55
+ addRequestInterceptor?(interceptor: Function): void;
56
+ removeRequestInterceptor?(interceptor: Function): void;
57
+ reset?(): void;
58
+ }
59
+ export interface DashP2pClientLike {
60
+ swarmId: string;
61
+ addEventListener(listener: P2pEventListener): void;
62
+ removeEventListener(listener: P2pEventListener): void;
63
+ statistics(): Partial<P2pStats>;
64
+ diagnostics(): Partial<P2pDiagnostics>;
65
+ setP2pEnabled(enabled: boolean): void;
66
+ dispose(): void;
67
+ }
68
+ export declare class MeshStreamDashPlayer {
69
+ readonly key: string;
70
+ readonly url: string;
71
+ readonly video: HTMLMediaElement;
72
+ private readonly options;
73
+ private readonly protocol;
74
+ private readonly ownsShakaInstance;
75
+ private dash?;
76
+ private shaka?;
77
+ private p2p?;
78
+ private dashOriginInterceptor?;
79
+ private sessionTokenManager?;
80
+ private mode;
81
+ private p2pEnabledOverride?;
82
+ private readonly eventListeners;
83
+ private playbackState;
84
+ private readonly lifecycle;
85
+ private startPromise?;
86
+ private startResult?;
87
+ constructor(options: MeshStreamDashPlayerOptions);
88
+ get dashClient(): DashLike | undefined;
89
+ get shakaClient(): ShakaPlayerLike | undefined;
90
+ get p2pClient(): DashP2pClientLike | undefined;
91
+ get playbackMode(): MeshStreamDashPlaybackMode;
92
+ start(): Promise<MeshStreamDashStartResult>;
93
+ private startInternal;
94
+ statistics(): P2pStats;
95
+ diagnostics(): Partial<P2pDiagnostics>;
96
+ qoe(): MeshStreamQoeSnapshot;
97
+ setP2pEnabled(enabled: boolean): void;
98
+ dispose(): void;
99
+ private teardown;
100
+ private startCdnDash;
101
+ addEventListener(listener: P2pEventListener): () => void;
102
+ private startP2pDashJs;
103
+ private effectiveP2pEnabled;
104
+ private bindEventListeners;
105
+ private completeFallbackStart;
106
+ private removeEventListener;
107
+ private setPlaybackState;
108
+ private resolveQoePlaybackState;
109
+ private releaseShaka;
110
+ }
@@ -0,0 +1,222 @@
1
+ import { Core, type EngineCallbacks } from "p2p-media-loader-core";
2
+ import type { WebP2pCapabilityResult } from "./capabilities.js";
3
+ import type { SdkConfigResponse } from "./config.js";
4
+ import { type P2pEventListener } from "./hls.js";
5
+ import { type OriginHeaders, type OriginHeadersProvider } from "./origin-headers.js";
6
+ import { type P2pDiagnostics, type P2pStats } from "./report.js";
7
+ export interface DashJsP2pConfig {
8
+ dashPlayer: DashJsPlayerLike;
9
+ /**
10
+ * The media element initialized by dash.js. It lets Core follow actual
11
+ * playback progress, which is required to schedule its first request.
12
+ */
13
+ video?: HTMLMediaElement;
14
+ streamUrl: string;
15
+ contentId?: string;
16
+ originHeaders?: OriginHeaders;
17
+ originHeadersProvider?: OriginHeadersProvider;
18
+ sdkConfig?: Pick<SdkConfigResponse, "applicationId" | "keyId" | "reportUrl" | "trackerUrls" | "primaryTrackerUrl" | "iceServers" | "playbackAuth" | "defaults">;
19
+ trackerUrl?: string;
20
+ trackerUrls?: string[];
21
+ appId?: string;
22
+ sessionId?: string;
23
+ iceServers?: RTCIceServer[];
24
+ p2pEnabled?: boolean;
25
+ httpDownloadInitialTimeoutMs?: number;
26
+ uploadSlots?: number;
27
+ downloadSlots?: number;
28
+ capability?: WebP2pCapabilityResult;
29
+ sessionTokenManager?: {
30
+ getAuthorizationHeader(): Promise<string | undefined>;
31
+ diagnostics?(): {
32
+ attempts: number;
33
+ successes: number;
34
+ failures: number;
35
+ durationMs: number;
36
+ };
37
+ };
38
+ /** Internal test seam; customer integrations should not supply this. */
39
+ dependencies?: DashJsP2pClientDependencies;
40
+ }
41
+ export interface DashJsP2pClientDependencies {
42
+ createCore?: (config: ConstructorParameters<typeof Core>[0]) => DashCoreLike;
43
+ }
44
+ export interface DashJsPlayerLike {
45
+ extend?: (parentName: string, childInstance: DashJsExtensionFactory, override: boolean) => void;
46
+ /** dash.js exposes the loaded MPD mode after manifest parsing. */
47
+ isDynamic?: () => boolean;
48
+ }
49
+ export interface DashJsExtensionContext {
50
+ parent?: DashJsXhrLoaderLike;
51
+ }
52
+ export type DashJsExtensionFactory = (this: DashJsExtensionContext) => DashJsXhrLoaderLike;
53
+ export interface DashJsXhrLoaderLike {
54
+ load(request: DashJsCommonRequest, response: DashJsCommonResponse): boolean | void;
55
+ abort?(request?: DashJsCommonRequest): void;
56
+ getXhr?(request?: DashJsCommonRequest, response?: DashJsCommonResponse): unknown;
57
+ reset?(): void;
58
+ resetInitialSettings?(): void;
59
+ }
60
+ export interface DashJsCommonRequest {
61
+ url?: string;
62
+ method?: string;
63
+ responseType?: string;
64
+ credentials?: string;
65
+ customData?: {
66
+ request?: DashJsFragmentRequest;
67
+ abort?: () => void;
68
+ onloadend?: () => void;
69
+ onprogress?: (event: DashJsProgressEvent) => void;
70
+ onabort?: () => void;
71
+ ontimeout?: (event: DashJsProgressEvent) => void;
72
+ };
73
+ }
74
+ export interface DashJsCommonResponse {
75
+ url?: string;
76
+ status?: number;
77
+ statusText?: string;
78
+ headers?: Record<string, string>;
79
+ data?: ArrayBuffer;
80
+ resourceTiming?: {
81
+ responseStart?: number;
82
+ responseEnd?: number;
83
+ duration?: number;
84
+ encodedBodySize?: number;
85
+ };
86
+ }
87
+ export interface DashJsProgressEvent {
88
+ lengthComputable: boolean;
89
+ loaded: number;
90
+ total: number;
91
+ time?: number;
92
+ throughput?: number;
93
+ noTrace?: boolean;
94
+ }
95
+ export interface DashJsFragmentRequest {
96
+ type?: string | null;
97
+ mediaType?: string | null;
98
+ representation?: {
99
+ id?: string | number | null;
100
+ bandwidth?: number;
101
+ adaptation?: {
102
+ index?: number;
103
+ period?: {
104
+ id?: string | number | null;
105
+ index?: number;
106
+ };
107
+ };
108
+ } | null;
109
+ adaptationIndex?: number;
110
+ bandwidth?: number;
111
+ index?: number;
112
+ startTime?: number;
113
+ duration?: number;
114
+ range?: string | null;
115
+ isPartialSegmentRequest?: boolean;
116
+ }
117
+ interface DashCoreLike {
118
+ addEventListener(event: string, listener: (...args: any[]) => void): void;
119
+ addStreamIfNoneExists(stream: {
120
+ runtimeId: string;
121
+ type: "main" | "secondary";
122
+ index: string;
123
+ }): void;
124
+ updateStream(streamRuntimeId: string, addSegments?: Iterable<DashCoreSegment>, removeSegmentIds?: Iterable<string>): void;
125
+ updatePlayback(position: number, rate: number): void;
126
+ loadSegment(segmentRuntimeId: string, callbacks: EngineCallbacks): Promise<void>;
127
+ abortSegmentLoading(segmentRuntimeId: string): void;
128
+ setManifestResponseUrl(url: string): void;
129
+ setIsLive(isLive: boolean): void;
130
+ applyDynamicConfig(config: Record<string, unknown>): void;
131
+ destroy(): void;
132
+ }
133
+ interface DashCoreSegment {
134
+ runtimeId: string;
135
+ externalId: number;
136
+ url: string;
137
+ byteRange?: {
138
+ start: number;
139
+ end: number;
140
+ };
141
+ startTime: number;
142
+ endTime: number;
143
+ }
144
+ /**
145
+ * P2P transport for dash.js. It uses dash.js's documented XHRLoader extension
146
+ * point and leaves non-segment traffic on the customer's original loader.
147
+ */
148
+ export declare class DashJsP2pClient {
149
+ private readonly dashPlayer;
150
+ private readonly config;
151
+ private readonly video;
152
+ private core;
153
+ private readonly trackerCandidates;
154
+ private readonly streamSegments;
155
+ private readonly listeners;
156
+ private readonly eventListeners;
157
+ private readonly activePeers;
158
+ private readonly sessionId;
159
+ private readonly streamUrl;
160
+ private readonly contentId?;
161
+ private readonly appId?;
162
+ private readonly keyId?;
163
+ private readonly uploadSlots;
164
+ private readonly downloadSlots;
165
+ /** Defaults to VOD until dash.js has parsed the MPD. */
166
+ private live;
167
+ private readonly reportIntervalMs;
168
+ private readonly capability?;
169
+ private readonly reportUrl?;
170
+ private readonly sessionTokenManager?;
171
+ private readonly startedAtMs;
172
+ private readonly pagehideHandler;
173
+ private readonly playbackHandler;
174
+ private readonly stats;
175
+ private readonly diagnosticState;
176
+ private activeTrackerIndex;
177
+ private engineGeneration;
178
+ private eventTimer;
179
+ private reportTimer;
180
+ private reportInFlight;
181
+ private pendingFinalReport;
182
+ private hasReportedContext;
183
+ private failoverInFlight;
184
+ private p2pEnabled;
185
+ private p2pReady;
186
+ private peerOptimizedWindows;
187
+ private disposed;
188
+ /** Remains unknown until dash.js requests its first regular media segment. */
189
+ private playbackIsLive;
190
+ readonly swarmId: string;
191
+ constructor(config: DashJsP2pConfig);
192
+ addEventListener(listener: P2pEventListener): void;
193
+ removeEventListener(listener: P2pEventListener): void;
194
+ statistics(): P2pStats;
195
+ diagnostics(): P2pDiagnostics;
196
+ setP2pEnabled(enabled: boolean): void;
197
+ dispose(): void;
198
+ private createCore;
199
+ private createXhrLoader;
200
+ private registerSegment;
201
+ private updateLiveMode;
202
+ private updatePlaybackFromMediaElement;
203
+ /**
204
+ * dash.js asks its XHR loader for the first segment before a `timeupdate`
205
+ * event can fire. Core otherwise keeps that initial request pending until a
206
+ * position change arrives. Seed it within the requested segment so normal
207
+ * Core scheduling, including HTTP fallback, can begin immediately.
208
+ */
209
+ private primeSegmentPlayback;
210
+ private bindCoreEvents;
211
+ private failoverTracker;
212
+ private isCurrentCore;
213
+ private applyPeerOptimizedWindows;
214
+ private emit;
215
+ private notify;
216
+ private notifyPlaybackState;
217
+ private startStatsReporting;
218
+ private reportStats;
219
+ }
220
+ /** @internal Guardrail: partial CMAF requests remain on dash.js/CDN. */
221
+ export declare function isDashJsP2pSegment(fragment: DashJsFragmentRequest, request: DashJsCommonRequest): boolean;
222
+ export {};
@@ -0,0 +1,8 @@
1
+ import { MeshStreamHlsPlayer, type MeshStreamHlsPlayerOptions } from "./player.js";
2
+ /**
3
+ * Progressive MP4/MP3 player backed by the Service Worker transport. P2P is
4
+ * limited to bounded byte-range requests; all unsupported requests use CDN.
5
+ */
6
+ export declare class MeshStreamDirectFilePlayer extends MeshStreamHlsPlayer {
7
+ constructor(options: MeshStreamHlsPlayerOptions);
8
+ }
@@ -0,0 +1,35 @@
1
+ import type { WebP2pCapabilityResult } from "./capabilities.js";
2
+ import type { SdkConfigResponse } from "./config.js";
3
+ import { type OriginHeaders, type OriginHeadersProvider } from "./origin-headers.js";
4
+ export type FallbackPlaybackMode = "live" | "vod";
5
+ export interface WebP2pFallbackReportConfig {
6
+ appId?: string;
7
+ keyId?: string;
8
+ streamUrl: string;
9
+ contentId?: string;
10
+ protocol?: "hls" | "dash" | "mp4" | "mp3";
11
+ playerType?: "hlsjs" | "shaka" | "dashjs" | "native" | string;
12
+ /** Applied only to the media-origin manifest probe, never to peers. */
13
+ originHeaders?: OriginHeaders;
14
+ originHeadersProvider?: OriginHeadersProvider;
15
+ sdkConfig?: Pick<SdkConfigResponse, "keyId" | "reportUrl" | "playbackAuth">;
16
+ sessionId?: string;
17
+ sessionToken?: string;
18
+ /** Internal deferred token resolver used by non-blocking player fallback telemetry. */
19
+ sessionTokenProvider?: () => string | undefined | Promise<string | undefined>;
20
+ capability: WebP2pCapabilityResult;
21
+ }
22
+ export interface WebP2pFallbackReportOptions {
23
+ fetcher?: typeof fetch;
24
+ /** Test/integration override for the media manifest probe. */
25
+ manifestFetcher?: typeof fetch;
26
+ manifestProbeTimeoutMs?: number;
27
+ sessionIdFactory?: () => string;
28
+ }
29
+ export declare function reportWebP2pFallback(config: WebP2pFallbackReportConfig, options?: WebP2pFallbackReportOptions): Promise<Response | undefined>;
30
+ /**
31
+ * Starts fallback telemetry without delaying CDN playback. Player-owned
32
+ * fallback paths use this; direct callers can await reportWebP2pFallback.
33
+ */
34
+ export declare function queueWebP2pFallbackReport(config: WebP2pFallbackReportConfig, options?: WebP2pFallbackReportOptions): void;
35
+ export declare function detectFallbackPlaybackMode(config: Pick<WebP2pFallbackReportConfig, "streamUrl" | "protocol" | "originHeaders" | "originHeadersProvider">, options?: Pick<WebP2pFallbackReportOptions, "fetcher" | "manifestFetcher" | "manifestProbeTimeoutMs">): Promise<FallbackPlaybackMode | undefined>;