googlevideo 2.0.0 → 4.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 +127 -66
- package/dist/protos/generated/misc/common.d.ts +180 -21
- package/dist/protos/generated/misc/common.js +277 -147
- package/dist/protos/generated/misc/common.js.map +1 -0
- package/dist/protos/generated/video_streaming/buffered_range.d.ts +10 -25
- package/dist/protos/generated/video_streaming/buffered_range.js +21 -166
- package/dist/protos/generated/video_streaming/buffered_range.js.map +1 -0
- package/dist/protos/generated/video_streaming/client_abr_state.d.ts +34 -45
- package/dist/protos/generated/video_streaming/client_abr_state.js +209 -350
- package/dist/protos/generated/video_streaming/client_abr_state.js.map +1 -0
- package/dist/protos/generated/video_streaming/crypto_params.d.ts +2 -24
- package/dist/protos/generated/video_streaming/crypto_params.js +2 -86
- package/dist/protos/generated/video_streaming/crypto_params.js.map +1 -0
- package/dist/protos/generated/video_streaming/format_initialization_metadata.d.ts +6 -21
- package/dist/protos/generated/video_streaming/format_initialization_metadata.js +32 -95
- package/dist/protos/generated/video_streaming/format_initialization_metadata.js.map +1 -0
- package/dist/protos/generated/video_streaming/format_selection_config.d.ts +12 -0
- package/dist/protos/generated/video_streaming/format_selection_config.js +68 -0
- package/dist/protos/generated/video_streaming/format_selection_config.js.map +1 -0
- package/dist/protos/generated/video_streaming/innertube_request.d.ts +25 -0
- package/dist/protos/generated/video_streaming/innertube_request.js +186 -0
- package/dist/protos/generated/video_streaming/innertube_request.js.map +1 -0
- package/dist/protos/generated/video_streaming/live_metadata.d.ts +20 -0
- package/dist/protos/generated/video_streaming/live_metadata.js +153 -0
- package/dist/protos/generated/video_streaming/live_metadata.js.map +1 -0
- package/dist/protos/generated/video_streaming/media_capabilities.d.ts +0 -15
- package/dist/protos/generated/video_streaming/media_capabilities.js +2 -122
- package/dist/protos/generated/video_streaming/media_capabilities.js.map +1 -0
- package/dist/protos/generated/video_streaming/media_header.d.ts +5 -27
- package/dist/protos/generated/video_streaming/media_header.js +28 -151
- package/dist/protos/generated/video_streaming/media_header.js.map +1 -0
- package/dist/protos/generated/video_streaming/next_request_policy.d.ts +3 -15
- package/dist/protos/generated/video_streaming/next_request_policy.js +32 -50
- package/dist/protos/generated/video_streaming/next_request_policy.js.map +1 -0
- package/dist/protos/generated/video_streaming/onesie_header.d.ts +7 -22
- package/dist/protos/generated/video_streaming/onesie_header.js +16 -137
- package/dist/protos/generated/video_streaming/onesie_header.js.map +1 -0
- package/dist/protos/generated/video_streaming/onesie_header_type.d.ts +9 -25
- package/dist/protos/generated/video_streaming/onesie_header_type.js +17 -176
- package/dist/protos/generated/video_streaming/onesie_header_type.js.map +1 -0
- package/dist/protos/generated/video_streaming/onesie_innertube_request.d.ts +15 -0
- package/dist/protos/generated/video_streaming/{onesie_player_request.js → onesie_innertube_request.js} +10 -54
- package/dist/protos/generated/video_streaming/onesie_innertube_request.js.map +1 -0
- package/dist/protos/generated/video_streaming/onesie_innertube_response.d.ts +15 -0
- package/dist/protos/generated/video_streaming/{onesie_player_response.js → onesie_innertube_response.js} +6 -58
- package/dist/protos/generated/video_streaming/onesie_innertube_response.js.map +1 -0
- package/dist/protos/generated/video_streaming/onesie_proxy_status.d.ts +18 -0
- package/dist/protos/generated/video_streaming/onesie_proxy_status.js +25 -0
- package/dist/protos/generated/video_streaming/onesie_proxy_status.js.map +1 -0
- package/dist/protos/generated/video_streaming/onesie_request.d.ts +7 -17
- package/dist/protos/generated/video_streaming/onesie_request.js +28 -89
- package/dist/protos/generated/video_streaming/onesie_request.js.map +1 -0
- package/dist/protos/generated/video_streaming/playback_cookie.d.ts +2 -17
- package/dist/protos/generated/video_streaming/playback_cookie.js +6 -47
- package/dist/protos/generated/video_streaming/playback_cookie.js.map +1 -0
- package/dist/protos/generated/video_streaming/playback_start_policy.d.ts +0 -15
- package/dist/protos/generated/video_streaming/playback_start_policy.js +2 -66
- package/dist/protos/generated/video_streaming/playback_start_policy.js.map +1 -0
- package/dist/protos/generated/video_streaming/reload_player_response.d.ts +14 -0
- package/dist/protos/generated/video_streaming/reload_player_response.js +73 -0
- package/dist/protos/generated/video_streaming/reload_player_response.js.map +1 -0
- package/dist/protos/generated/video_streaming/request_cancellation_policy.d.ts +0 -15
- package/dist/protos/generated/video_streaming/request_cancellation_policy.js +2 -66
- package/dist/protos/generated/video_streaming/request_cancellation_policy.js.map +1 -0
- package/dist/protos/generated/video_streaming/request_identifier.d.ts +10 -0
- package/dist/protos/generated/video_streaming/request_identifier.js +41 -0
- package/dist/protos/generated/video_streaming/request_identifier.js.map +1 -0
- package/dist/protos/generated/video_streaming/sabr_context_sending_policy.d.ts +12 -0
- package/dist/protos/generated/video_streaming/sabr_context_sending_policy.js +86 -0
- package/dist/protos/generated/video_streaming/sabr_context_sending_policy.js.map +1 -0
- package/dist/protos/generated/video_streaming/sabr_context_update.d.ts +48 -0
- package/dist/protos/generated/video_streaming/sabr_context_update.js +242 -0
- package/dist/protos/generated/video_streaming/sabr_context_update.js.map +1 -0
- package/dist/protos/generated/video_streaming/sabr_error.d.ts +0 -15
- package/dist/protos/generated/video_streaming/sabr_error.js +2 -29
- package/dist/protos/generated/video_streaming/sabr_error.js.map +1 -0
- package/dist/protos/generated/video_streaming/sabr_redirect.d.ts +0 -15
- package/dist/protos/generated/video_streaming/sabr_redirect.js +2 -22
- package/dist/protos/generated/video_streaming/sabr_redirect.js.map +1 -0
- package/dist/protos/generated/video_streaming/snackbar_message.d.ts +10 -0
- package/dist/protos/generated/video_streaming/snackbar_message.js +41 -0
- package/dist/protos/generated/video_streaming/snackbar_message.js.map +1 -0
- package/dist/protos/generated/video_streaming/stream_protection_status.d.ts +1 -16
- package/dist/protos/generated/video_streaming/stream_protection_status.js +6 -33
- package/dist/protos/generated/video_streaming/stream_protection_status.js.map +1 -0
- package/dist/protos/generated/video_streaming/streamer_context.d.ts +11 -28
- package/dist/protos/generated/video_streaming/streamer_context.js +33 -383
- package/dist/protos/generated/video_streaming/streamer_context.js.map +1 -0
- package/dist/protos/generated/video_streaming/time_range.d.ts +2 -17
- package/dist/protos/generated/video_streaming/time_range.js +9 -41
- package/dist/protos/generated/video_streaming/time_range.js.map +1 -0
- package/dist/protos/generated/video_streaming/ump_part_id.d.ts +58 -0
- package/dist/protos/generated/video_streaming/ump_part_id.js +89 -0
- package/dist/protos/generated/video_streaming/ump_part_id.js.map +1 -0
- package/dist/protos/generated/video_streaming/video_playback_abr_request.d.ts +21 -36
- package/dist/protos/generated/video_streaming/video_playback_abr_request.js +67 -343
- package/dist/protos/generated/video_streaming/video_playback_abr_request.js.map +1 -0
- package/dist/src/core/{ChunkedDataBuffer.d.ts → CompositeBuffer.d.ts} +8 -8
- package/dist/src/core/{ChunkedDataBuffer.js → CompositeBuffer.js} +32 -27
- package/dist/src/core/CompositeBuffer.js.map +1 -0
- package/dist/src/core/SabrStream.d.ts +356 -0
- package/dist/src/core/SabrStream.js +958 -0
- package/dist/src/core/SabrStream.js.map +1 -0
- package/dist/src/core/SabrStreamingAdapter.d.ts +158 -0
- package/dist/src/core/SabrStreamingAdapter.js +496 -0
- package/dist/src/core/SabrStreamingAdapter.js.map +1 -0
- package/dist/src/core/SabrUmpProcessor.d.ts +53 -0
- package/dist/src/core/SabrUmpProcessor.js +234 -0
- package/dist/src/core/SabrUmpProcessor.js.map +1 -0
- package/dist/src/core/UmpReader.d.ts +30 -0
- package/dist/src/core/UmpReader.js +122 -0
- package/dist/src/core/UmpReader.js.map +1 -0
- package/dist/src/core/UmpWriter.d.ts +16 -0
- package/dist/src/core/UmpWriter.js +56 -0
- package/dist/src/core/UmpWriter.js.map +1 -0
- package/dist/src/exports/protos.d.ts +1 -0
- package/dist/src/exports/protos.js +2 -0
- package/dist/src/exports/protos.js.map +1 -0
- package/dist/src/exports/sabr-stream.d.ts +2 -0
- package/dist/src/exports/sabr-stream.js +2 -0
- package/dist/src/exports/sabr-stream.js.map +1 -0
- package/dist/src/exports/sabr-streaming-adapter.d.ts +3 -0
- package/dist/src/exports/sabr-streaming-adapter.js +3 -0
- package/dist/src/exports/sabr-streaming-adapter.js.map +1 -0
- package/dist/src/exports/ump.d.ts +3 -0
- package/dist/src/exports/ump.js +4 -0
- package/dist/src/exports/ump.js.map +1 -0
- package/dist/src/exports/utils.d.ts +1 -0
- package/dist/src/exports/utils.js +2 -0
- package/dist/src/exports/utils.js.map +1 -0
- package/dist/src/types/sabrStreamTypes.d.ts +102 -0
- package/dist/src/types/sabrStreamTypes.js +2 -0
- package/dist/src/types/sabrStreamTypes.js.map +1 -0
- package/dist/src/types/sabrStreamingAdapterTypes.d.ts +93 -0
- package/dist/src/types/sabrStreamingAdapterTypes.js +2 -0
- package/dist/src/types/sabrStreamingAdapterTypes.js.map +1 -0
- package/dist/src/types/shared.d.ts +64 -0
- package/dist/src/types/shared.js +2 -0
- package/dist/src/types/shared.js.map +1 -0
- package/dist/src/utils/CacheManager.d.ts +32 -0
- package/dist/src/utils/CacheManager.js +131 -0
- package/dist/src/utils/CacheManager.js.map +1 -0
- package/dist/src/utils/EventEmitterLike.d.ts +5 -0
- package/dist/src/utils/EventEmitterLike.js +51 -10
- package/dist/src/utils/EventEmitterLike.js.map +1 -0
- package/dist/src/utils/Logger.d.ts +30 -0
- package/dist/src/utils/Logger.js +80 -0
- package/dist/src/utils/Logger.js.map +1 -0
- package/dist/src/utils/Protos.d.ts +21 -13
- package/dist/src/utils/Protos.js +22 -13
- package/dist/src/utils/Protos.js.map +1 -0
- package/dist/src/utils/RequestMetadataManager.d.ts +15 -0
- package/dist/src/utils/RequestMetadataManager.js +48 -0
- package/dist/src/utils/RequestMetadataManager.js.map +1 -0
- package/dist/src/utils/formatKeyUtils.d.ts +45 -0
- package/dist/src/utils/formatKeyUtils.js +77 -0
- package/dist/src/utils/formatKeyUtils.js.map +1 -0
- package/dist/src/utils/index.d.ts +5 -3
- package/dist/src/utils/index.js +6 -2
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/sabrStreamUtils.d.ts +28 -0
- package/dist/src/utils/sabrStreamUtils.js +76 -0
- package/dist/src/utils/sabrStreamUtils.js.map +1 -0
- package/dist/src/utils/shared.d.ts +43 -0
- package/dist/src/utils/shared.js +108 -0
- package/dist/src/utils/shared.js.map +1 -0
- package/package.json +88 -61
- package/dist/protos/generated/video_streaming/encrypted_player_request.d.ts +0 -37
- package/dist/protos/generated/video_streaming/encrypted_player_request.js +0 -239
- package/dist/protos/generated/video_streaming/onesie_player_request.d.ts +0 -31
- package/dist/protos/generated/video_streaming/onesie_player_response.d.ts +0 -29
- package/dist/protos/generated/video_streaming/proxy_status.d.ts +0 -16
- package/dist/protos/generated/video_streaming/proxy_status.js +0 -86
- package/dist/src/core/ServerAbrStream.d.ts +0 -38
- package/dist/src/core/ServerAbrStream.js +0 -272
- package/dist/src/core/UMP.d.ts +0 -10
- package/dist/src/core/UMP.js +0 -109
- package/dist/src/core/index.d.ts +0 -3
- package/dist/src/core/index.js +0 -3
- package/dist/src/index.d.ts +0 -4
- package/dist/src/index.js +0 -4
- package/dist/src/utils/helpers.d.ts +0 -63
- package/dist/src/utils/helpers.js +0 -101
- package/dist/src/utils/types.d.ts +0 -65
- package/dist/src/utils/types.js +0 -1
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
export class
|
|
1
|
+
export class CompositeBuffer {
|
|
2
2
|
constructor(chunks = []) {
|
|
3
3
|
this.chunks = [];
|
|
4
4
|
this.currentChunkOffset = this.currentChunkIndex = 0;
|
|
5
5
|
this.currentDataView = undefined;
|
|
6
6
|
this.totalLength = 0;
|
|
7
|
-
chunks.forEach((chunk) =>
|
|
8
|
-
this.append(chunk);
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
getLength() {
|
|
12
|
-
return this.totalLength;
|
|
7
|
+
chunks.forEach((chunk) => this.append(chunk));
|
|
13
8
|
}
|
|
14
9
|
append(chunk) {
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
10
|
+
if (chunk instanceof Uint8Array) {
|
|
11
|
+
if (this.canMergeWithLastChunk(chunk)) {
|
|
12
|
+
const lastChunk = this.chunks[this.chunks.length - 1];
|
|
13
|
+
this.chunks[this.chunks.length - 1] = new Uint8Array(lastChunk.buffer, lastChunk.byteOffset, lastChunk.length + chunk.length);
|
|
14
|
+
this.resetFocus();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
this.chunks.push(chunk);
|
|
18
|
+
}
|
|
19
|
+
this.totalLength += chunk.length;
|
|
19
20
|
}
|
|
20
21
|
else {
|
|
21
|
-
|
|
22
|
+
chunk.chunks.forEach((c) => this.append(c));
|
|
22
23
|
}
|
|
23
|
-
this.totalLength += chunk.length;
|
|
24
24
|
}
|
|
25
25
|
split(position) {
|
|
26
|
-
const extractedBuffer = new
|
|
27
|
-
const remainingBuffer = new
|
|
26
|
+
const extractedBuffer = new CompositeBuffer();
|
|
27
|
+
const remainingBuffer = new CompositeBuffer();
|
|
28
28
|
const iterator = this.chunks[Symbol.iterator]();
|
|
29
29
|
let item = iterator.next();
|
|
30
30
|
while (!item.done) {
|
|
@@ -45,8 +45,15 @@ export class ChunkedDataBuffer {
|
|
|
45
45
|
}
|
|
46
46
|
return { extractedBuffer, remainingBuffer };
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
return
|
|
48
|
+
getLength() {
|
|
49
|
+
return this.totalLength;
|
|
50
|
+
}
|
|
51
|
+
canReadBytes(position, length) {
|
|
52
|
+
return position + length <= this.totalLength;
|
|
53
|
+
}
|
|
54
|
+
getUint8(position) {
|
|
55
|
+
this.focus(position);
|
|
56
|
+
return this.chunks[this.currentChunkIndex][position - this.currentChunkOffset];
|
|
50
57
|
}
|
|
51
58
|
focus(position) {
|
|
52
59
|
if (!this.isFocused(position)) {
|
|
@@ -60,12 +67,14 @@ export class ChunkedDataBuffer {
|
|
|
60
67
|
this.currentDataView = undefined;
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
|
-
|
|
64
|
-
return position
|
|
70
|
+
isFocused(position) {
|
|
71
|
+
return (position >= this.currentChunkOffset &&
|
|
72
|
+
position < this.currentChunkOffset + this.chunks[this.currentChunkIndex].length);
|
|
65
73
|
}
|
|
66
|
-
|
|
67
|
-
this.
|
|
68
|
-
|
|
74
|
+
resetFocus() {
|
|
75
|
+
this.currentDataView = undefined;
|
|
76
|
+
this.currentChunkIndex = 0;
|
|
77
|
+
this.currentChunkOffset = 0;
|
|
69
78
|
}
|
|
70
79
|
canMergeWithLastChunk(chunk) {
|
|
71
80
|
if (this.chunks.length === 0)
|
|
@@ -74,9 +83,5 @@ export class ChunkedDataBuffer {
|
|
|
74
83
|
return (lastChunk.buffer === chunk.buffer &&
|
|
75
84
|
lastChunk.byteOffset + lastChunk.length === chunk.byteOffset);
|
|
76
85
|
}
|
|
77
|
-
resetFocus() {
|
|
78
|
-
this.currentDataView = undefined;
|
|
79
|
-
this.currentChunkIndex = 0;
|
|
80
|
-
this.currentChunkOffset = 0;
|
|
81
|
-
}
|
|
82
86
|
}
|
|
87
|
+
//# sourceMappingURL=CompositeBuffer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompositeBuffer.js","sourceRoot":"","sources":["../../../src/core/CompositeBuffer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
import { FormatInitializationMetadata, MediaHeader, NextRequestPolicy, ReloadPlaybackContext, SabrContextUpdate, StreamProtectionStatus } from '../utils/Protos.js';
|
|
2
|
+
import type { BufferedRange, ClientInfo } from '../utils/Protos.js';
|
|
3
|
+
import type { SabrPlaybackOptions, SabrStreamConfig } from '../types/sabrStreamTypes.js';
|
|
4
|
+
import type { SabrFormat } from '../types/shared.js';
|
|
5
|
+
import { EventEmitterLike } from '../utils/index.js';
|
|
6
|
+
export interface InitializedFormat {
|
|
7
|
+
formatInitializationMetadata: FormatInitializationMetadata;
|
|
8
|
+
downloadedSegments: Map<number, Segment>;
|
|
9
|
+
lastMediaHeaders: MediaHeader[];
|
|
10
|
+
}
|
|
11
|
+
export interface SabrStreamState {
|
|
12
|
+
durationMs: number;
|
|
13
|
+
requestNumber: number;
|
|
14
|
+
playerTimeMs: number;
|
|
15
|
+
activeSabrContexts: number[];
|
|
16
|
+
sabrContextUpdates: Array<[number, SabrContextUpdate]>;
|
|
17
|
+
formatToDiscard?: string;
|
|
18
|
+
cachedBufferedRanges: BufferedRange[];
|
|
19
|
+
nextRequestPolicy?: NextRequestPolicy;
|
|
20
|
+
initializedFormats: Array<{
|
|
21
|
+
formatKey: string;
|
|
22
|
+
formatInitializationMetadata: FormatInitializationMetadata;
|
|
23
|
+
downloadedSegments: Array<[number, Segment]>;
|
|
24
|
+
lastMediaHeaders: MediaHeader[];
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
interface SelectedFormats {
|
|
28
|
+
videoFormat: SabrFormat;
|
|
29
|
+
audioFormat: SabrFormat;
|
|
30
|
+
}
|
|
31
|
+
interface Segment {
|
|
32
|
+
formatIdKey: string;
|
|
33
|
+
segmentNumber: number;
|
|
34
|
+
durationMs?: number;
|
|
35
|
+
mediaHeader: MediaHeader;
|
|
36
|
+
bufferedChunks: Uint8Array[];
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Manages the download and processing of YouTube's Server-Adaptive Bitrate (SABR) streams.
|
|
40
|
+
*
|
|
41
|
+
* This class handles the entire lifecycle of a SABR stream:
|
|
42
|
+
* - Selecting appropriate video and audio formats.
|
|
43
|
+
* - Making network requests to fetch media segments.
|
|
44
|
+
* - Processing UMP parts in real-time.
|
|
45
|
+
* - Handling server-side directives like redirects, context updates, and backoff policies.
|
|
46
|
+
* - Emitting events for key stream updates, such as format initialization and errors.
|
|
47
|
+
* - Providing separate `ReadableStream` instances for video and audio data.
|
|
48
|
+
*/
|
|
49
|
+
export declare class SabrStream extends EventEmitterLike {
|
|
50
|
+
private readonly logger;
|
|
51
|
+
private readonly fetchFunction;
|
|
52
|
+
private readonly formatIds;
|
|
53
|
+
private readonly videoStream;
|
|
54
|
+
private readonly audioStream;
|
|
55
|
+
private readonly umpPartHandlers;
|
|
56
|
+
private serverAbrStreamingUrl?;
|
|
57
|
+
private videoPlaybackUstreamerConfig?;
|
|
58
|
+
private clientInfo?;
|
|
59
|
+
private poToken?;
|
|
60
|
+
private nextRequestPolicy?;
|
|
61
|
+
private streamProtectionStatus?;
|
|
62
|
+
private sabrContexts;
|
|
63
|
+
private activeSabrContextTypes;
|
|
64
|
+
private initializedFormatsMap;
|
|
65
|
+
private abortController?;
|
|
66
|
+
private partialSegmentQueue;
|
|
67
|
+
private requestNumber;
|
|
68
|
+
private durationMs;
|
|
69
|
+
private cachedBufferedRanges;
|
|
70
|
+
private formatToDiscard?;
|
|
71
|
+
private mediaHeadersProcessed;
|
|
72
|
+
private mainFormat?;
|
|
73
|
+
private _errored;
|
|
74
|
+
private _aborted;
|
|
75
|
+
private progressTracker;
|
|
76
|
+
private videoController?;
|
|
77
|
+
private audioController?;
|
|
78
|
+
/**
|
|
79
|
+
* Fired when the server sends initialization metadata for a media format.
|
|
80
|
+
* @event
|
|
81
|
+
*/
|
|
82
|
+
on(event: 'formatInitialization', listener: (initializedFormat: InitializedFormat) => void): void;
|
|
83
|
+
/**
|
|
84
|
+
* Fired when the server provides an update on the stream's content protection status.
|
|
85
|
+
* @event
|
|
86
|
+
*/
|
|
87
|
+
on(event: 'streamProtectionStatusUpdate', listener: (data: StreamProtectionStatus) => void): void;
|
|
88
|
+
/**
|
|
89
|
+
* Fired when the server directs the client to reload the player, usually indicating the current session is invalid.
|
|
90
|
+
* @event
|
|
91
|
+
*/
|
|
92
|
+
on(event: 'reloadPlayerResponse', listener: (reloadPlaybackContext: ReloadPlaybackContext) => void): void;
|
|
93
|
+
/**
|
|
94
|
+
* Fired when the entire stream has been successfully downloaded.
|
|
95
|
+
* @event
|
|
96
|
+
*/
|
|
97
|
+
on(event: 'finish', listener: () => void): void;
|
|
98
|
+
/**
|
|
99
|
+
* Fired when the download process is manually aborted via the `abort()` method.
|
|
100
|
+
* @event
|
|
101
|
+
*/
|
|
102
|
+
on(event: 'abort', listener: () => void): void;
|
|
103
|
+
once(event: 'formatInitialization', listener: (initializedFormat: InitializedFormat) => void): void;
|
|
104
|
+
once(event: 'streamProtectionStatusUpdate', listener: (data: StreamProtectionStatus) => void): void;
|
|
105
|
+
once(event: 'reloadPlayerResponse', listener: (reloadPlaybackContext: ReloadPlaybackContext) => void): void;
|
|
106
|
+
once(event: 'finish', listener: () => void): void;
|
|
107
|
+
once(event: 'abort', listener: () => void): void;
|
|
108
|
+
constructor(config?: SabrStreamConfig);
|
|
109
|
+
/**
|
|
110
|
+
* Sets Proof of Origin (PO) token.
|
|
111
|
+
* @param poToken - The base64-encoded token string.
|
|
112
|
+
*/
|
|
113
|
+
setPoToken(poToken: string): void;
|
|
114
|
+
/**
|
|
115
|
+
* Sets the available server ABR formats.
|
|
116
|
+
* @param formats - An array of available SabrFormat objects.
|
|
117
|
+
*/
|
|
118
|
+
setServerAbrFormats(formats: SabrFormat[]): void;
|
|
119
|
+
/**
|
|
120
|
+
* Sets the total duration of the stream in milliseconds.
|
|
121
|
+
* This is optional as duration is often determined automatically from format metadata.
|
|
122
|
+
* @param durationMs - The duration in milliseconds.
|
|
123
|
+
*/
|
|
124
|
+
setDurationMs(durationMs: number): void;
|
|
125
|
+
/**
|
|
126
|
+
* Sets the server ABR streaming URL for media requests.
|
|
127
|
+
* @param url - The streaming URL.
|
|
128
|
+
*/
|
|
129
|
+
setStreamingURL(url: string): void;
|
|
130
|
+
/**
|
|
131
|
+
* Sets the Ustreamer configuration string.
|
|
132
|
+
* @param config - The Ustreamer configuration.
|
|
133
|
+
*/
|
|
134
|
+
setUstreamerConfig(config: string): void;
|
|
135
|
+
/**
|
|
136
|
+
* Sets the client information used in SABR requests.
|
|
137
|
+
* @param clientInfo - The client information object.
|
|
138
|
+
*/
|
|
139
|
+
setClientInfo(clientInfo: ClientInfo): void;
|
|
140
|
+
/**
|
|
141
|
+
* Aborts the download process, closing all streams and cleaning up resources.
|
|
142
|
+
* Emits an 'abort' event.
|
|
143
|
+
*/
|
|
144
|
+
abort(): void;
|
|
145
|
+
/**
|
|
146
|
+
* Returns a serializable state object that can be used to restore the stream later.
|
|
147
|
+
* @throws {Error} If the main format is not initialized.
|
|
148
|
+
* @returns The current state of the stream.
|
|
149
|
+
*/
|
|
150
|
+
getState(): SabrStreamState;
|
|
151
|
+
/**
|
|
152
|
+
* Initiates the streaming process for the selected formats.
|
|
153
|
+
* @param options - Playback options, including format preferences and initial state.
|
|
154
|
+
* @throws {Error} If no suitable formats are found or streaming fails.
|
|
155
|
+
* @returns A promise that resolves with the video/audio streams and selected formats.
|
|
156
|
+
*/
|
|
157
|
+
start(options: SabrPlaybackOptions): Promise<{
|
|
158
|
+
videoStream: ReadableStream<Uint8Array>;
|
|
159
|
+
audioStream: ReadableStream<Uint8Array>;
|
|
160
|
+
selectedFormats: SelectedFormats;
|
|
161
|
+
}>;
|
|
162
|
+
/**
|
|
163
|
+
* Sets up and manages the main streaming loop.
|
|
164
|
+
* @param videoFormat - The selected video format.
|
|
165
|
+
* @param audioFormat - The selected audio format.
|
|
166
|
+
* @param options - Playback options.
|
|
167
|
+
* @private
|
|
168
|
+
*/
|
|
169
|
+
private setupStreamingProcess;
|
|
170
|
+
/**
|
|
171
|
+
* Restores the stream state from a previously saved state object.
|
|
172
|
+
* @param videoFormat - The selected video format.
|
|
173
|
+
* @param audioFormat - The selected audio format.
|
|
174
|
+
* @param state - The saved state object.
|
|
175
|
+
* @returns `true` if the state was restored successfully, `false` otherwise.
|
|
176
|
+
* @private
|
|
177
|
+
*/
|
|
178
|
+
private restoreState;
|
|
179
|
+
/**
|
|
180
|
+
* Checks if the download has stalled by tracking progress over time.
|
|
181
|
+
* @param options - Configuration for stall detection.
|
|
182
|
+
* @returns `true` if a stall was detected but is within the retry limit, `false` otherwise.
|
|
183
|
+
* @throws {Error} If the maximum number of consecutive stalls is reached.
|
|
184
|
+
* @private
|
|
185
|
+
*/
|
|
186
|
+
private checkForStall;
|
|
187
|
+
/**
|
|
188
|
+
* Selects the best video and audio formats based on provided options.
|
|
189
|
+
* @param options - Format selection options and quality preferences.
|
|
190
|
+
* @throws {Error} If no suitable formats are found or the duration is invalid.
|
|
191
|
+
* @returns The selected video and audio formats.
|
|
192
|
+
* @private
|
|
193
|
+
*/
|
|
194
|
+
private selectFormats;
|
|
195
|
+
/**
|
|
196
|
+
* Fetches and processes media segments from the server for the current ABR state.
|
|
197
|
+
* @param abrState - The current client adaptive bitrate state.
|
|
198
|
+
* @param selectedAudioFormat - The selected audio format.
|
|
199
|
+
* @param selectedVideoFormat - The selected video format.
|
|
200
|
+
* @throws {Error} If the server returns an error or no valid data.
|
|
201
|
+
* @private
|
|
202
|
+
*/
|
|
203
|
+
private fetchAndProcessSegments;
|
|
204
|
+
/**
|
|
205
|
+
* Constructs an array of `BufferedRange` objects from initialized formats.
|
|
206
|
+
* @param initializedVideoFormat - The initialized video format, if available.
|
|
207
|
+
* @param initializedAudioFormat - The initialized audio format, if available.
|
|
208
|
+
* @returns An array of `BufferedRange` objects.
|
|
209
|
+
* @private
|
|
210
|
+
*/
|
|
211
|
+
private buildBufferedRanges;
|
|
212
|
+
/**
|
|
213
|
+
* Builds the protobuf request body for a `VideoPlaybackAbrRequest`.
|
|
214
|
+
* @param abrState - The current client adaptive bitrate state.
|
|
215
|
+
* @param selectedAudioFormat - The selected audio format.
|
|
216
|
+
* @param selectedVideoFormat - The selected video format.
|
|
217
|
+
* @returns The encoded request body as a `Uint8Array`.
|
|
218
|
+
* @throws {Error} If required configuration (ustreamer config, client info) is missing.
|
|
219
|
+
* @private
|
|
220
|
+
*/
|
|
221
|
+
private buildRequestBody;
|
|
222
|
+
/**
|
|
223
|
+
* Prepares SABR context data for the request body.
|
|
224
|
+
* @returns An object containing active and unsent SABR contexts.
|
|
225
|
+
* @private
|
|
226
|
+
*/
|
|
227
|
+
private prepareSabrContexts;
|
|
228
|
+
/**
|
|
229
|
+
* Prepares format selections and buffered ranges for the request body.
|
|
230
|
+
* @param formats - An array of formats to process.
|
|
231
|
+
* @param currentBufferedRanges - The current buffered ranges to update.
|
|
232
|
+
* @returns An object with selected format IDs and updated buffered ranges.
|
|
233
|
+
* @private
|
|
234
|
+
*/
|
|
235
|
+
private prepareFormatSelections;
|
|
236
|
+
/**
|
|
237
|
+
* Executes a streaming POST request to the server.
|
|
238
|
+
* @param body - The request body payload.
|
|
239
|
+
* @returns A `Promise` that resolves with the server `Response`.
|
|
240
|
+
* @throws {Error} If the server ABR streaming URL is not configured or the request fails.
|
|
241
|
+
* @private
|
|
242
|
+
*/
|
|
243
|
+
private makeStreamingRequest;
|
|
244
|
+
/**
|
|
245
|
+
* Reads the response body as a stream and processes each UMP part.
|
|
246
|
+
* @param response - The server response to process.
|
|
247
|
+
* @returns A promise that resolves to an array of processed UMP part types.
|
|
248
|
+
* @throws {Error} If the response is invalid, empty, or aborted.
|
|
249
|
+
* @private
|
|
250
|
+
*/
|
|
251
|
+
private processStreamingResponse;
|
|
252
|
+
/**
|
|
253
|
+
* Executes a function with automatic retries and exponential backoff.
|
|
254
|
+
* Respects server-specified backoff times from `nextRequestPolicy`.
|
|
255
|
+
* @param fetchFn - The function to execute.
|
|
256
|
+
* @param maxRetries - The maximum number of retry attempts.
|
|
257
|
+
* @returns A promise that resolves to `true` on success, or `false` if all retries fail.
|
|
258
|
+
* @private
|
|
259
|
+
*/
|
|
260
|
+
private executeWithRetry;
|
|
261
|
+
/**
|
|
262
|
+
* Handles `FORMAT_INITIALIZATION_METADATA` parts.
|
|
263
|
+
* Creates and stores a new `InitializedFormat` entry.
|
|
264
|
+
* @private
|
|
265
|
+
*/
|
|
266
|
+
private handleFormatInitializationMetadata;
|
|
267
|
+
/**
|
|
268
|
+
* Handles `NEXT_REQUEST_POLICY` parts.
|
|
269
|
+
* Stores the server's policy for backoff time and playback cookies.
|
|
270
|
+
* @private
|
|
271
|
+
*/
|
|
272
|
+
private handleNextRequestPolicy;
|
|
273
|
+
/**
|
|
274
|
+
* Handles `SABR_ERROR` parts.
|
|
275
|
+
* Throws an error to terminate the current request attempt.
|
|
276
|
+
* @throws {Error} Always throws with the SABR error details.
|
|
277
|
+
* @private
|
|
278
|
+
*/
|
|
279
|
+
private handleSabrError;
|
|
280
|
+
/**
|
|
281
|
+
* Handles `SABR_REDIRECT` parts.
|
|
282
|
+
* Updates the streaming URL to the new location provided by the server.
|
|
283
|
+
* @private
|
|
284
|
+
*/
|
|
285
|
+
private handleSabrRedirect;
|
|
286
|
+
/**
|
|
287
|
+
* Handles `SABR_CONTEXT_UPDATE` parts.
|
|
288
|
+
* Updates the client's context state based on server instructions.
|
|
289
|
+
* @private
|
|
290
|
+
*/
|
|
291
|
+
private handleSabrContextUpdate;
|
|
292
|
+
/**
|
|
293
|
+
* Handles `SABR_CONTEXT_SENDING_POLICY` parts.
|
|
294
|
+
* Updates which contexts should be sent in future requests.
|
|
295
|
+
* @private
|
|
296
|
+
*/
|
|
297
|
+
private handleSabrContextSendingPolicy;
|
|
298
|
+
/**
|
|
299
|
+
* Handles `STREAM_PROTECTION_STATUS` parts.
|
|
300
|
+
* Emits updates and handles critical statuses like required attestation.
|
|
301
|
+
* @throws {Error} If attestation is required (status 3).
|
|
302
|
+
* @private
|
|
303
|
+
*/
|
|
304
|
+
private handleStreamProtectionStatus;
|
|
305
|
+
/**
|
|
306
|
+
* Handles `RELOAD_PLAYER_RESPONSE` parts.
|
|
307
|
+
* Emits an event with reload parameters and terminates the session.
|
|
308
|
+
* @throws {Error} Always throws to terminate the current streaming session.
|
|
309
|
+
* @private
|
|
310
|
+
*/
|
|
311
|
+
private handleReloadPlayerResponse;
|
|
312
|
+
/**
|
|
313
|
+
* Handles `MEDIA_HEADER` parts.
|
|
314
|
+
* Creates an entry in the `partialSegmentQueue` for the upcoming media chunks.
|
|
315
|
+
* @private
|
|
316
|
+
*/
|
|
317
|
+
private handleMediaHeader;
|
|
318
|
+
/**
|
|
319
|
+
* Handles `MEDIA` parts.
|
|
320
|
+
* Buffers media data chunks associated with a specific header ID.
|
|
321
|
+
* @private
|
|
322
|
+
*/
|
|
323
|
+
private handleMedia;
|
|
324
|
+
/**
|
|
325
|
+
* Handles `MEDIA_END` parts.
|
|
326
|
+
* Finalizes a segment, enqueues its data to the appropriate stream, and updates tracking.
|
|
327
|
+
* @private
|
|
328
|
+
*/
|
|
329
|
+
private handleMediaEnd;
|
|
330
|
+
/**
|
|
331
|
+
* Validates and corrects the stream duration based on format initialization metadata.
|
|
332
|
+
* @param formatInitializationMetadata - The metadata from an initialized format.
|
|
333
|
+
* @private
|
|
334
|
+
*/
|
|
335
|
+
private validateAndCorrectDuration;
|
|
336
|
+
/**
|
|
337
|
+
* Validates downloaded segments for completeness and consistency after the stream finishes.
|
|
338
|
+
* Checks for duration coverage, missing segments, and duplicates.
|
|
339
|
+
* @private
|
|
340
|
+
*/
|
|
341
|
+
private validateDownloadedSegments;
|
|
342
|
+
/**
|
|
343
|
+
* Resets the internal state of the stream.
|
|
344
|
+
* Clears all maps, resets counters, and re-initializes the progress tracker.
|
|
345
|
+
* @private
|
|
346
|
+
*/
|
|
347
|
+
private resetState;
|
|
348
|
+
/**
|
|
349
|
+
* Handles errors during the streaming process.
|
|
350
|
+
* @param error - The error that occurred.
|
|
351
|
+
* @param notifyControllers - Whether to propagate the error to the stream controllers.
|
|
352
|
+
* @private
|
|
353
|
+
*/
|
|
354
|
+
private errorHandler;
|
|
355
|
+
}
|
|
356
|
+
export {};
|