googlevideo 3.0.0 → 4.0.1
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 +93 -45
- package/dist/protos/generated/misc/common.d.ts +180 -6
- package/dist/protos/generated/misc/common.js +282 -19
- package/dist/protos/generated/misc/common.js.map +1 -0
- package/dist/protos/generated/video_streaming/buffered_range.d.ts +10 -10
- package/dist/protos/generated/video_streaming/buffered_range.js +20 -19
- package/dist/protos/generated/video_streaming/buffered_range.js.map +1 -0
- package/dist/protos/generated/video_streaming/client_abr_state.d.ts +22 -11
- package/dist/protos/generated/video_streaming/client_abr_state.js +133 -50
- package/dist/protos/generated/video_streaming/client_abr_state.js.map +1 -0
- package/dist/protos/generated/video_streaming/crypto_params.d.ts +2 -7
- package/dist/protos/generated/video_streaming/crypto_params.js +1 -7
- package/dist/protos/generated/video_streaming/crypto_params.js.map +1 -0
- package/dist/protos/generated/video_streaming/format_initialization_metadata.d.ts +6 -6
- package/dist/protos/generated/video_streaming/format_initialization_metadata.js +32 -21
- 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/{encrypted_player_request.d.ts → innertube_request.d.ts} +11 -6
- package/dist/protos/generated/video_streaming/{encrypted_player_request.js → innertube_request.js} +64 -20
- package/dist/protos/generated/video_streaming/innertube_request.js.map +1 -0
- package/dist/protos/generated/video_streaming/live_metadata.d.ts +8 -5
- package/dist/protos/generated/video_streaming/live_metadata.js +57 -26
- package/dist/protos/generated/video_streaming/live_metadata.js.map +1 -0
- package/dist/protos/generated/video_streaming/media_capabilities.js +1 -0
- package/dist/protos/generated/video_streaming/media_capabilities.js.map +1 -0
- package/dist/protos/generated/video_streaming/media_header.d.ts +5 -10
- package/dist/protos/generated/video_streaming/media_header.js +27 -23
- package/dist/protos/generated/video_streaming/media_header.js.map +1 -0
- package/dist/protos/generated/video_streaming/next_request_policy.d.ts +3 -0
- package/dist/protos/generated/video_streaming/next_request_policy.js +31 -0
- package/dist/protos/generated/video_streaming/next_request_policy.js.map +1 -0
- package/dist/protos/generated/video_streaming/onesie_header.d.ts +7 -7
- package/dist/protos/generated/video_streaming/onesie_header.js +15 -14
- package/dist/protos/generated/video_streaming/onesie_header.js.map +1 -0
- package/dist/protos/generated/video_streaming/onesie_header_type.d.ts +9 -23
- package/dist/protos/generated/video_streaming/onesie_header_type.js +16 -30
- package/dist/protos/generated/video_streaming/onesie_header_type.js.map +1 -0
- package/dist/protos/generated/video_streaming/{onesie_player_request.d.ts → onesie_innertube_request.d.ts} +2 -2
- package/dist/protos/generated/video_streaming/{onesie_player_request.js → onesie_innertube_request.js} +5 -4
- 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} +5 -22
- 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 +6 -3
- package/dist/protos/generated/video_streaming/onesie_request.js +17 -5
- package/dist/protos/generated/video_streaming/onesie_request.js.map +1 -0
- package/dist/protos/generated/video_streaming/playback_cookie.d.ts +2 -2
- package/dist/protos/generated/video_streaming/playback_cookie.js +5 -4
- package/dist/protos/generated/video_streaming/playback_cookie.js.map +1 -0
- package/dist/protos/generated/video_streaming/playback_start_policy.js +1 -0
- 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.js +1 -0
- 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.js +1 -0
- package/dist/protos/generated/video_streaming/sabr_error.js.map +1 -0
- package/dist/protos/generated/video_streaming/sabr_redirect.js +1 -0
- 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 -1
- package/dist/protos/generated/video_streaming/stream_protection_status.js +5 -4
- package/dist/protos/generated/video_streaming/stream_protection_status.js.map +1 -0
- package/dist/protos/generated/video_streaming/streamer_context.d.ts +11 -11
- package/dist/protos/generated/video_streaming/streamer_context.js +32 -32
- package/dist/protos/generated/video_streaming/streamer_context.js.map +1 -0
- package/dist/protos/generated/video_streaming/time_range.d.ts +2 -2
- package/dist/protos/generated/video_streaming/time_range.js +8 -7
- 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 +20 -21
- package/dist/protos/generated/video_streaming/video_playback_abr_request.js +48 -86
- package/dist/protos/generated/video_streaming/video_playback_abr_request.js.map +1 -0
- package/dist/src/core/{ChunkedDataBuffer.d.ts → CompositeBuffer.d.ts} +11 -8
- package/dist/src/core/{ChunkedDataBuffer.js → CompositeBuffer.js} +35 -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/{UMP.d.ts → UmpReader.d.ts} +9 -10
- package/dist/src/core/{UMP.js → UmpReader.js} +36 -36
- package/dist/src/core/UmpReader.js.map +1 -0
- package/dist/src/core/UmpWriter.d.ts +19 -0
- package/dist/src/core/UmpWriter.js +59 -0
- package/dist/src/core/UmpWriter.js.map +1 -0
- package/dist/src/exports/protos.d.ts +5 -0
- package/dist/src/exports/protos.js +6 -0
- package/dist/src/exports/protos.js.map +1 -0
- package/dist/src/exports/sabr-stream.d.ts +6 -0
- package/dist/src/exports/sabr-stream.js +6 -0
- package/dist/src/exports/sabr-stream.js.map +1 -0
- package/dist/src/exports/sabr-streaming-adapter.d.ts +8 -0
- package/dist/src/exports/sabr-streaming-adapter.js +8 -0
- package/dist/src/exports/sabr-streaming-adapter.js.map +1 -0
- package/dist/src/exports/ump.d.ts +7 -0
- package/dist/src/exports/ump.js +8 -0
- package/dist/src/exports/ump.js.map +1 -0
- package/dist/src/exports/utils.d.ts +5 -0
- package/dist/src/exports/utils.js +6 -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 +43 -0
- package/dist/src/utils/Logger.js +93 -0
- package/dist/src/utils/Logger.js.map +1 -0
- package/dist/src/utils/Protos.d.ts +20 -13
- package/dist/src/utils/Protos.js +21 -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 +55 -0
- package/dist/src/utils/shared.js +120 -0
- package/dist/src/utils/shared.js.map +1 -0
- package/package.json +40 -12
- package/dist/protos/generated/video_streaming/onesie_player_response.d.ts +0 -31
- package/dist/protos/generated/video_streaming/proxy_status.d.ts +0 -14
- package/dist/protos/generated/video_streaming/proxy_status.js +0 -21
- package/dist/src/core/ServerAbrStream.d.ts +0 -39
- package/dist/src/core/ServerAbrStream.js +0 -259
- 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
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
import { MAX_INT32_VALUE, base64ToU8, EnabledTrackTypes, parseRangeHeader } from '../utils/shared.js';
|
|
2
|
+
import { fromFormat, fromMediaHeader } from '../utils/formatKeyUtils.js';
|
|
3
|
+
import { Logger } from '../utils/Logger.js';
|
|
4
|
+
import { CacheManager, RequestMetadataManager, SabrAdapterError } from '../utils/index.js';
|
|
5
|
+
import { PlaybackCookie, SabrContextWritePolicy, VideoPlaybackAbrRequest } from '../utils/Protos.js';
|
|
6
|
+
const TAG = 'SabrStreamingAdapter';
|
|
7
|
+
export const SABR_CONSTANTS = {
|
|
8
|
+
PROTOCOL: 'sabr:',
|
|
9
|
+
KEY_PARAM: 'key',
|
|
10
|
+
DEFAULT_OPTIONS: {
|
|
11
|
+
enableCaching: true,
|
|
12
|
+
enableVerboseRequestLogging: false,
|
|
13
|
+
maxCacheSizeMB: 3,
|
|
14
|
+
maxCacheAgeSeconds: 300
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Standard UMP request body bytes.
|
|
19
|
+
* These bytes represent a minimal valid protobuf message for UMP.
|
|
20
|
+
*/
|
|
21
|
+
const UMP_REQUEST_BODY = new Uint8Array([120, 0]);
|
|
22
|
+
/**
|
|
23
|
+
* Adapter class that handles YouTube SABR integration with media players (e.g., Shaka Player).
|
|
24
|
+
*
|
|
25
|
+
* What it does:
|
|
26
|
+
* - Sets up request/response interceptors so we can send proper SABR requests (UMP response parsing must be done in the player adapter).
|
|
27
|
+
* - Keeps track of initialized formats and their metadata.
|
|
28
|
+
* - Handles SABR-specific things, such as redirects, context updates, and playback cookies.
|
|
29
|
+
*/
|
|
30
|
+
export class SabrStreamingAdapter {
|
|
31
|
+
/**
|
|
32
|
+
* Registers a callback function to handle snackbar messages.
|
|
33
|
+
*/
|
|
34
|
+
onSnackbarMessage(cb) {
|
|
35
|
+
this.onSnackbarMessageCallback = cb;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Handles server requests to reload the player with new parameters.
|
|
39
|
+
* @param cb
|
|
40
|
+
*/
|
|
41
|
+
onReloadPlayerResponse(cb) {
|
|
42
|
+
this.onReloadPlayerResponseCallback = cb;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Registers a callback function to mint a new PoToken.
|
|
46
|
+
* @param cb
|
|
47
|
+
*/
|
|
48
|
+
onMintPoToken(cb) {
|
|
49
|
+
this.onMintPoTokenCallback = cb;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* @param options - Configuration options for the adapter.
|
|
53
|
+
* @throws SabrAdapterError if a player adapter is not provided.
|
|
54
|
+
*/
|
|
55
|
+
constructor(options) {
|
|
56
|
+
this.initializedFormats = new Map();
|
|
57
|
+
this.logger = Logger.getInstance();
|
|
58
|
+
this.sabrFormats = [];
|
|
59
|
+
this.sabrContexts = new Map();
|
|
60
|
+
this.activeSabrContextTypes = new Set();
|
|
61
|
+
this.cacheManager = null;
|
|
62
|
+
this.requestNumber = 0;
|
|
63
|
+
this.activeDelayPromise = null;
|
|
64
|
+
this.isDisposed = false;
|
|
65
|
+
this.options = {
|
|
66
|
+
...SABR_CONSTANTS.DEFAULT_OPTIONS,
|
|
67
|
+
...options
|
|
68
|
+
};
|
|
69
|
+
if (options.playerAdapter) {
|
|
70
|
+
this.playerAdapter = options.playerAdapter;
|
|
71
|
+
}
|
|
72
|
+
else
|
|
73
|
+
throw new SabrAdapterError('A player adapter is required.');
|
|
74
|
+
if (this.options.enableCaching) {
|
|
75
|
+
this.cacheManager = new CacheManager(this.options.maxCacheSizeMB, this.options.maxCacheAgeSeconds);
|
|
76
|
+
}
|
|
77
|
+
this.requestMetadataManager = new RequestMetadataManager();
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Initializes the player adapter and sets up request/response interceptors.
|
|
81
|
+
* @throws SabrAdapterError if the adapter has been disposed.
|
|
82
|
+
*/
|
|
83
|
+
attach(player) {
|
|
84
|
+
this.checkDisposed();
|
|
85
|
+
this.playerAdapter.initialize(player, this.requestMetadataManager, this.cacheManager);
|
|
86
|
+
this.setupInterceptors();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Sets the initial server abr streaming URL.
|
|
90
|
+
* @throws SabrAdapterError if the adapter has been disposed.
|
|
91
|
+
*/
|
|
92
|
+
setStreamingURL(url) {
|
|
93
|
+
this.checkDisposed();
|
|
94
|
+
this.serverAbrStreamingUrl = url;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Sets the ustreamer configuration for SABR requests.
|
|
98
|
+
* @throws SabrAdapterError if the adapter has been disposed.
|
|
99
|
+
*/
|
|
100
|
+
setUstreamerConfig(ustreamerConfig) {
|
|
101
|
+
this.checkDisposed();
|
|
102
|
+
this.ustreamerConfig = ustreamerConfig;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Sets the available SABR formats for streaming.
|
|
106
|
+
* @throws SabrAdapterError if the adapter has been disposed.
|
|
107
|
+
*/
|
|
108
|
+
setServerAbrFormats(sabrFormats) {
|
|
109
|
+
this.checkDisposed();
|
|
110
|
+
this.sabrFormats = sabrFormats;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Returns the cache manager instance, if caching is enabled.
|
|
114
|
+
*/
|
|
115
|
+
getCacheManager() {
|
|
116
|
+
return this.cacheManager;
|
|
117
|
+
}
|
|
118
|
+
setupInterceptors() {
|
|
119
|
+
this.playerAdapter.registerRequestInterceptor(this.handleRequest.bind(this));
|
|
120
|
+
this.playerAdapter.registerResponseInterceptor(this.handleResponse.bind(this));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Processes incoming requests and modifies them to conform to SABR protocol requirements.
|
|
124
|
+
* For SABR protocol URIs, prepares a VideoPlaybackAbrRequest with current state information.
|
|
125
|
+
* For regular URIs with UMP requirements, adds necessary query parameters.
|
|
126
|
+
* @returns Modified request with SABR-specific changes.
|
|
127
|
+
*/
|
|
128
|
+
async handleRequest(request) {
|
|
129
|
+
const originalUri = new URL(request.url);
|
|
130
|
+
if (originalUri.protocol === SABR_CONSTANTS.PROTOCOL) {
|
|
131
|
+
if (this.activeDelayPromise)
|
|
132
|
+
await this.activeDelayPromise;
|
|
133
|
+
if (!this.serverAbrStreamingUrl) {
|
|
134
|
+
throw new SabrAdapterError('Server ABR URL not set.');
|
|
135
|
+
}
|
|
136
|
+
if (!this.sabrFormats.length) {
|
|
137
|
+
throw new SabrAdapterError('No SABR formats available.');
|
|
138
|
+
}
|
|
139
|
+
const requestNumber = String(this.requestNumber++);
|
|
140
|
+
// Set the request number in the URL so we can identify it later (and also for the server).
|
|
141
|
+
const sabrUrl = new URL(this.serverAbrStreamingUrl || '');
|
|
142
|
+
sabrUrl.searchParams.set('rn', requestNumber);
|
|
143
|
+
request.url = sabrUrl.toString();
|
|
144
|
+
const currentFormat = this.sabrFormats.find((format) => fromFormat(format) === (originalUri.searchParams.get(SABR_CONSTANTS.KEY_PARAM) || ''));
|
|
145
|
+
if (!currentFormat)
|
|
146
|
+
throw new SabrAdapterError(`Could not determine current format from URL: ${request.url}`);
|
|
147
|
+
const activeFormats = this.playerAdapter.getActiveTrackFormats(currentFormat, this.sabrFormats);
|
|
148
|
+
const videoPlaybackAbrRequest = await this.createVideoPlaybackAbrRequest(request, currentFormat, activeFormats);
|
|
149
|
+
if (currentFormat.height) {
|
|
150
|
+
videoPlaybackAbrRequest.clientAbrState.stickyResolution = currentFormat.height;
|
|
151
|
+
videoPlaybackAbrRequest.clientAbrState.lastManualSelectedResolution = currentFormat.height;
|
|
152
|
+
}
|
|
153
|
+
const formatToDiscard = this.addBufferingInfoToAbrRequest(videoPlaybackAbrRequest, currentFormat, activeFormats);
|
|
154
|
+
if (formatToDiscard) {
|
|
155
|
+
videoPlaybackAbrRequest.selectedFormatIds.push(formatToDiscard);
|
|
156
|
+
}
|
|
157
|
+
if (!request.segment.isInit()) {
|
|
158
|
+
videoPlaybackAbrRequest.selectedFormatIds.push(currentFormat);
|
|
159
|
+
}
|
|
160
|
+
if (this.options.enableVerboseRequestLogging)
|
|
161
|
+
this.logger.debug(TAG, `Created VideoPlaybackAbrRequest (${requestNumber}):`, videoPlaybackAbrRequest);
|
|
162
|
+
request.body = VideoPlaybackAbrRequest.encode(videoPlaybackAbrRequest).finish();
|
|
163
|
+
this.requestMetadataManager.metadataMap.set(requestNumber, {
|
|
164
|
+
format: currentFormat,
|
|
165
|
+
isUMP: true,
|
|
166
|
+
isSABR: true,
|
|
167
|
+
isInit: request.segment.isInit(),
|
|
168
|
+
byteRange: parseRangeHeader(request.headers.Range),
|
|
169
|
+
timestamp: Date.now()
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
const webPoToken = this.onMintPoTokenCallback ? await this.onMintPoTokenCallback() : undefined;
|
|
174
|
+
// Handle simple UMP requests.
|
|
175
|
+
if (originalUri.pathname.includes('videoplayback/expire') || originalUri.pathname.includes('source/yt_live_broadcast')) {
|
|
176
|
+
originalUri.pathname += '/ump/1';
|
|
177
|
+
originalUri.pathname += '/srfvp/1';
|
|
178
|
+
originalUri.pathname += '/alr/yes';
|
|
179
|
+
if (webPoToken)
|
|
180
|
+
originalUri.pathname += `/pot/${webPoToken}`;
|
|
181
|
+
if (request.headers.Range)
|
|
182
|
+
originalUri.pathname += `/range/${request.headers.Range?.split('=')[1]}`;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
originalUri.searchParams.set('ump', '1');
|
|
186
|
+
originalUri.searchParams.set('srfvp', '1');
|
|
187
|
+
originalUri.searchParams.set('alr', 'yes');
|
|
188
|
+
if (webPoToken)
|
|
189
|
+
originalUri.searchParams.set('pot', webPoToken);
|
|
190
|
+
if (request.headers.Range)
|
|
191
|
+
originalUri.searchParams.set('range', request.headers.Range?.split('=')[1]);
|
|
192
|
+
}
|
|
193
|
+
const requestNumber = String(this.requestNumber++);
|
|
194
|
+
originalUri.searchParams.set('rn', requestNumber);
|
|
195
|
+
request.url = originalUri.toString();
|
|
196
|
+
request.body = UMP_REQUEST_BODY;
|
|
197
|
+
this.requestMetadataManager.metadataMap.set(requestNumber, {
|
|
198
|
+
isUMP: true,
|
|
199
|
+
isSABR: false,
|
|
200
|
+
timestamp: Date.now()
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
request.method = 'POST';
|
|
204
|
+
delete request.headers.Range;
|
|
205
|
+
return request;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Creates a VideoPlaybackAbrRequest object with current playback state information.
|
|
209
|
+
* @param request - The original player HTTP request.
|
|
210
|
+
* @param currentFormat - The format currently being fetched.
|
|
211
|
+
* @param activeFormats - Object containing references to active audio and video formats.
|
|
212
|
+
* @returns A populated VideoPlaybackAbrRequest object.
|
|
213
|
+
* @throws SabrAdapterError if ustreamer config is not set.
|
|
214
|
+
*/
|
|
215
|
+
async createVideoPlaybackAbrRequest(request, currentFormat, activeFormats) {
|
|
216
|
+
if (!this.ustreamerConfig) {
|
|
217
|
+
throw new SabrAdapterError('Ustreamer config not set');
|
|
218
|
+
}
|
|
219
|
+
const streamerContext = {
|
|
220
|
+
poToken: this.onMintPoTokenCallback ? base64ToU8(await this.onMintPoTokenCallback()) : undefined,
|
|
221
|
+
playbackCookie: this.lastPlaybackCookie ? PlaybackCookie.encode(this.lastPlaybackCookie).finish() : undefined,
|
|
222
|
+
clientInfo: this.options.clientInfo,
|
|
223
|
+
sabrContexts: [],
|
|
224
|
+
unsentSabrContexts: []
|
|
225
|
+
};
|
|
226
|
+
for (const ctxUpdate of this.sabrContexts.values()) {
|
|
227
|
+
if (this.activeSabrContextTypes.has(ctxUpdate.type)) {
|
|
228
|
+
streamerContext.sabrContexts.push(ctxUpdate);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
streamerContext.unsentSabrContexts.push(ctxUpdate.type);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return {
|
|
235
|
+
clientAbrState: {
|
|
236
|
+
playbackRate: this.playerAdapter.getPlaybackRate(),
|
|
237
|
+
playerTimeMs: Math.round((request.segment.getStartTime() ?? this.playerAdapter.getPlayerTime()) * 1000),
|
|
238
|
+
timeSinceLastManualFormatSelectionMs: 0,
|
|
239
|
+
clientViewportIsFlexible: false,
|
|
240
|
+
bandwidthEstimate: Math.round(this.playerAdapter.getBandwidthEstimate() || 0),
|
|
241
|
+
drcEnabled: currentFormat?.isDrc ?? false,
|
|
242
|
+
enabledTrackTypesBitfield: currentFormat.width ? EnabledTrackTypes.VIDEO_ONLY : EnabledTrackTypes.AUDIO_ONLY,
|
|
243
|
+
audioTrackId: currentFormat.audioTrackId
|
|
244
|
+
},
|
|
245
|
+
bufferedRanges: [],
|
|
246
|
+
selectedFormatIds: [],
|
|
247
|
+
preferredAudioFormatIds: [activeFormats.audioFormat || {}],
|
|
248
|
+
preferredVideoFormatIds: [activeFormats.videoFormat || {}],
|
|
249
|
+
preferredSubtitleFormatIds: [],
|
|
250
|
+
videoPlaybackUstreamerConfig: base64ToU8(this.ustreamerConfig),
|
|
251
|
+
streamerContext,
|
|
252
|
+
field1000: []
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Adds buffering information to the ABR request for all active formats.
|
|
257
|
+
*
|
|
258
|
+
* NOTE:
|
|
259
|
+
* On the web, mobile, and TV clients, buffered ranges in combination to player time is what dictates the segments you get.
|
|
260
|
+
* In our case, we are cheating a bit by abusing the player time field (in clientAbrState), setting it to the exact start
|
|
261
|
+
* time value of the segment we want, while YouTube simply uses the actual player time.
|
|
262
|
+
*
|
|
263
|
+
* We don't have to fully replicate this behavior for two reasons:
|
|
264
|
+
* 1. The SABR server will only send so much segments for a given player time. That means players like Shaka would
|
|
265
|
+
* not be able to buffer more than what the server thinks is enough. It would behave like YouTube's.
|
|
266
|
+
* 2. We don't have to know what segment a buffered range starts/ends at. It is easy to do in Shaka, but not in other players.
|
|
267
|
+
*
|
|
268
|
+
* @param videoPlaybackAbrRequest - The ABR request to modify with buffering information.
|
|
269
|
+
* @param currentFormat - The format currently being requested.
|
|
270
|
+
* @param activeFormats - References to the currently active audio and video formats.
|
|
271
|
+
* @returns The format to discard (if any) - typically formats that are active but not currently requested.
|
|
272
|
+
*/
|
|
273
|
+
addBufferingInfoToAbrRequest(videoPlaybackAbrRequest, currentFormat, activeFormats) {
|
|
274
|
+
let formatToDiscard;
|
|
275
|
+
const currentFormatKey = fromFormat(currentFormat);
|
|
276
|
+
for (const activeFormat of Object.values(activeFormats)) {
|
|
277
|
+
if (!activeFormat)
|
|
278
|
+
continue;
|
|
279
|
+
const activeFormatKey = fromFormat(activeFormat);
|
|
280
|
+
const shouldDiscard = currentFormatKey !== activeFormatKey;
|
|
281
|
+
const initializedFormat = this.initializedFormats.get(activeFormatKey || '');
|
|
282
|
+
const bufferedRange = shouldDiscard
|
|
283
|
+
? this.createFullBufferRange(activeFormat)
|
|
284
|
+
: this.createPartialBufferRange(initializedFormat);
|
|
285
|
+
if (bufferedRange) {
|
|
286
|
+
videoPlaybackAbrRequest.bufferedRanges.push(bufferedRange);
|
|
287
|
+
if (shouldDiscard) {
|
|
288
|
+
formatToDiscard = activeFormat;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return formatToDiscard;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Creates a bogus buffered range for a format. Used when we want to signal to the server to not send any
|
|
296
|
+
* segments for this format.
|
|
297
|
+
* @param format - The format to create a full buffer range for.
|
|
298
|
+
* @returns A BufferedRange object indicating the entire format is buffered.
|
|
299
|
+
*/
|
|
300
|
+
createFullBufferRange(format) {
|
|
301
|
+
return {
|
|
302
|
+
formatId: format,
|
|
303
|
+
durationMs: MAX_INT32_VALUE,
|
|
304
|
+
startTimeMs: 0,
|
|
305
|
+
startSegmentIndex: MAX_INT32_VALUE,
|
|
306
|
+
endSegmentIndex: MAX_INT32_VALUE,
|
|
307
|
+
timeRange: {
|
|
308
|
+
durationTicks: MAX_INT32_VALUE,
|
|
309
|
+
startTicks: 0,
|
|
310
|
+
timescale: 1000
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
}
|
|
314
|
+
/**
|
|
315
|
+
* Creates a buffered range representing a partially buffered format.
|
|
316
|
+
* @param initializedFormat - The format with initialization data.
|
|
317
|
+
* @returns A BufferedRange object with segment information, or null if no metadata is available.
|
|
318
|
+
*/
|
|
319
|
+
createPartialBufferRange(initializedFormat) {
|
|
320
|
+
if (!initializedFormat?.lastSegmentMetadata)
|
|
321
|
+
return null;
|
|
322
|
+
const { formatId, startSequenceNumber, timescale, durationMs, endSequenceNumber } = initializedFormat.lastSegmentMetadata;
|
|
323
|
+
return {
|
|
324
|
+
formatId,
|
|
325
|
+
startSegmentIndex: startSequenceNumber,
|
|
326
|
+
durationMs,
|
|
327
|
+
startTimeMs: 0,
|
|
328
|
+
endSegmentIndex: endSequenceNumber,
|
|
329
|
+
timeRange: {
|
|
330
|
+
timescale,
|
|
331
|
+
startTicks: 0,
|
|
332
|
+
durationTicks: durationMs
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Processes HTTP responses to extract SABR-specific information.
|
|
338
|
+
* @returns The response object.
|
|
339
|
+
*/
|
|
340
|
+
async handleResponse(response) {
|
|
341
|
+
const requestMetadata = this.requestMetadataManager.getRequestMetadata(response.url, true);
|
|
342
|
+
if (!requestMetadata)
|
|
343
|
+
return response;
|
|
344
|
+
const { streamInfo, format, byteRange, isSABR } = requestMetadata;
|
|
345
|
+
if (!streamInfo)
|
|
346
|
+
return response;
|
|
347
|
+
const retry = async () => {
|
|
348
|
+
const formatType = format?.width ? 'video' : 'audio';
|
|
349
|
+
const formatKey = fromFormat(format) || '';
|
|
350
|
+
const url = new URL(`${SABR_CONSTANTS.PROTOCOL}//${formatType}?${SABR_CONSTANTS.KEY_PARAM}=${formatKey}`);
|
|
351
|
+
return await this.makeFollowupRequest(response, url.toString(), isSABR, byteRange);
|
|
352
|
+
};
|
|
353
|
+
if (streamInfo.snackbarMessage) {
|
|
354
|
+
this.logger.debug(TAG, 'Received snackbar message:', streamInfo.snackbarMessage);
|
|
355
|
+
if (this.onSnackbarMessageCallback) {
|
|
356
|
+
this.onSnackbarMessageCallback(streamInfo.snackbarMessage);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (streamInfo.redirect?.url) {
|
|
360
|
+
let redirectUrl = new URL(streamInfo.redirect?.url);
|
|
361
|
+
this.logger.info(TAG, `Redirecting to ${redirectUrl}`);
|
|
362
|
+
if (isSABR) {
|
|
363
|
+
this.serverAbrStreamingUrl = streamInfo.redirect?.url;
|
|
364
|
+
const formatType = format?.width ? 'video' : 'audio';
|
|
365
|
+
const formatKey = fromFormat(format) || '';
|
|
366
|
+
redirectUrl = new URL(`${SABR_CONSTANTS.PROTOCOL}//${formatType}?${SABR_CONSTANTS.KEY_PARAM}=${formatKey}`);
|
|
367
|
+
}
|
|
368
|
+
// No media data = follow the redirect immediately.
|
|
369
|
+
if (!response.data?.byteLength) {
|
|
370
|
+
return await this.makeFollowupRequest(response, redirectUrl.toString(), isSABR, byteRange);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (streamInfo.nextRequestPolicy) {
|
|
374
|
+
this.lastPlaybackCookie = streamInfo.nextRequestPolicy?.playbackCookie;
|
|
375
|
+
const delayMs = streamInfo.nextRequestPolicy.backoffTimeMs || 0;
|
|
376
|
+
if (delayMs > 0 && !this.activeDelayPromise) {
|
|
377
|
+
this.logger.info(TAG, `Delaying next requests by ${delayMs / 1000} seconds.`);
|
|
378
|
+
this.activeDelayPromise = new Promise((resolve) => {
|
|
379
|
+
setTimeout(() => {
|
|
380
|
+
this.logger.info(TAG, 'Delay completed, resuming requests.');
|
|
381
|
+
this.activeDelayPromise = null;
|
|
382
|
+
resolve();
|
|
383
|
+
}, delayMs);
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
if (streamInfo.sabrContextSendingPolicy) {
|
|
388
|
+
for (const startPolicy of streamInfo.sabrContextSendingPolicy.startPolicy) {
|
|
389
|
+
if (!this.activeSabrContextTypes.has(startPolicy)) {
|
|
390
|
+
this.activeSabrContextTypes.add(startPolicy);
|
|
391
|
+
this.logger.debug(TAG, `Activated SABR context for type ${startPolicy}`);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
for (const stopPolicy of streamInfo.sabrContextSendingPolicy.stopPolicy) {
|
|
395
|
+
if (this.activeSabrContextTypes.has(stopPolicy)) {
|
|
396
|
+
this.activeSabrContextTypes.delete(stopPolicy);
|
|
397
|
+
this.logger.debug(TAG, `Deactivated SABR context for type ${stopPolicy}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
for (const discardPolicy of streamInfo.sabrContextSendingPolicy.discardPolicy) {
|
|
401
|
+
if (this.sabrContexts.has(discardPolicy)) {
|
|
402
|
+
this.sabrContexts.delete(discardPolicy);
|
|
403
|
+
this.logger.debug(TAG, `Discarded SABR context for type ${discardPolicy}`);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (streamInfo.sabrContextUpdate && (streamInfo.sabrContextUpdate.type !== undefined && streamInfo.sabrContextUpdate.value?.length)) {
|
|
408
|
+
if (!this.sabrContexts.has(streamInfo.sabrContextUpdate.type) || streamInfo.sabrContextUpdate.writePolicy === SabrContextWritePolicy.OVERWRITE) {
|
|
409
|
+
this.logger.debug(TAG, `Received SABR context update (type: ${streamInfo.sabrContextUpdate.type}, writePolicy: ${SabrContextWritePolicy[streamInfo.sabrContextUpdate.writePolicy]} sendByDefault: ${streamInfo.sabrContextUpdate.sendByDefault})`);
|
|
410
|
+
this.sabrContexts.set(streamInfo.sabrContextUpdate.type, streamInfo.sabrContextUpdate);
|
|
411
|
+
}
|
|
412
|
+
if (streamInfo.sabrContextUpdate.sendByDefault) {
|
|
413
|
+
this.activeSabrContextTypes.add(streamInfo.sabrContextUpdate.type);
|
|
414
|
+
}
|
|
415
|
+
// Retry if we got no media data.
|
|
416
|
+
if (!response.data?.byteLength) {
|
|
417
|
+
return retry();
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
// Try reloading the streaming data, if possible.
|
|
421
|
+
if (streamInfo.reloadPlaybackContext && this.onReloadPlayerResponseCallback) {
|
|
422
|
+
this.logger.info(TAG, 'Server requested player reload with new parameters:', streamInfo.reloadPlaybackContext);
|
|
423
|
+
await this.onReloadPlayerResponseCallback(streamInfo.reloadPlaybackContext);
|
|
424
|
+
return retry();
|
|
425
|
+
}
|
|
426
|
+
if (streamInfo.mediaHeader) {
|
|
427
|
+
const formatKey = fromMediaHeader(streamInfo.mediaHeader);
|
|
428
|
+
if (streamInfo.mediaHeader.isInitSeg)
|
|
429
|
+
return;
|
|
430
|
+
const initializedFormat = this.initializedFormats.get(formatKey) || {};
|
|
431
|
+
initializedFormat.lastSegmentMetadata = {
|
|
432
|
+
formatId: streamInfo.mediaHeader.formatId,
|
|
433
|
+
startSequenceNumber: streamInfo.mediaHeader.sequenceNumber || 1,
|
|
434
|
+
endSequenceNumber: streamInfo.mediaHeader.sequenceNumber || 1,
|
|
435
|
+
startTimeMs: streamInfo.mediaHeader.startMs || 0,
|
|
436
|
+
durationMs: streamInfo.mediaHeader.durationMs || 0,
|
|
437
|
+
timescale: streamInfo.mediaHeader.timeRange?.timescale || 1000
|
|
438
|
+
};
|
|
439
|
+
this.initializedFormats.set(formatKey, initializedFormat);
|
|
440
|
+
}
|
|
441
|
+
return response;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Makes a followup request and updates the original response object with the new data.
|
|
445
|
+
* @param originalResponse - The original HTTP response.
|
|
446
|
+
* @param url - The URL to request.
|
|
447
|
+
* @param isSABR - Whether this is a SABR request.
|
|
448
|
+
* @param byteRange - Optional byte range for the request.
|
|
449
|
+
* @returns The updated response.
|
|
450
|
+
*/
|
|
451
|
+
async makeFollowupRequest(originalResponse, url, isSABR, byteRange) {
|
|
452
|
+
if (this.activeDelayPromise)
|
|
453
|
+
await this.activeDelayPromise;
|
|
454
|
+
const headers = {};
|
|
455
|
+
// Keep range so we can slice the response (only used for init segments).
|
|
456
|
+
if (isSABR && byteRange) {
|
|
457
|
+
headers['Range'] = `bytes=${byteRange.start}-${byteRange.end}`;
|
|
458
|
+
}
|
|
459
|
+
const redirectResponse = await originalResponse.makeRequest(url, headers);
|
|
460
|
+
Object.assign(originalResponse, redirectResponse);
|
|
461
|
+
return originalResponse;
|
|
462
|
+
}
|
|
463
|
+
checkDisposed() {
|
|
464
|
+
if (this.isDisposed) {
|
|
465
|
+
throw new SabrAdapterError('Adapter has been disposed.');
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Releases resources and cleans up the adapter instance.
|
|
470
|
+
* After calling dispose, the adapter can no longer be used.
|
|
471
|
+
*/
|
|
472
|
+
dispose() {
|
|
473
|
+
if (this.isDisposed)
|
|
474
|
+
return;
|
|
475
|
+
this.cacheManager?.dispose();
|
|
476
|
+
this.cacheManager = null;
|
|
477
|
+
this.initializedFormats.clear();
|
|
478
|
+
this.requestMetadataManager.metadataMap.clear();
|
|
479
|
+
this.sabrContexts.clear();
|
|
480
|
+
this.activeSabrContextTypes.clear();
|
|
481
|
+
this.lastPlaybackCookie = undefined;
|
|
482
|
+
this.sabrFormats = [];
|
|
483
|
+
this.serverAbrStreamingUrl = undefined;
|
|
484
|
+
this.ustreamerConfig = undefined;
|
|
485
|
+
this.activeDelayPromise = null;
|
|
486
|
+
this.playerAdapter.dispose();
|
|
487
|
+
this.requestNumber = 0;
|
|
488
|
+
this.onReloadPlayerResponseCallback = undefined;
|
|
489
|
+
this.onSnackbarMessageCallback = undefined;
|
|
490
|
+
this.onMintPoTokenCallback = undefined;
|
|
491
|
+
this.options = undefined;
|
|
492
|
+
this.isDisposed = true;
|
|
493
|
+
this.logger.debug(TAG, 'Disposed');
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
//# sourceMappingURL=SabrStreamingAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SabrStreamingAdapter.js","sourceRoot":"","sources":["../../../src/core/SabrStreamingAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type CacheManager } from '../utils/index.js';
|
|
2
|
+
import { MediaHeader } from '../utils/Protos.js';
|
|
3
|
+
import type { Part } from '../types/shared.js';
|
|
4
|
+
import type { SabrRequestMetadata } from '../types/sabrStreamingAdapterTypes.js';
|
|
5
|
+
interface Segment {
|
|
6
|
+
headerId?: number;
|
|
7
|
+
mediaHeader: MediaHeader;
|
|
8
|
+
complete?: boolean;
|
|
9
|
+
bufferedChunks: Uint8Array[];
|
|
10
|
+
lastChunkSize: number;
|
|
11
|
+
}
|
|
12
|
+
export interface UmpProcessingResult {
|
|
13
|
+
data?: Uint8Array;
|
|
14
|
+
done: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* This class is responsible for reading a UMP stream, handling different part types
|
|
18
|
+
* (like media headers, media data, and server directives), and populating a
|
|
19
|
+
* metadata object with the extracted information. It is supposed to be used
|
|
20
|
+
* in conjunction with a {@linkcode SabrPlayerAdapter} in video player
|
|
21
|
+
* implementations.
|
|
22
|
+
*/
|
|
23
|
+
export declare class SabrUmpProcessor {
|
|
24
|
+
private requestMetadata;
|
|
25
|
+
private cacheManager?;
|
|
26
|
+
partialPart?: Part;
|
|
27
|
+
private readonly formatInitMetadata;
|
|
28
|
+
private desiredHeaderId?;
|
|
29
|
+
private partialSegments;
|
|
30
|
+
private readonly umpPartHandlers;
|
|
31
|
+
constructor(requestMetadata: SabrRequestMetadata, cacheManager?: CacheManager | undefined);
|
|
32
|
+
/**
|
|
33
|
+
* Processes a chunk of data from a UMP stream and updates the request context.
|
|
34
|
+
* @returns A promise that resolves with a processing result if a terminal part is found (e.g., MediaEnd), or undefined otherwise.
|
|
35
|
+
* @param value
|
|
36
|
+
*/
|
|
37
|
+
processChunk(value: Uint8Array): Promise<UmpProcessingResult | undefined>;
|
|
38
|
+
getSegmentInfo(): Segment | undefined;
|
|
39
|
+
private decodePart;
|
|
40
|
+
private handleFormatInitMetadata;
|
|
41
|
+
private handleNextRequestPolicy;
|
|
42
|
+
private handleMediaHeader;
|
|
43
|
+
private handleMedia;
|
|
44
|
+
private handleMediaEnd;
|
|
45
|
+
private handleSnackbarMessage;
|
|
46
|
+
private handleSabrError;
|
|
47
|
+
private handleStreamProtectionStatus;
|
|
48
|
+
private handleReloadPlayerResponse;
|
|
49
|
+
private handleSabrRedirect;
|
|
50
|
+
private handleSabrContextUpdate;
|
|
51
|
+
private handleSabrContextSendingPolicy;
|
|
52
|
+
}
|
|
53
|
+
export {};
|