googlevideo 2.0.0 → 3.0.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.
- package/LICENSE +9 -9
- package/README.md +79 -66
- package/dist/protos/generated/misc/common.d.ts +0 -15
- package/dist/protos/generated/misc/common.js +1 -134
- package/dist/protos/generated/video_streaming/buffered_range.d.ts +0 -15
- package/dist/protos/generated/video_streaming/buffered_range.js +1 -147
- package/dist/protos/generated/video_streaming/client_abr_state.d.ts +16 -38
- package/dist/protos/generated/video_streaming/client_abr_state.js +95 -319
- package/dist/protos/generated/video_streaming/crypto_params.d.ts +0 -17
- package/dist/protos/generated/video_streaming/crypto_params.js +1 -79
- package/dist/protos/generated/video_streaming/encrypted_player_request.d.ts +2 -19
- package/dist/protos/generated/video_streaming/encrypted_player_request.js +9 -106
- package/dist/protos/generated/video_streaming/format_initialization_metadata.d.ts +0 -15
- package/dist/protos/generated/video_streaming/format_initialization_metadata.js +1 -75
- package/dist/protos/generated/video_streaming/live_metadata.d.ts +17 -0
- package/dist/protos/generated/video_streaming/live_metadata.js +122 -0
- package/dist/protos/generated/video_streaming/media_capabilities.d.ts +0 -15
- package/dist/protos/generated/video_streaming/media_capabilities.js +1 -122
- package/dist/protos/generated/video_streaming/media_header.d.ts +0 -17
- package/dist/protos/generated/video_streaming/media_header.js +1 -128
- package/dist/protos/generated/video_streaming/next_request_policy.d.ts +0 -15
- package/dist/protos/generated/video_streaming/next_request_policy.js +1 -50
- package/dist/protos/generated/video_streaming/onesie_header.d.ts +0 -15
- package/dist/protos/generated/video_streaming/onesie_header.js +1 -123
- package/dist/protos/generated/video_streaming/onesie_header_type.d.ts +0 -2
- package/dist/protos/generated/video_streaming/onesie_header_type.js +1 -146
- package/dist/protos/generated/video_streaming/onesie_player_request.d.ts +1 -17
- package/dist/protos/generated/video_streaming/onesie_player_request.js +5 -50
- package/dist/protos/generated/video_streaming/onesie_player_response.d.ts +18 -16
- package/dist/protos/generated/video_streaming/onesie_player_response.js +19 -54
- package/dist/protos/generated/video_streaming/onesie_request.d.ts +2 -15
- package/dist/protos/generated/video_streaming/onesie_request.js +11 -84
- package/dist/protos/generated/video_streaming/playback_cookie.d.ts +0 -15
- package/dist/protos/generated/video_streaming/playback_cookie.js +1 -43
- package/dist/protos/generated/video_streaming/playback_start_policy.d.ts +0 -15
- package/dist/protos/generated/video_streaming/playback_start_policy.js +1 -66
- package/dist/protos/generated/video_streaming/proxy_status.d.ts +0 -2
- package/dist/protos/generated/video_streaming/proxy_status.js +1 -66
- package/dist/protos/generated/video_streaming/request_cancellation_policy.d.ts +0 -15
- package/dist/protos/generated/video_streaming/request_cancellation_policy.js +1 -66
- package/dist/protos/generated/video_streaming/sabr_error.d.ts +0 -15
- package/dist/protos/generated/video_streaming/sabr_error.js +1 -29
- package/dist/protos/generated/video_streaming/sabr_redirect.d.ts +0 -15
- package/dist/protos/generated/video_streaming/sabr_redirect.js +1 -22
- package/dist/protos/generated/video_streaming/stream_protection_status.d.ts +0 -15
- package/dist/protos/generated/video_streaming/stream_protection_status.js +1 -29
- package/dist/protos/generated/video_streaming/streamer_context.d.ts +0 -17
- package/dist/protos/generated/video_streaming/streamer_context.js +1 -351
- package/dist/protos/generated/video_streaming/time_range.d.ts +0 -15
- package/dist/protos/generated/video_streaming/time_range.js +1 -34
- package/dist/protos/generated/video_streaming/video_playback_abr_request.d.ts +1 -15
- package/dist/protos/generated/video_streaming/video_playback_abr_request.js +19 -257
- package/dist/src/core/ServerAbrStream.d.ts +1 -0
- package/dist/src/core/ServerAbrStream.js +34 -47
- package/dist/src/core/UMP.d.ts +25 -1
- package/dist/src/core/UMP.js +35 -19
- package/dist/src/utils/Protos.d.ts +3 -2
- package/dist/src/utils/Protos.js +3 -2
- package/package.json +59 -60
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Code generated by protoc-gen-ts_proto. DO NOT EDIT.
|
|
2
2
|
// versions:
|
|
3
3
|
// protoc-gen-ts_proto v2.2.0
|
|
4
|
-
// protoc
|
|
4
|
+
// protoc v3.21.12
|
|
5
5
|
// source: video_streaming/video_playback_abr_request.proto
|
|
6
6
|
/* eslint-disable */
|
|
7
7
|
import { BinaryReader, BinaryWriter } from "@bufbuild/protobuf/wire";
|
|
@@ -15,6 +15,7 @@ function createBaseVideoPlaybackAbrRequest() {
|
|
|
15
15
|
clientAbrState: undefined,
|
|
16
16
|
selectedFormatIds: [],
|
|
17
17
|
bufferedRanges: [],
|
|
18
|
+
playerTimeMs: 0,
|
|
18
19
|
videoPlaybackUstreamerConfig: new Uint8Array(0),
|
|
19
20
|
lo: undefined,
|
|
20
21
|
selectedAudioFormatIds: [],
|
|
@@ -37,6 +38,9 @@ export const VideoPlaybackAbrRequest = {
|
|
|
37
38
|
for (const v of message.bufferedRanges) {
|
|
38
39
|
BufferedRange.encode(v, writer.uint32(26).fork()).join();
|
|
39
40
|
}
|
|
41
|
+
if (message.playerTimeMs !== undefined && message.playerTimeMs !== 0) {
|
|
42
|
+
writer.uint32(32).int64(message.playerTimeMs);
|
|
43
|
+
}
|
|
40
44
|
if (message.videoPlaybackUstreamerConfig !== undefined && message.videoPlaybackUstreamerConfig.length !== 0) {
|
|
41
45
|
writer.uint32(42).bytes(message.videoPlaybackUstreamerConfig);
|
|
42
46
|
}
|
|
@@ -91,6 +95,12 @@ export const VideoPlaybackAbrRequest = {
|
|
|
91
95
|
}
|
|
92
96
|
message.bufferedRanges.push(BufferedRange.decode(reader, reader.uint32()));
|
|
93
97
|
continue;
|
|
98
|
+
case 4:
|
|
99
|
+
if (tag !== 32) {
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
message.playerTimeMs = longToNumber(reader.int64());
|
|
103
|
+
continue;
|
|
94
104
|
case 5:
|
|
95
105
|
if (tag !== 42) {
|
|
96
106
|
break;
|
|
@@ -153,97 +163,6 @@ export const VideoPlaybackAbrRequest = {
|
|
|
153
163
|
}
|
|
154
164
|
return message;
|
|
155
165
|
},
|
|
156
|
-
fromJSON(object) {
|
|
157
|
-
return {
|
|
158
|
-
clientAbrState: isSet(object.clientAbrState) ? ClientAbrState.fromJSON(object.clientAbrState) : undefined,
|
|
159
|
-
selectedFormatIds: globalThis.Array.isArray(object?.selectedFormatIds)
|
|
160
|
-
? object.selectedFormatIds.map((e) => FormatId.fromJSON(e))
|
|
161
|
-
: [],
|
|
162
|
-
bufferedRanges: globalThis.Array.isArray(object?.bufferedRanges)
|
|
163
|
-
? object.bufferedRanges.map((e) => BufferedRange.fromJSON(e))
|
|
164
|
-
: [],
|
|
165
|
-
videoPlaybackUstreamerConfig: isSet(object.videoPlaybackUstreamerConfig)
|
|
166
|
-
? bytesFromBase64(object.videoPlaybackUstreamerConfig)
|
|
167
|
-
: new Uint8Array(0),
|
|
168
|
-
lo: isSet(object.lo) ? Lo.fromJSON(object.lo) : undefined,
|
|
169
|
-
selectedAudioFormatIds: globalThis.Array.isArray(object?.selectedAudioFormatIds)
|
|
170
|
-
? object.selectedAudioFormatIds.map((e) => FormatId.fromJSON(e))
|
|
171
|
-
: [],
|
|
172
|
-
selectedVideoFormatIds: globalThis.Array.isArray(object?.selectedVideoFormatIds)
|
|
173
|
-
? object.selectedVideoFormatIds.map((e) => FormatId.fromJSON(e))
|
|
174
|
-
: [],
|
|
175
|
-
streamerContext: isSet(object.streamerContext) ? StreamerContext.fromJSON(object.streamerContext) : undefined,
|
|
176
|
-
field21: isSet(object.field21) ? OQa.fromJSON(object.field21) : undefined,
|
|
177
|
-
field22: isSet(object.field22) ? globalThis.Number(object.field22) : 0,
|
|
178
|
-
field23: isSet(object.field23) ? globalThis.Number(object.field23) : 0,
|
|
179
|
-
field1000: globalThis.Array.isArray(object?.field1000) ? object.field1000.map((e) => Pqa.fromJSON(e)) : [],
|
|
180
|
-
};
|
|
181
|
-
},
|
|
182
|
-
toJSON(message) {
|
|
183
|
-
const obj = {};
|
|
184
|
-
if (message.clientAbrState !== undefined) {
|
|
185
|
-
obj.clientAbrState = ClientAbrState.toJSON(message.clientAbrState);
|
|
186
|
-
}
|
|
187
|
-
if (message.selectedFormatIds?.length) {
|
|
188
|
-
obj.selectedFormatIds = message.selectedFormatIds.map((e) => FormatId.toJSON(e));
|
|
189
|
-
}
|
|
190
|
-
if (message.bufferedRanges?.length) {
|
|
191
|
-
obj.bufferedRanges = message.bufferedRanges.map((e) => BufferedRange.toJSON(e));
|
|
192
|
-
}
|
|
193
|
-
if (message.videoPlaybackUstreamerConfig !== undefined && message.videoPlaybackUstreamerConfig.length !== 0) {
|
|
194
|
-
obj.videoPlaybackUstreamerConfig = base64FromBytes(message.videoPlaybackUstreamerConfig);
|
|
195
|
-
}
|
|
196
|
-
if (message.lo !== undefined) {
|
|
197
|
-
obj.lo = Lo.toJSON(message.lo);
|
|
198
|
-
}
|
|
199
|
-
if (message.selectedAudioFormatIds?.length) {
|
|
200
|
-
obj.selectedAudioFormatIds = message.selectedAudioFormatIds.map((e) => FormatId.toJSON(e));
|
|
201
|
-
}
|
|
202
|
-
if (message.selectedVideoFormatIds?.length) {
|
|
203
|
-
obj.selectedVideoFormatIds = message.selectedVideoFormatIds.map((e) => FormatId.toJSON(e));
|
|
204
|
-
}
|
|
205
|
-
if (message.streamerContext !== undefined) {
|
|
206
|
-
obj.streamerContext = StreamerContext.toJSON(message.streamerContext);
|
|
207
|
-
}
|
|
208
|
-
if (message.field21 !== undefined) {
|
|
209
|
-
obj.field21 = OQa.toJSON(message.field21);
|
|
210
|
-
}
|
|
211
|
-
if (message.field22 !== undefined && message.field22 !== 0) {
|
|
212
|
-
obj.field22 = Math.round(message.field22);
|
|
213
|
-
}
|
|
214
|
-
if (message.field23 !== undefined && message.field23 !== 0) {
|
|
215
|
-
obj.field23 = Math.round(message.field23);
|
|
216
|
-
}
|
|
217
|
-
if (message.field1000?.length) {
|
|
218
|
-
obj.field1000 = message.field1000.map((e) => Pqa.toJSON(e));
|
|
219
|
-
}
|
|
220
|
-
return obj;
|
|
221
|
-
},
|
|
222
|
-
create(base) {
|
|
223
|
-
return VideoPlaybackAbrRequest.fromPartial(base ?? {});
|
|
224
|
-
},
|
|
225
|
-
fromPartial(object) {
|
|
226
|
-
const message = createBaseVideoPlaybackAbrRequest();
|
|
227
|
-
message.clientAbrState = (object.clientAbrState !== undefined && object.clientAbrState !== null)
|
|
228
|
-
? ClientAbrState.fromPartial(object.clientAbrState)
|
|
229
|
-
: undefined;
|
|
230
|
-
message.selectedFormatIds = object.selectedFormatIds?.map((e) => FormatId.fromPartial(e)) || [];
|
|
231
|
-
message.bufferedRanges = object.bufferedRanges?.map((e) => BufferedRange.fromPartial(e)) || [];
|
|
232
|
-
message.videoPlaybackUstreamerConfig = object.videoPlaybackUstreamerConfig ?? new Uint8Array(0);
|
|
233
|
-
message.lo = (object.lo !== undefined && object.lo !== null) ? Lo.fromPartial(object.lo) : undefined;
|
|
234
|
-
message.selectedAudioFormatIds = object.selectedAudioFormatIds?.map((e) => FormatId.fromPartial(e)) || [];
|
|
235
|
-
message.selectedVideoFormatIds = object.selectedVideoFormatIds?.map((e) => FormatId.fromPartial(e)) || [];
|
|
236
|
-
message.streamerContext = (object.streamerContext !== undefined && object.streamerContext !== null)
|
|
237
|
-
? StreamerContext.fromPartial(object.streamerContext)
|
|
238
|
-
: undefined;
|
|
239
|
-
message.field21 = (object.field21 !== undefined && object.field21 !== null)
|
|
240
|
-
? OQa.fromPartial(object.field21)
|
|
241
|
-
: undefined;
|
|
242
|
-
message.field22 = object.field22 ?? 0;
|
|
243
|
-
message.field23 = object.field23 ?? 0;
|
|
244
|
-
message.field1000 = object.field1000?.map((e) => Pqa.fromPartial(e)) || [];
|
|
245
|
-
return message;
|
|
246
|
-
},
|
|
247
166
|
};
|
|
248
167
|
function createBaseLo() {
|
|
249
168
|
return { formatId: undefined, Lj: 0, sequenceNumber: 0, field4: undefined, MZ: 0 };
|
|
@@ -312,50 +231,6 @@ export const Lo = {
|
|
|
312
231
|
}
|
|
313
232
|
return message;
|
|
314
233
|
},
|
|
315
|
-
fromJSON(object) {
|
|
316
|
-
return {
|
|
317
|
-
formatId: isSet(object.formatId) ? FormatId.fromJSON(object.formatId) : undefined,
|
|
318
|
-
Lj: isSet(object.Lj) ? globalThis.Number(object.Lj) : 0,
|
|
319
|
-
sequenceNumber: isSet(object.sequenceNumber) ? globalThis.Number(object.sequenceNumber) : 0,
|
|
320
|
-
field4: isSet(object.field4) ? Lo_Field4.fromJSON(object.field4) : undefined,
|
|
321
|
-
MZ: isSet(object.MZ) ? globalThis.Number(object.MZ) : 0,
|
|
322
|
-
};
|
|
323
|
-
},
|
|
324
|
-
toJSON(message) {
|
|
325
|
-
const obj = {};
|
|
326
|
-
if (message.formatId !== undefined) {
|
|
327
|
-
obj.formatId = FormatId.toJSON(message.formatId);
|
|
328
|
-
}
|
|
329
|
-
if (message.Lj !== undefined && message.Lj !== 0) {
|
|
330
|
-
obj.Lj = Math.round(message.Lj);
|
|
331
|
-
}
|
|
332
|
-
if (message.sequenceNumber !== undefined && message.sequenceNumber !== 0) {
|
|
333
|
-
obj.sequenceNumber = Math.round(message.sequenceNumber);
|
|
334
|
-
}
|
|
335
|
-
if (message.field4 !== undefined) {
|
|
336
|
-
obj.field4 = Lo_Field4.toJSON(message.field4);
|
|
337
|
-
}
|
|
338
|
-
if (message.MZ !== undefined && message.MZ !== 0) {
|
|
339
|
-
obj.MZ = Math.round(message.MZ);
|
|
340
|
-
}
|
|
341
|
-
return obj;
|
|
342
|
-
},
|
|
343
|
-
create(base) {
|
|
344
|
-
return Lo.fromPartial(base ?? {});
|
|
345
|
-
},
|
|
346
|
-
fromPartial(object) {
|
|
347
|
-
const message = createBaseLo();
|
|
348
|
-
message.formatId = (object.formatId !== undefined && object.formatId !== null)
|
|
349
|
-
? FormatId.fromPartial(object.formatId)
|
|
350
|
-
: undefined;
|
|
351
|
-
message.Lj = object.Lj ?? 0;
|
|
352
|
-
message.sequenceNumber = object.sequenceNumber ?? 0;
|
|
353
|
-
message.field4 = (object.field4 !== undefined && object.field4 !== null)
|
|
354
|
-
? Lo_Field4.fromPartial(object.field4)
|
|
355
|
-
: undefined;
|
|
356
|
-
message.MZ = object.MZ ?? 0;
|
|
357
|
-
return message;
|
|
358
|
-
},
|
|
359
234
|
};
|
|
360
235
|
function createBaseLo_Field4() {
|
|
361
236
|
return { field1: 0, field2: 0, field3: 0 };
|
|
@@ -406,36 +281,6 @@ export const Lo_Field4 = {
|
|
|
406
281
|
}
|
|
407
282
|
return message;
|
|
408
283
|
},
|
|
409
|
-
fromJSON(object) {
|
|
410
|
-
return {
|
|
411
|
-
field1: isSet(object.field1) ? globalThis.Number(object.field1) : 0,
|
|
412
|
-
field2: isSet(object.field2) ? globalThis.Number(object.field2) : 0,
|
|
413
|
-
field3: isSet(object.field3) ? globalThis.Number(object.field3) : 0,
|
|
414
|
-
};
|
|
415
|
-
},
|
|
416
|
-
toJSON(message) {
|
|
417
|
-
const obj = {};
|
|
418
|
-
if (message.field1 !== undefined && message.field1 !== 0) {
|
|
419
|
-
obj.field1 = Math.round(message.field1);
|
|
420
|
-
}
|
|
421
|
-
if (message.field2 !== undefined && message.field2 !== 0) {
|
|
422
|
-
obj.field2 = Math.round(message.field2);
|
|
423
|
-
}
|
|
424
|
-
if (message.field3 !== undefined && message.field3 !== 0) {
|
|
425
|
-
obj.field3 = Math.round(message.field3);
|
|
426
|
-
}
|
|
427
|
-
return obj;
|
|
428
|
-
},
|
|
429
|
-
create(base) {
|
|
430
|
-
return Lo_Field4.fromPartial(base ?? {});
|
|
431
|
-
},
|
|
432
|
-
fromPartial(object) {
|
|
433
|
-
const message = createBaseLo_Field4();
|
|
434
|
-
message.field1 = object.field1 ?? 0;
|
|
435
|
-
message.field2 = object.field2 ?? 0;
|
|
436
|
-
message.field3 = object.field3 ?? 0;
|
|
437
|
-
return message;
|
|
438
|
-
},
|
|
439
284
|
};
|
|
440
285
|
function createBaseOQa() {
|
|
441
286
|
return { field1: [], field2: new Uint8Array(0), field3: "", field4: 0, field5: 0, field6: "" };
|
|
@@ -513,51 +358,6 @@ export const OQa = {
|
|
|
513
358
|
}
|
|
514
359
|
return message;
|
|
515
360
|
},
|
|
516
|
-
fromJSON(object) {
|
|
517
|
-
return {
|
|
518
|
-
field1: globalThis.Array.isArray(object?.field1) ? object.field1.map((e) => globalThis.String(e)) : [],
|
|
519
|
-
field2: isSet(object.field2) ? bytesFromBase64(object.field2) : new Uint8Array(0),
|
|
520
|
-
field3: isSet(object.field3) ? globalThis.String(object.field3) : "",
|
|
521
|
-
field4: isSet(object.field4) ? globalThis.Number(object.field4) : 0,
|
|
522
|
-
field5: isSet(object.field5) ? globalThis.Number(object.field5) : 0,
|
|
523
|
-
field6: isSet(object.field6) ? globalThis.String(object.field6) : "",
|
|
524
|
-
};
|
|
525
|
-
},
|
|
526
|
-
toJSON(message) {
|
|
527
|
-
const obj = {};
|
|
528
|
-
if (message.field1?.length) {
|
|
529
|
-
obj.field1 = message.field1;
|
|
530
|
-
}
|
|
531
|
-
if (message.field2 !== undefined && message.field2.length !== 0) {
|
|
532
|
-
obj.field2 = base64FromBytes(message.field2);
|
|
533
|
-
}
|
|
534
|
-
if (message.field3 !== undefined && message.field3 !== "") {
|
|
535
|
-
obj.field3 = message.field3;
|
|
536
|
-
}
|
|
537
|
-
if (message.field4 !== undefined && message.field4 !== 0) {
|
|
538
|
-
obj.field4 = Math.round(message.field4);
|
|
539
|
-
}
|
|
540
|
-
if (message.field5 !== undefined && message.field5 !== 0) {
|
|
541
|
-
obj.field5 = Math.round(message.field5);
|
|
542
|
-
}
|
|
543
|
-
if (message.field6 !== undefined && message.field6 !== "") {
|
|
544
|
-
obj.field6 = message.field6;
|
|
545
|
-
}
|
|
546
|
-
return obj;
|
|
547
|
-
},
|
|
548
|
-
create(base) {
|
|
549
|
-
return OQa.fromPartial(base ?? {});
|
|
550
|
-
},
|
|
551
|
-
fromPartial(object) {
|
|
552
|
-
const message = createBaseOQa();
|
|
553
|
-
message.field1 = object.field1?.map((e) => e) || [];
|
|
554
|
-
message.field2 = object.field2 ?? new Uint8Array(0);
|
|
555
|
-
message.field3 = object.field3 ?? "";
|
|
556
|
-
message.field4 = object.field4 ?? 0;
|
|
557
|
-
message.field5 = object.field5 ?? 0;
|
|
558
|
-
message.field6 = object.field6 ?? "";
|
|
559
|
-
return message;
|
|
560
|
-
},
|
|
561
361
|
};
|
|
562
362
|
function createBasePqa() {
|
|
563
363
|
return { formats: [], ud: [], clipId: "" };
|
|
@@ -608,52 +408,14 @@ export const Pqa = {
|
|
|
608
408
|
}
|
|
609
409
|
return message;
|
|
610
410
|
},
|
|
611
|
-
fromJSON(object) {
|
|
612
|
-
return {
|
|
613
|
-
formats: globalThis.Array.isArray(object?.formats) ? object.formats.map((e) => FormatId.fromJSON(e)) : [],
|
|
614
|
-
ud: globalThis.Array.isArray(object?.ud) ? object.ud.map((e) => BufferedRange.fromJSON(e)) : [],
|
|
615
|
-
clipId: isSet(object.clipId) ? globalThis.String(object.clipId) : "",
|
|
616
|
-
};
|
|
617
|
-
},
|
|
618
|
-
toJSON(message) {
|
|
619
|
-
const obj = {};
|
|
620
|
-
if (message.formats?.length) {
|
|
621
|
-
obj.formats = message.formats.map((e) => FormatId.toJSON(e));
|
|
622
|
-
}
|
|
623
|
-
if (message.ud?.length) {
|
|
624
|
-
obj.ud = message.ud.map((e) => BufferedRange.toJSON(e));
|
|
625
|
-
}
|
|
626
|
-
if (message.clipId !== undefined && message.clipId !== "") {
|
|
627
|
-
obj.clipId = message.clipId;
|
|
628
|
-
}
|
|
629
|
-
return obj;
|
|
630
|
-
},
|
|
631
|
-
create(base) {
|
|
632
|
-
return Pqa.fromPartial(base ?? {});
|
|
633
|
-
},
|
|
634
|
-
fromPartial(object) {
|
|
635
|
-
const message = createBasePqa();
|
|
636
|
-
message.formats = object.formats?.map((e) => FormatId.fromPartial(e)) || [];
|
|
637
|
-
message.ud = object.ud?.map((e) => BufferedRange.fromPartial(e)) || [];
|
|
638
|
-
message.clipId = object.clipId ?? "";
|
|
639
|
-
return message;
|
|
640
|
-
},
|
|
641
411
|
};
|
|
642
|
-
function
|
|
643
|
-
const
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
arr[i] = bin.charCodeAt(i);
|
|
412
|
+
function longToNumber(int64) {
|
|
413
|
+
const num = globalThis.Number(int64.toString());
|
|
414
|
+
if (num > globalThis.Number.MAX_SAFE_INTEGER) {
|
|
415
|
+
throw new globalThis.Error("Value is larger than Number.MAX_SAFE_INTEGER");
|
|
647
416
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
arr.forEach((byte) => {
|
|
653
|
-
bin.push(globalThis.String.fromCharCode(byte));
|
|
654
|
-
});
|
|
655
|
-
return globalThis.btoa(bin.join(""));
|
|
656
|
-
}
|
|
657
|
-
function isSet(value) {
|
|
658
|
-
return value !== null && value !== undefined;
|
|
417
|
+
if (num < globalThis.Number.MIN_SAFE_INTEGER) {
|
|
418
|
+
throw new globalThis.Error("Value is smaller than Number.MIN_SAFE_INTEGER");
|
|
419
|
+
}
|
|
420
|
+
return num;
|
|
659
421
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { UMP } from './UMP.js';
|
|
2
2
|
import { ChunkedDataBuffer } from './ChunkedDataBuffer.js';
|
|
3
3
|
import { EventEmitterLike, PART, QUALITY, base64ToU8, getFormatKey } from '../utils/index.js';
|
|
4
|
-
import { ClientAbrState_MediaType } from '../../protos/generated/video_streaming/client_abr_state.js';
|
|
5
4
|
import { VideoPlaybackAbrRequest } from '../../protos/generated/video_streaming/video_playback_abr_request.js';
|
|
6
5
|
import { MediaHeader } from '../../protos/generated/video_streaming/media_header.js';
|
|
7
6
|
import { NextRequestPolicy } from '../../protos/generated/video_streaming/next_request_policy.js';
|
|
@@ -40,11 +39,11 @@ export class ServerAbrStream extends EventEmitterLike {
|
|
|
40
39
|
const clientAbrState = {
|
|
41
40
|
lastManualDirection: 0,
|
|
42
41
|
timeSinceLastManualFormatSelectionMs: 0,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
lastManualSelectedResolution: videoFormats.length === 1 ? firstVideoFormat?.height : DEFAULT_QUALITY,
|
|
43
|
+
stickyResolution: videoFormats.length === 1 ? firstVideoFormat?.height : DEFAULT_QUALITY,
|
|
44
|
+
playerTimeMs: 0,
|
|
46
45
|
visibility: 0,
|
|
47
|
-
|
|
46
|
+
enabledTrackTypesBitfield: 0,
|
|
48
47
|
...initialState
|
|
49
48
|
};
|
|
50
49
|
const audioFormatIds = audioFormats.map((fmt) => ({
|
|
@@ -57,15 +56,15 @@ export class ServerAbrStream extends EventEmitterLike {
|
|
|
57
56
|
lastModified: parseInt(fmt.lastModified),
|
|
58
57
|
xtags: fmt.xtags
|
|
59
58
|
}));
|
|
60
|
-
if (typeof clientAbrState.
|
|
59
|
+
if (typeof clientAbrState.playerTimeMs !== 'number')
|
|
61
60
|
throw new Error('Invalid media start time');
|
|
62
61
|
try {
|
|
63
|
-
while (clientAbrState.
|
|
62
|
+
while (clientAbrState.playerTimeMs < this.totalDurationMs) {
|
|
64
63
|
const data = await this.fetchMedia({ clientAbrState, audioFormatIds, videoFormatIds });
|
|
65
64
|
this.emit('data', data);
|
|
66
65
|
if (data.sabrError)
|
|
67
66
|
break;
|
|
68
|
-
const mainFormat = clientAbrState.
|
|
67
|
+
const mainFormat = clientAbrState.enabledTrackTypesBitfield === 0
|
|
69
68
|
? data.initializedFormats.find((fmt) => fmt.mimeType?.includes('video'))
|
|
70
69
|
: data.initializedFormats[0];
|
|
71
70
|
for (const fmt of data.initializedFormats) {
|
|
@@ -77,11 +76,12 @@ export class ServerAbrStream extends EventEmitterLike {
|
|
|
77
76
|
this.emit('end', data);
|
|
78
77
|
break;
|
|
79
78
|
}
|
|
80
|
-
clientAbrState.
|
|
79
|
+
clientAbrState.playerTimeMs += mainFormat.sequenceList.reduce((acc, seq) => acc + (seq.durationMs || 0), 0);
|
|
81
80
|
}
|
|
82
81
|
}
|
|
83
82
|
catch (error) {
|
|
84
83
|
this.emit('error', error);
|
|
84
|
+
clientAbrState.playerTimeMs = Infinity;
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
87
|
async fetchMedia(args) {
|
|
@@ -170,27 +170,9 @@ export class ServerAbrStream extends EventEmitterLike {
|
|
|
170
170
|
if (!mediaHeader.formatId)
|
|
171
171
|
return;
|
|
172
172
|
const formatKey = getFormatKey(mediaHeader.formatId);
|
|
173
|
-
|
|
174
|
-
if (!currentFormat)
|
|
175
|
-
|
|
176
|
-
formatId: mediaHeader.formatId,
|
|
177
|
-
formatKey,
|
|
178
|
-
durationMs: mediaHeader.durationMs,
|
|
179
|
-
mimeType: undefined,
|
|
180
|
-
sequenceCount: undefined,
|
|
181
|
-
sequenceList: [],
|
|
182
|
-
mediaChunks: [],
|
|
183
|
-
_state: {
|
|
184
|
-
formatId: mediaHeader.formatId,
|
|
185
|
-
startTimeMs: 0,
|
|
186
|
-
durationMs: 0,
|
|
187
|
-
startSegmentIndex: 1,
|
|
188
|
-
endSegmentIndex: 0
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
this.formatsByKey.set(formatKey, this.initializedFormats[this.initializedFormats.length - 1]);
|
|
192
|
-
currentFormat = this.formatsByKey.get(formatKey);
|
|
193
|
-
}
|
|
173
|
+
const currentFormat = this.formatsByKey.get(formatKey) || this.registerFormat(mediaHeader);
|
|
174
|
+
if (!currentFormat)
|
|
175
|
+
return;
|
|
194
176
|
// FIXME: This is a hacky workaround to prevent duplicate sequences from being added. This should be fixed in the future (preferably by figuring out how to make the server not send duplicates).
|
|
195
177
|
if (mediaHeader.sequenceNumber !== undefined && this.previousSequences.get(formatKey)?.includes(mediaHeader.sequenceNumber))
|
|
196
178
|
return;
|
|
@@ -239,34 +221,39 @@ export class ServerAbrStream extends EventEmitterLike {
|
|
|
239
221
|
}
|
|
240
222
|
processFormatInitialization(data) {
|
|
241
223
|
const formatInitializationMetadata = FormatInitializationMetadata.decode(data);
|
|
242
|
-
|
|
224
|
+
this.registerFormat(formatInitializationMetadata);
|
|
225
|
+
}
|
|
226
|
+
processSabrRedirect(data) {
|
|
227
|
+
const sabrRedirect = SabrRedirect.decode(data);
|
|
228
|
+
if (!sabrRedirect.url)
|
|
229
|
+
throw new Error('Invalid SABR redirect');
|
|
230
|
+
this.serverAbrStreamingUrl = sabrRedirect.url;
|
|
231
|
+
return sabrRedirect;
|
|
232
|
+
}
|
|
233
|
+
registerFormat(data) {
|
|
234
|
+
if (!data.formatId)
|
|
243
235
|
return;
|
|
244
|
-
const formatKey = getFormatKey(
|
|
236
|
+
const formatKey = getFormatKey(data.formatId);
|
|
245
237
|
if (!this.formatsByKey.has(formatKey)) {
|
|
246
|
-
|
|
247
|
-
formatId:
|
|
248
|
-
formatKey:
|
|
249
|
-
durationMs:
|
|
250
|
-
mimeType:
|
|
251
|
-
sequenceCount:
|
|
238
|
+
const format = {
|
|
239
|
+
formatId: data.formatId,
|
|
240
|
+
formatKey: formatKey,
|
|
241
|
+
durationMs: data.durationMs,
|
|
242
|
+
mimeType: 'mimeType' in data ? data.mimeType : undefined,
|
|
243
|
+
sequenceCount: 'field4' in data ? data.field4 : undefined,
|
|
252
244
|
sequenceList: [],
|
|
253
245
|
mediaChunks: [],
|
|
254
246
|
_state: {
|
|
255
|
-
formatId:
|
|
247
|
+
formatId: data.formatId,
|
|
256
248
|
startTimeMs: 0,
|
|
257
249
|
durationMs: 0,
|
|
258
250
|
startSegmentIndex: 1,
|
|
259
251
|
endSegmentIndex: 0
|
|
260
252
|
}
|
|
261
|
-
}
|
|
253
|
+
};
|
|
254
|
+
this.initializedFormats.push(format);
|
|
262
255
|
this.formatsByKey.set(formatKey, this.initializedFormats[this.initializedFormats.length - 1]);
|
|
256
|
+
return format;
|
|
263
257
|
}
|
|
264
258
|
}
|
|
265
|
-
processSabrRedirect(data) {
|
|
266
|
-
const sabrRedirect = SabrRedirect.decode(data);
|
|
267
|
-
if (!sabrRedirect.url)
|
|
268
|
-
throw new Error('Invalid SABR redirect');
|
|
269
|
-
this.serverAbrStreamingUrl = sabrRedirect.url;
|
|
270
|
-
return sabrRedirect;
|
|
271
|
-
}
|
|
272
259
|
}
|
package/dist/src/core/UMP.d.ts
CHANGED
|
@@ -2,9 +2,33 @@ import type { Part } from '../index.js';
|
|
|
2
2
|
import type { ChunkedDataBuffer } from './ChunkedDataBuffer.js';
|
|
3
3
|
export declare class UMP {
|
|
4
4
|
private chunkedDataBuffer;
|
|
5
|
+
/**
|
|
6
|
+
* Creates a new UMP parser.
|
|
7
|
+
* @param chunkedDataBuffer - Buffer containing UMP format data.
|
|
8
|
+
*/
|
|
5
9
|
constructor(chunkedDataBuffer: ChunkedDataBuffer);
|
|
6
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Parses parts from the buffer and calls the handler for each complete part.
|
|
12
|
+
* @param handlePart - Function called with each complete part.
|
|
13
|
+
* @returns Partial part if parsing is incomplete, undefined otherwise.
|
|
14
|
+
*/
|
|
15
|
+
parse(handlePart: (part: Part) => void): Part | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Reads a variable-length integer from the buffer.
|
|
18
|
+
* @param offset - Position to start reading from.
|
|
19
|
+
* @returns Tuple of [value, new offset] or [-1, offset] if incomplete.
|
|
20
|
+
*/
|
|
7
21
|
readVarInt(offset: number): [number, number];
|
|
22
|
+
/**
|
|
23
|
+
* Checks if the specified bytes can be read from the current chunk.
|
|
24
|
+
* @param offset - Position to start reading from.
|
|
25
|
+
* @param length - Number of bytes to read.
|
|
26
|
+
* @returns True if bytes can be read from current chunk, false otherwise.
|
|
27
|
+
*/
|
|
8
28
|
canReadFromCurrentChunk(offset: number, length: number): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Gets a DataView of the current chunk, creating it if necessary.
|
|
31
|
+
* @returns DataView for the current chunk.
|
|
32
|
+
*/
|
|
9
33
|
getCurrentDataView(): DataView;
|
|
10
34
|
}
|
package/dist/src/core/UMP.js
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
export class UMP {
|
|
2
|
+
/**
|
|
3
|
+
* Creates a new UMP parser.
|
|
4
|
+
* @param chunkedDataBuffer - Buffer containing UMP format data.
|
|
5
|
+
*/
|
|
2
6
|
constructor(chunkedDataBuffer) {
|
|
3
7
|
this.chunkedDataBuffer = chunkedDataBuffer;
|
|
4
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Parses parts from the buffer and calls the handler for each complete part.
|
|
11
|
+
* @param handlePart - Function called with each complete part.
|
|
12
|
+
* @returns Partial part if parsing is incomplete, undefined otherwise.
|
|
13
|
+
*/
|
|
5
14
|
parse(handlePart) {
|
|
6
15
|
while (true) {
|
|
7
16
|
let offset = 0;
|
|
@@ -11,9 +20,15 @@ export class UMP {
|
|
|
11
20
|
offset = finalOffset;
|
|
12
21
|
if (partType < 0 || partSize < 0)
|
|
13
22
|
break;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
23
|
+
if (!this.chunkedDataBuffer.canReadBytes(offset, partSize)) {
|
|
24
|
+
if (!this.chunkedDataBuffer.canReadBytes(offset, 1))
|
|
25
|
+
break;
|
|
26
|
+
return {
|
|
27
|
+
type: partType,
|
|
28
|
+
size: partSize,
|
|
29
|
+
data: this.chunkedDataBuffer
|
|
30
|
+
};
|
|
31
|
+
}
|
|
17
32
|
const splitResult = this.chunkedDataBuffer.split(offset).remainingBuffer.split(partSize);
|
|
18
33
|
offset = 0;
|
|
19
34
|
handlePart({
|
|
@@ -24,26 +39,17 @@ export class UMP {
|
|
|
24
39
|
this.chunkedDataBuffer = splitResult.remainingBuffer;
|
|
25
40
|
}
|
|
26
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Reads a variable-length integer from the buffer.
|
|
44
|
+
* @param offset - Position to start reading from.
|
|
45
|
+
* @returns Tuple of [value, new offset] or [-1, offset] if incomplete.
|
|
46
|
+
*/
|
|
27
47
|
readVarInt(offset) {
|
|
28
48
|
let byteLength;
|
|
49
|
+
// Determine the length of the val
|
|
29
50
|
if (this.chunkedDataBuffer.canReadBytes(offset, 1)) {
|
|
30
51
|
const firstByte = this.chunkedDataBuffer.getUint8(offset);
|
|
31
|
-
|
|
32
|
-
if (firstByte < 128) {
|
|
33
|
-
byteLength = 1;
|
|
34
|
-
}
|
|
35
|
-
else if (firstByte < 192) {
|
|
36
|
-
byteLength = 2;
|
|
37
|
-
}
|
|
38
|
-
else if (firstByte < 224) {
|
|
39
|
-
byteLength = 3;
|
|
40
|
-
}
|
|
41
|
-
else if (firstByte < 240) {
|
|
42
|
-
byteLength = 4;
|
|
43
|
-
}
|
|
44
|
-
else {
|
|
45
|
-
byteLength = 5;
|
|
46
|
-
}
|
|
52
|
+
byteLength = firstByte < 128 ? 1 : firstByte < 192 ? 2 : firstByte < 224 ? 3 : firstByte < 240 ? 4 : 5;
|
|
47
53
|
}
|
|
48
54
|
else {
|
|
49
55
|
byteLength = 0;
|
|
@@ -96,9 +102,19 @@ export class UMP {
|
|
|
96
102
|
}
|
|
97
103
|
return [value, offset];
|
|
98
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Checks if the specified bytes can be read from the current chunk.
|
|
107
|
+
* @param offset - Position to start reading from.
|
|
108
|
+
* @param length - Number of bytes to read.
|
|
109
|
+
* @returns True if bytes can be read from current chunk, false otherwise.
|
|
110
|
+
*/
|
|
99
111
|
canReadFromCurrentChunk(offset, length) {
|
|
100
112
|
return offset - this.chunkedDataBuffer.currentChunkOffset + length <= this.chunkedDataBuffer.chunks[this.chunkedDataBuffer.currentChunkIndex].length;
|
|
101
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Gets a DataView of the current chunk, creating it if necessary.
|
|
116
|
+
* @returns DataView for the current chunk.
|
|
117
|
+
*/
|
|
102
118
|
getCurrentDataView() {
|
|
103
119
|
if (!this.chunkedDataBuffer.currentDataView) {
|
|
104
120
|
const currentChunk = this.chunkedDataBuffer.chunks[this.chunkedDataBuffer.currentChunkIndex];
|
|
@@ -14,10 +14,11 @@ export { EncryptedPlayerRequest } from '../../protos/generated/video_streaming/e
|
|
|
14
14
|
export { OnesieHeader } from '../../protos/generated/video_streaming/onesie_header.js';
|
|
15
15
|
export { OnesieHeaderType } from '../../protos/generated/video_streaming/onesie_header_type.js';
|
|
16
16
|
export { OnesiePlayerRequest } from '../../protos/generated/video_streaming/onesie_player_request.js';
|
|
17
|
-
export { OnesiePlayerResponse } from '../../protos/generated/video_streaming/onesie_player_response.js';
|
|
17
|
+
export { OnesiePlayerResponse, OnesieProxyStatus } from '../../protos/generated/video_streaming/onesie_player_response.js';
|
|
18
18
|
export { ClientAbrState } from '../../protos/generated/video_streaming/client_abr_state.js';
|
|
19
19
|
export { StreamerContext } from '../../protos/generated/video_streaming/streamer_context.js';
|
|
20
20
|
export { ProxyStatus } from '../../protos/generated/video_streaming/proxy_status.js';
|
|
21
21
|
export { MediaCapabilities } from '../../protos/generated/video_streaming/media_capabilities.js';
|
|
22
22
|
export { CryptoParams } from '../../protos/generated/video_streaming/crypto_params.js';
|
|
23
|
-
export {
|
|
23
|
+
export { LiveMetadata } from '../../protos/generated/video_streaming/live_metadata.js';
|
|
24
|
+
export { FormatId, KeyValuePair, InitRange, IndexRange, HttpHeader } from '../../protos/generated/misc/common.js';
|
package/dist/src/utils/Protos.js
CHANGED
|
@@ -14,10 +14,11 @@ export { EncryptedPlayerRequest } from '../../protos/generated/video_streaming/e
|
|
|
14
14
|
export { OnesieHeader } from '../../protos/generated/video_streaming/onesie_header.js';
|
|
15
15
|
export { OnesieHeaderType } from '../../protos/generated/video_streaming/onesie_header_type.js';
|
|
16
16
|
export { OnesiePlayerRequest } from '../../protos/generated/video_streaming/onesie_player_request.js';
|
|
17
|
-
export { OnesiePlayerResponse } from '../../protos/generated/video_streaming/onesie_player_response.js';
|
|
17
|
+
export { OnesiePlayerResponse, OnesieProxyStatus } from '../../protos/generated/video_streaming/onesie_player_response.js';
|
|
18
18
|
export { ClientAbrState } from '../../protos/generated/video_streaming/client_abr_state.js';
|
|
19
19
|
export { StreamerContext } from '../../protos/generated/video_streaming/streamer_context.js';
|
|
20
20
|
export { ProxyStatus } from '../../protos/generated/video_streaming/proxy_status.js';
|
|
21
21
|
export { MediaCapabilities } from '../../protos/generated/video_streaming/media_capabilities.js';
|
|
22
22
|
export { CryptoParams } from '../../protos/generated/video_streaming/crypto_params.js';
|
|
23
|
-
export {
|
|
23
|
+
export { LiveMetadata } from '../../protos/generated/video_streaming/live_metadata.js';
|
|
24
|
+
export { FormatId, KeyValuePair, InitRange, IndexRange, HttpHeader } from '../../protos/generated/misc/common.js';
|