@relaymessenger/livekit 0.1.0-staging.15 → 0.1.0-staging.17
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 +16 -187
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/livekit.d.ts +7 -1
- package/dist/livekit.d.ts.map +1 -1
- package/dist/livekit.js +19 -7
- package/dist/livekit.js.map +1 -1
- package/package.json +3 -8
- package/dist/engine-werift-video.d.ts +0 -70
- package/dist/engine-werift-video.d.ts.map +0 -1
- package/dist/engine-werift-video.js +0 -594
- package/dist/engine-werift-video.js.map +0 -1
- package/dist/engine-werift.d.ts +0 -48
- package/dist/engine-werift.d.ts.map +0 -1
- package/dist/engine-werift.js +0 -457
- package/dist/engine-werift.js.map +0 -1
- package/dist/transport.d.ts +0 -314
- package/dist/transport.d.ts.map +0 -1
- package/dist/transport.js +0 -1303
- package/dist/transport.js.map +0 -1
- package/dist/video-frame.d.ts +0 -56
- package/dist/video-frame.d.ts.map +0 -1
- package/dist/video-frame.js +0 -245
- package/dist/video-frame.js.map +0 -1
- package/dist/video-rtp.d.ts +0 -51
- package/dist/video-rtp.d.ts.map +0 -1
- package/dist/video-rtp.js +0 -294
- package/dist/video-rtp.js.map +0 -1
- package/dist/video.d.ts +0 -144
- package/dist/video.d.ts.map +0 -1
- package/dist/video.js +0 -228
- package/dist/video.js.map +0 -1
package/dist/video.js
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Video tracks for Relay calls, with LiveKit's public API shape.
|
|
3
|
-
*
|
|
4
|
-
* Names and semantics copied from `@livekit/rtc-node` 0.13.35
|
|
5
|
-
* (node_modules/@livekit/rtc-node/src):
|
|
6
|
-
* - video_source.ts:18-75: `new VideoSource(width, height)`,
|
|
7
|
-
* `captureFrame(frame, timestampUs = BigInt(0), rotation = VIDEO_ROTATION_0)`
|
|
8
|
-
* which throws "VideoSource is closed" after `close()`.
|
|
9
|
-
* - track.ts:241-268: `LocalVideoTrack.createVideoTrack(name, source)` and
|
|
10
|
-
* `close(closeSource = true)`.
|
|
11
|
-
* - video_stream.ts:12-16 and :94-98: `VideoFrameEvent { frame, timestampUs,
|
|
12
|
-
* rotation }` and `class VideoStream extends ReadableStream<VideoFrameEvent>`
|
|
13
|
-
* built from a remote track, read with `for await`.
|
|
14
|
-
* - participant.ts:737 `publishTrack(track, options)` and :783
|
|
15
|
-
* `unpublishTrack(...)`; the publish options `videoCodec` and
|
|
16
|
-
* `videoEncoding { maxBitrate, maxFramerate }` from
|
|
17
|
-
* @livekit/rtc-ffi-bindings proto/room_pb.d.ts:1792-1859, and `VideoCodec`
|
|
18
|
-
* (VP8 = 0, H264 = 1) from proto/video_frame_pb.d.ts:28-50.
|
|
19
|
-
* The optional `{ capacity, format }` of `VideoStream` is LiveKit's Python SDK
|
|
20
|
-
* (livekit-rtc/livekit/rtc/video_stream.py:42-60, `RingQueue` in _utils.py:78-94:
|
|
21
|
-
* capacity 0 keeps every frame, a positive capacity drops the oldest).
|
|
22
|
-
*
|
|
23
|
-
* Relay semantics (PROTOCOL.md sections 1-2, _artifacts/calls-facetime-20260922):
|
|
24
|
-
* a participant publishes at most one `video` track; publishing it the first
|
|
25
|
-
* time negotiates it with an add-track offer and announces `userUpdate
|
|
26
|
-
* { video: true }`; unpublishing stops sending and announces `video: false`
|
|
27
|
-
* but leaves the track negotiated, so publishing again only resumes.
|
|
28
|
-
*/
|
|
29
|
-
import { ReadableStream } from "node:stream/web";
|
|
30
|
-
import { VideoBufferType, VideoFrame, VideoRotation } from "./video-frame.js";
|
|
31
|
-
export { VideoBufferType, VideoFrame, VideoRotation } from "./video-frame.js";
|
|
32
|
-
/** Same names and numbers as LiveKit's `VideoCodec`; Relay sends these two. */
|
|
33
|
-
export var VideoCodec;
|
|
34
|
-
(function (VideoCodec) {
|
|
35
|
-
VideoCodec[VideoCodec["VP8"] = 0] = "VP8";
|
|
36
|
-
VideoCodec[VideoCodec["H264"] = 1] = "H264";
|
|
37
|
-
})(VideoCodec || (VideoCodec = {}));
|
|
38
|
-
export class VideoSource {
|
|
39
|
-
width;
|
|
40
|
-
height;
|
|
41
|
-
/** @internal */
|
|
42
|
-
closed = false;
|
|
43
|
-
#sinks = new Set();
|
|
44
|
-
constructor(width, height) {
|
|
45
|
-
this.width = width;
|
|
46
|
-
this.height = height;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Hand one raw frame to the published track. RGBA, BGRA and I420 (LiveKit
|
|
50
|
-
* `VideoBufferType`) go to the encoder as they are; the other packed RGB
|
|
51
|
-
* layouts are converted to I420 first. `timestampUs` 0 means "now".
|
|
52
|
-
* Frames captured while the track is not published are dropped.
|
|
53
|
-
*/
|
|
54
|
-
captureFrame(frame, timestampUs = BigInt(0), rotation = VideoRotation.VIDEO_ROTATION_0) {
|
|
55
|
-
if (this.closed)
|
|
56
|
-
throw new Error("VideoSource is closed");
|
|
57
|
-
for (const sink of this.#sinks)
|
|
58
|
-
sink(frame, timestampUs, rotation);
|
|
59
|
-
}
|
|
60
|
-
async close() {
|
|
61
|
-
this.closed = true;
|
|
62
|
-
this.#sinks.clear();
|
|
63
|
-
}
|
|
64
|
-
/** @internal */
|
|
65
|
-
_attach(sink) {
|
|
66
|
-
this.#sinks.add(sink);
|
|
67
|
-
return () => this.#sinks.delete(sink);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
export class LocalVideoTrack {
|
|
71
|
-
kind = "video";
|
|
72
|
-
name;
|
|
73
|
-
/** @internal */
|
|
74
|
-
source;
|
|
75
|
-
constructor(name, source) {
|
|
76
|
-
this.name = name;
|
|
77
|
-
this.source = source;
|
|
78
|
-
}
|
|
79
|
-
static createVideoTrack(name, source) {
|
|
80
|
-
return new LocalVideoTrack(name, source);
|
|
81
|
-
}
|
|
82
|
-
async close(closeSource = true) {
|
|
83
|
-
if (closeSource)
|
|
84
|
-
await this.source.close();
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* The other participant's camera. Emitted once per call by the transport's
|
|
89
|
-
* `trackSubscribed` event; it survives SFU restarts (the transport moves it
|
|
90
|
-
* onto the new session's receiver), so a `VideoStream` read from it keeps going.
|
|
91
|
-
*/
|
|
92
|
-
export class RemoteVideoTrack {
|
|
93
|
-
kind = "video";
|
|
94
|
-
name = "video";
|
|
95
|
-
#receiver;
|
|
96
|
-
#retired;
|
|
97
|
-
#consumers = new Set();
|
|
98
|
-
#ended = false;
|
|
99
|
-
/** Counters summed over every receiver this track has had. */
|
|
100
|
-
stats() {
|
|
101
|
-
const current = this.#receiver?.stats();
|
|
102
|
-
const retired = this.#retired;
|
|
103
|
-
if (!retired)
|
|
104
|
-
return current;
|
|
105
|
-
if (!current)
|
|
106
|
-
return { ...retired, recentFrames: 0 };
|
|
107
|
-
return {
|
|
108
|
-
...current,
|
|
109
|
-
rtpPackets: retired.rtpPackets + current.rtpPackets,
|
|
110
|
-
framesAssembled: retired.framesAssembled + current.framesAssembled,
|
|
111
|
-
framesDropped: retired.framesDropped + current.framesDropped,
|
|
112
|
-
framesDecoded: retired.framesDecoded + current.framesDecoded,
|
|
113
|
-
decodeErrors: retired.decodeErrors + current.decodeErrors,
|
|
114
|
-
keyframeRequests: retired.keyframeRequests + current.keyframeRequests,
|
|
115
|
-
firstFrameAt: retired.firstFrameAt ?? current.firstFrameAt,
|
|
116
|
-
lastFrameAt: current.lastFrameAt ?? retired.lastFrameAt,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
/** @internal The transport moves the track onto a new session's receiver. */
|
|
120
|
-
_attach(receiver) {
|
|
121
|
-
this._detach();
|
|
122
|
-
this.#receiver = receiver;
|
|
123
|
-
receiver.onframe = (event) => {
|
|
124
|
-
for (const consumer of this.#consumers)
|
|
125
|
-
consumer.push(event);
|
|
126
|
-
};
|
|
127
|
-
receiver.setActive(this.#consumers.size > 0);
|
|
128
|
-
}
|
|
129
|
-
/** @internal */
|
|
130
|
-
_detach() {
|
|
131
|
-
const receiver = this.#receiver;
|
|
132
|
-
if (!receiver)
|
|
133
|
-
return;
|
|
134
|
-
this.#receiver = undefined;
|
|
135
|
-
const stats = receiver.stats();
|
|
136
|
-
const retired = this.#retired;
|
|
137
|
-
this.#retired = retired
|
|
138
|
-
? {
|
|
139
|
-
...stats,
|
|
140
|
-
rtpPackets: retired.rtpPackets + stats.rtpPackets,
|
|
141
|
-
framesAssembled: retired.framesAssembled + stats.framesAssembled,
|
|
142
|
-
framesDropped: retired.framesDropped + stats.framesDropped,
|
|
143
|
-
framesDecoded: retired.framesDecoded + stats.framesDecoded,
|
|
144
|
-
decodeErrors: retired.decodeErrors + stats.decodeErrors,
|
|
145
|
-
keyframeRequests: retired.keyframeRequests + stats.keyframeRequests,
|
|
146
|
-
firstFrameAt: retired.firstFrameAt ?? stats.firstFrameAt,
|
|
147
|
-
lastFrameAt: stats.lastFrameAt ?? retired.lastFrameAt,
|
|
148
|
-
}
|
|
149
|
-
: stats;
|
|
150
|
-
receiver.onframe = null;
|
|
151
|
-
receiver.stop();
|
|
152
|
-
}
|
|
153
|
-
/** @internal The call is over: every `VideoStream` ends. */
|
|
154
|
-
_end() {
|
|
155
|
-
this._detach();
|
|
156
|
-
this.#ended = true;
|
|
157
|
-
for (const consumer of [...this.#consumers])
|
|
158
|
-
consumer.end();
|
|
159
|
-
this.#consumers.clear();
|
|
160
|
-
}
|
|
161
|
-
/** @internal */
|
|
162
|
-
_subscribe(consumer) {
|
|
163
|
-
if (this.#ended) {
|
|
164
|
-
consumer.end();
|
|
165
|
-
return () => undefined;
|
|
166
|
-
}
|
|
167
|
-
this.#consumers.add(consumer);
|
|
168
|
-
if (this.#consumers.size === 1)
|
|
169
|
-
this.#receiver?.setActive(true);
|
|
170
|
-
return () => {
|
|
171
|
-
this.#consumers.delete(consumer);
|
|
172
|
-
if (this.#consumers.size === 0)
|
|
173
|
-
this.#receiver?.setActive(false);
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Decoded frames of a remote video track. Decoding starts when the first
|
|
179
|
-
* stream opens and stops when the last one is cancelled.
|
|
180
|
-
*/
|
|
181
|
-
export class VideoStream extends ReadableStream {
|
|
182
|
-
constructor(track, options = {}) {
|
|
183
|
-
const capacity = options.capacity ?? 0;
|
|
184
|
-
const format = options.format;
|
|
185
|
-
const queue = [];
|
|
186
|
-
let waiting;
|
|
187
|
-
let ended = false;
|
|
188
|
-
let unsubscribe;
|
|
189
|
-
const wake = () => {
|
|
190
|
-
const resolve = waiting;
|
|
191
|
-
waiting = undefined;
|
|
192
|
-
resolve?.();
|
|
193
|
-
};
|
|
194
|
-
super({
|
|
195
|
-
start: () => {
|
|
196
|
-
unsubscribe = track._subscribe({
|
|
197
|
-
push: (event) => {
|
|
198
|
-
if (capacity > 0 && queue.length >= capacity)
|
|
199
|
-
queue.shift();
|
|
200
|
-
queue.push(event);
|
|
201
|
-
wake();
|
|
202
|
-
},
|
|
203
|
-
end: () => {
|
|
204
|
-
ended = true;
|
|
205
|
-
wake();
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
},
|
|
209
|
-
pull: async (controller) => {
|
|
210
|
-
while (queue.length === 0 && !ended)
|
|
211
|
-
await new Promise((resolve) => { waiting = resolve; });
|
|
212
|
-
const event = queue.shift();
|
|
213
|
-
if (!event) {
|
|
214
|
-
controller.close();
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
const frame = format === undefined || format === event.frame.type ? event.frame : event.frame.convert(format);
|
|
218
|
-
controller.enqueue({ ...event, frame });
|
|
219
|
-
},
|
|
220
|
-
cancel: () => {
|
|
221
|
-
unsubscribe?.();
|
|
222
|
-
ended = true;
|
|
223
|
-
wake();
|
|
224
|
-
},
|
|
225
|
-
}, { highWaterMark: 0 });
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
//# sourceMappingURL=video.js.map
|
package/dist/video.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"video.js","sourceRoot":"","sources":["../src/video.ts"],"names":[],"mappings":"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"}
|