@stinkycomputing/web-live-player 0.1.2 → 0.1.4
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.
- package/README.md +31 -5
- package/dist/assets/audio-encoder.worker-c5c829bb.js +114 -0
- package/dist/assets/video-encoder.worker-a613b1f0.js +91 -0
- package/dist/capture/audio-encoder.worker.d.ts +7 -0
- package/dist/capture/capture-sink.d.ts +105 -0
- package/dist/capture/capture-types.d.ts +120 -0
- package/dist/capture/index.d.ts +17 -0
- package/dist/capture/media-capture.d.ts +89 -0
- package/dist/capture/media-encoder.d.ts +65 -0
- package/dist/capture/moq-sink.d.ts +55 -0
- package/dist/capture/video-encoder.worker.d.ts +7 -0
- package/dist/capture/websocket-sink.d.ts +35 -0
- package/dist/index.d.ts +5 -4
- package/dist/player/live-player.d.ts +28 -1
- package/dist/scheduling/frame-scheduler.d.ts +23 -1
- package/dist/sources/moq-source.d.ts +44 -0
- package/dist/sources/mp4-file-source.d.ts +1 -0
- package/dist/sources/standalone-moq-source.d.ts +10 -10
- package/dist/web-live-player.cjs +3 -3
- package/dist/web-live-player.mjs +3229 -2481
- package/package.json +2 -2
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { BaseCaptureSink, CaptureSinkConfig, SerializedPacket } from './capture-sink';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Track configuration for MoQ publishing
|
|
5
|
+
*/
|
|
6
|
+
export interface MoQTrackConfig {
|
|
7
|
+
trackName: string;
|
|
8
|
+
priority?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* MoQ-specific sink configuration
|
|
12
|
+
*/
|
|
13
|
+
export interface MoQSinkConfig extends CaptureSinkConfig {
|
|
14
|
+
/** MoQ relay URL */
|
|
15
|
+
relayUrl: string;
|
|
16
|
+
/** Namespace for the streams */
|
|
17
|
+
namespace: string;
|
|
18
|
+
/** Video track configuration */
|
|
19
|
+
videoTrack?: MoQTrackConfig;
|
|
20
|
+
/** Audio track configuration */
|
|
21
|
+
audioTrack?: MoQTrackConfig;
|
|
22
|
+
/** Additional data tracks (e.g., for chat messages) */
|
|
23
|
+
dataTracks?: MoQTrackConfig[];
|
|
24
|
+
/** Reconnection delay in ms */
|
|
25
|
+
reconnectionDelay?: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Capture sink that sends data over MoQ
|
|
29
|
+
*/
|
|
30
|
+
export declare class MoQCaptureSink extends BaseCaptureSink {
|
|
31
|
+
private moqConfig;
|
|
32
|
+
private session;
|
|
33
|
+
private connecting;
|
|
34
|
+
private disposed;
|
|
35
|
+
private currentVideoGroup;
|
|
36
|
+
private audioFrameCount;
|
|
37
|
+
private static readonly AUDIO_FRAMES_PER_GROUP;
|
|
38
|
+
constructor(config: MoQSinkConfig);
|
|
39
|
+
connect(): Promise<void>;
|
|
40
|
+
disconnect(): Promise<void>;
|
|
41
|
+
send(packet: SerializedPacket): void;
|
|
42
|
+
private setupEventListeners;
|
|
43
|
+
dispose(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Send custom data on a data track (e.g., chat messages)
|
|
46
|
+
* Each data message starts a new group.
|
|
47
|
+
* @param trackName The data track name to send on
|
|
48
|
+
* @param data The data to send
|
|
49
|
+
*/
|
|
50
|
+
sendData(trackName: string, data: Uint8Array): void;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Factory function to create a MoQ capture sink
|
|
54
|
+
*/
|
|
55
|
+
export declare function createMoQSink(config: MoQSinkConfig): MoQCaptureSink;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BaseCaptureSink, CaptureSinkConfig, SerializedPacket } from './capture-sink';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* WebSocket-specific sink configuration
|
|
5
|
+
*/
|
|
6
|
+
export interface WebSocketSinkConfig extends CaptureSinkConfig {
|
|
7
|
+
/** WebSocket URL to connect to */
|
|
8
|
+
url: string;
|
|
9
|
+
/** Connection timeout in ms */
|
|
10
|
+
connectionTimeout?: number;
|
|
11
|
+
/** Whether to automatically reconnect on disconnect */
|
|
12
|
+
autoReconnect?: boolean;
|
|
13
|
+
/** Delay between reconnection attempts in ms */
|
|
14
|
+
reconnectDelay?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Capture sink that sends data over WebSocket
|
|
18
|
+
*/
|
|
19
|
+
export declare class WebSocketCaptureSink extends BaseCaptureSink {
|
|
20
|
+
private websocket?;
|
|
21
|
+
private wsConfig;
|
|
22
|
+
private reconnectTimer?;
|
|
23
|
+
private disposed;
|
|
24
|
+
constructor(config: WebSocketSinkConfig);
|
|
25
|
+
connect(): Promise<void>;
|
|
26
|
+
disconnect(): Promise<void>;
|
|
27
|
+
send(packet: SerializedPacket): void;
|
|
28
|
+
private scheduleReconnect;
|
|
29
|
+
private clearReconnectTimer;
|
|
30
|
+
dispose(): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Factory function to create a WebSocket capture sink
|
|
34
|
+
*/
|
|
35
|
+
export declare function createWebSocketSink(config: WebSocketSinkConfig): WebSocketCaptureSink;
|
package/dist/index.d.ts
CHANGED
|
@@ -12,10 +12,10 @@ export * from './sources/stream-source';
|
|
|
12
12
|
export { BasePlayer } from './player/base-player';
|
|
13
13
|
export type { BasePlayerConfig } from './player/base-player';
|
|
14
14
|
export { LiveVideoPlayer, createPlayer } from './player/live-player';
|
|
15
|
-
export type { PlayerConfig, PlayerStats, PlayerState } from './player/live-player';
|
|
15
|
+
export type { PlayerConfig, PlayerStats, PlayerState, BandwidthStats } from './player/live-player';
|
|
16
16
|
export { FileVideoPlayer, createFilePlayer } from './player/file-player';
|
|
17
17
|
export type { FilePlayerConfig, FilePlayerState, FilePlayerStats, FilePlayMode } from './player/file-player';
|
|
18
|
-
export {
|
|
18
|
+
export { createMoQSource, MoQSource } from './sources/moq-source';
|
|
19
19
|
export { WebSocketSource, createWebSocketSource } from './sources/websocket-source';
|
|
20
20
|
export type { WebSocketSourceConfig, VideoMetadata } from './sources/websocket-source';
|
|
21
21
|
export { MP4FileSource } from './sources/mp4-file-source';
|
|
@@ -30,6 +30,7 @@ export { FileAudioPlayer } from './audio/file-audio-player';
|
|
|
30
30
|
export { LiveAudioPlayer } from './audio/live-audio-player';
|
|
31
31
|
export type { LiveAudioConfig } from './audio/live-audio-player';
|
|
32
32
|
export { FrameScheduler } from './scheduling/frame-scheduler';
|
|
33
|
-
export type { FrameTiming, LatencyStats, SchedulerStatus, SchedulerConfig } from './scheduling/frame-scheduler';
|
|
34
|
-
export { SesameBinaryProtocol } from './protocol/sesame-binary-protocol';
|
|
33
|
+
export type { FrameTiming, LatencyStats, SchedulerStatus, SchedulerConfig, PacketTimingEntry } from './scheduling/frame-scheduler';
|
|
34
|
+
export { SesameBinaryProtocol, FLAG_IS_KEYFRAME, FLAG_HAS_CODEC_DATA, PacketType } from './protocol/sesame-binary-protocol';
|
|
35
35
|
export type { ParsedData, HeaderData, HeaderCodecData } from './protocol/sesame-binary-protocol';
|
|
36
|
+
export * from './capture';
|
|
@@ -21,6 +21,14 @@ export interface PlayerConfig {
|
|
|
21
21
|
* Player state
|
|
22
22
|
*/
|
|
23
23
|
export type PlayerState = 'idle' | 'playing' | 'paused' | 'error';
|
|
24
|
+
/**
|
|
25
|
+
* Bandwidth statistics
|
|
26
|
+
*/
|
|
27
|
+
export interface BandwidthStats {
|
|
28
|
+
videoBytesPerSecond: number;
|
|
29
|
+
audioBytesPerSecond: number;
|
|
30
|
+
totalBytesPerSecond: number;
|
|
31
|
+
}
|
|
24
32
|
/**
|
|
25
33
|
* Player statistics
|
|
26
34
|
*/
|
|
@@ -36,6 +44,7 @@ export interface PlayerStats {
|
|
|
36
44
|
streamHeight: number;
|
|
37
45
|
frameRate: number;
|
|
38
46
|
latency: LatencyStats | null;
|
|
47
|
+
bandwidth: BandwidthStats | null;
|
|
39
48
|
}
|
|
40
49
|
/**
|
|
41
50
|
* Player event types
|
|
@@ -79,11 +88,21 @@ export declare class LiveVideoPlayer extends BasePlayer<PlayerState> {
|
|
|
79
88
|
private streamWidth;
|
|
80
89
|
private streamHeight;
|
|
81
90
|
private estimatedFrameRate;
|
|
91
|
+
private lastVideoTimestampUs;
|
|
92
|
+
private fpsEstimateSamples;
|
|
93
|
+
private static readonly FPS_SAMPLE_COUNT;
|
|
82
94
|
private audioContext;
|
|
83
95
|
private audioPlayer;
|
|
84
96
|
private ownsAudioContext;
|
|
85
97
|
private audioCodecData;
|
|
86
98
|
private arrivalTimes;
|
|
99
|
+
private keyframeStatus;
|
|
100
|
+
private videoBytesReceived;
|
|
101
|
+
private audioBytesReceived;
|
|
102
|
+
private lastBandwidthUpdateTime;
|
|
103
|
+
private lastVideoBytesReceived;
|
|
104
|
+
private lastAudioBytesReceived;
|
|
105
|
+
private currentBandwidth;
|
|
87
106
|
constructor(config?: PlayerConfig);
|
|
88
107
|
/**
|
|
89
108
|
* Enable or disable debug logging at runtime
|
|
@@ -109,7 +128,7 @@ export declare class LiveVideoPlayer extends BasePlayer<PlayerState> {
|
|
|
109
128
|
* Convenience method to connect to a MoQ-like session
|
|
110
129
|
*
|
|
111
130
|
* Note: For audio support, the MoQ session must also be subscribed to the audio track.
|
|
112
|
-
* When using
|
|
131
|
+
* When using MoQSource, include both 'video' and 'audio' in subscriptions.
|
|
113
132
|
* When using Elmo's MoQSessionNode, add an audio track to the session config.
|
|
114
133
|
*
|
|
115
134
|
* @param session - MoQ session implementing IStreamSource (e.g., Elmo's MoQSessionNode)
|
|
@@ -164,6 +183,14 @@ export declare class LiveVideoPlayer extends BasePlayer<PlayerState> {
|
|
|
164
183
|
* Get player statistics
|
|
165
184
|
*/
|
|
166
185
|
getStats(): PlayerStats;
|
|
186
|
+
/**
|
|
187
|
+
* Update bandwidth statistics
|
|
188
|
+
*/
|
|
189
|
+
private updateBandwidthStats;
|
|
190
|
+
/**
|
|
191
|
+
* Get packet timing history for visualization/debugging
|
|
192
|
+
*/
|
|
193
|
+
getPacketTimingHistory(): import('..').PacketTimingEntry[];
|
|
167
194
|
/**
|
|
168
195
|
* Subscribe to player events (typed overload)
|
|
169
196
|
*/
|
|
@@ -42,6 +42,23 @@ export interface SchedulerStatus {
|
|
|
42
42
|
driftCorrections: number;
|
|
43
43
|
latency: LatencyStats | null;
|
|
44
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Packet timing entry for visualization
|
|
47
|
+
*/
|
|
48
|
+
export interface PacketTimingEntry {
|
|
49
|
+
/** Time packet arrived (performance.now()) */
|
|
50
|
+
arrivalTime: number;
|
|
51
|
+
/** Time since previous packet (ms) */
|
|
52
|
+
intervalMs: number;
|
|
53
|
+
/** Stream timestamp (us) */
|
|
54
|
+
streamTimestampUs: number;
|
|
55
|
+
/** Whether this was a keyframe */
|
|
56
|
+
isKeyframe: boolean;
|
|
57
|
+
/** Decode latency (ms) */
|
|
58
|
+
decodeLatencyMs: number;
|
|
59
|
+
/** Whether frame was dropped */
|
|
60
|
+
wasDropped: boolean;
|
|
61
|
+
}
|
|
45
62
|
export interface SchedulerConfig<T> {
|
|
46
63
|
/** Target buffer delay in milliseconds (0 = bypass mode, always return latest) */
|
|
47
64
|
bufferDelayMs?: number;
|
|
@@ -81,6 +98,9 @@ export declare class FrameScheduler<T> {
|
|
|
81
98
|
private dequeueCount;
|
|
82
99
|
private latencyHistory;
|
|
83
100
|
private latencyHistorySize;
|
|
101
|
+
private packetTimingHistory;
|
|
102
|
+
private packetTimingHistorySize;
|
|
103
|
+
private lastPacketArrivalTime;
|
|
84
104
|
private stats;
|
|
85
105
|
private logger;
|
|
86
106
|
private onFrameDropped?;
|
|
@@ -90,7 +110,7 @@ export declare class FrameScheduler<T> {
|
|
|
90
110
|
/** Effective drift threshold - scales with buffer target for low-latency mode */
|
|
91
111
|
private get effectiveDriftThresholdMs();
|
|
92
112
|
/** Enqueue a decoded frame with timing information */
|
|
93
|
-
enqueue(frame: T, timestampUs: number, timing: FrameTiming): void;
|
|
113
|
+
enqueue(frame: T, timestampUs: number, timing: FrameTiming, isKeyframe?: boolean): void;
|
|
94
114
|
/** Dequeue frame for rendering at given real time (milliseconds) */
|
|
95
115
|
dequeue(realTimeMs: number): T | null;
|
|
96
116
|
/** Bypass mode: return latest frame, drop rest */
|
|
@@ -119,4 +139,6 @@ export declare class FrameScheduler<T> {
|
|
|
119
139
|
logStatus(): void;
|
|
120
140
|
/** Reset statistics */
|
|
121
141
|
resetStats(): void;
|
|
142
|
+
/** Get packet timing history for visualization */
|
|
143
|
+
getPacketTimingHistory(): PacketTimingEntry[];
|
|
122
144
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { BaseStreamSource } from './stream-source';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Track configuration for MoQ source
|
|
5
|
+
*/
|
|
6
|
+
export interface MoQTrack {
|
|
7
|
+
trackName: string;
|
|
8
|
+
priority?: number;
|
|
9
|
+
streamType: 'video' | 'audio' | 'data';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Configuration for MoQ source
|
|
13
|
+
*/
|
|
14
|
+
export interface MoQSourceConfig {
|
|
15
|
+
relayUrl: string;
|
|
16
|
+
namespace: string;
|
|
17
|
+
subscriptions: MoQTrack[];
|
|
18
|
+
reconnectionDelay?: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Factory function to create a MoQ source
|
|
22
|
+
*/
|
|
23
|
+
export declare function createMoQSource(config: MoQSourceConfig): MoQSource;
|
|
24
|
+
/**
|
|
25
|
+
* MoQ stream source implementation
|
|
26
|
+
*/
|
|
27
|
+
export declare class MoQSource extends BaseStreamSource {
|
|
28
|
+
private config;
|
|
29
|
+
private session;
|
|
30
|
+
private trackTypeMap;
|
|
31
|
+
private connecting;
|
|
32
|
+
constructor(config: MoQSourceConfig);
|
|
33
|
+
/**
|
|
34
|
+
* Connect to the MoQ relay
|
|
35
|
+
*/
|
|
36
|
+
connect(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Disconnect from the MoQ relay
|
|
39
|
+
*/
|
|
40
|
+
disconnect(): Promise<void>;
|
|
41
|
+
private setupEventListeners;
|
|
42
|
+
private handleIncomingData;
|
|
43
|
+
dispose(): void;
|
|
44
|
+
}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
import { BaseStreamSource } from './stream-source';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Track configuration for
|
|
4
|
+
* Track configuration for MoQ source
|
|
5
5
|
*/
|
|
6
|
-
export interface
|
|
6
|
+
export interface MoQTrack {
|
|
7
7
|
trackName: string;
|
|
8
8
|
priority?: number;
|
|
9
9
|
streamType: 'video' | 'audio' | 'data';
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Configuration for
|
|
12
|
+
* Configuration for MoQ source
|
|
13
13
|
*/
|
|
14
|
-
export interface
|
|
14
|
+
export interface MoQSourceConfig {
|
|
15
15
|
relayUrl: string;
|
|
16
16
|
namespace: string;
|
|
17
|
-
subscriptions:
|
|
17
|
+
subscriptions: MoQTrack[];
|
|
18
18
|
reconnectionDelay?: number;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
* Factory function to create a
|
|
21
|
+
* Factory function to create a MoQ source
|
|
22
22
|
*/
|
|
23
|
-
export declare function
|
|
23
|
+
export declare function createMoQSource(config: MoQSourceConfig): MoQSource;
|
|
24
24
|
/**
|
|
25
|
-
*
|
|
25
|
+
* MoQ stream source implementation
|
|
26
26
|
*/
|
|
27
|
-
export declare class
|
|
27
|
+
export declare class MoQSource extends BaseStreamSource {
|
|
28
28
|
private config;
|
|
29
29
|
private session;
|
|
30
30
|
private trackTypeMap;
|
|
31
31
|
private connecting;
|
|
32
|
-
constructor(config:
|
|
32
|
+
constructor(config: MoQSourceConfig);
|
|
33
33
|
/**
|
|
34
34
|
* Connect to the MoQ relay
|
|
35
35
|
*/
|