shaka-player 3.1.4 → 3.3.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/.github/ISSUE_TEMPLATE/bug_report.md +1 -1
- package/.github/ISSUE_TEMPLATE/feature_request.md +1 -1
- package/.github/ISSUE_TEMPLATE/question.md +1 -1
- package/AUTHORS +6 -5
- package/CHANGELOG.md +363 -0
- package/CONTRIBUTORS +4 -2
- package/README.md +4 -4
- package/build/types/core +3 -0
- package/build/types/offline +1 -0
- package/build/types/polyfill +2 -0
- package/build/types/ui +2 -0
- package/demo/common/asset.js +9 -7
- package/demo/common/assets.js +28 -1
- package/demo/common/message_ids.js +15 -2
- package/demo/config.js +35 -2
- package/demo/index.html +1 -1
- package/demo/locales/en.json +14 -1
- package/demo/locales/source.json +56 -4
- package/demo/main.js +2 -1
- package/dist/controls.css +26 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +24 -21
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +24 -21
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +33 -25
- package/dist/locales.js +31 -29
- package/dist/receiver.compiled.debug.js +14 -12
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +14 -12
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +258 -20
- package/dist/shaka-player.compiled.debug.d.ts +258 -20
- package/dist/shaka-player.compiled.debug.externs.js +1005 -695
- package/dist/shaka-player.compiled.debug.js +720 -640
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +1005 -695
- package/dist/shaka-player.compiled.js +850 -817
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +274 -21
- package/dist/shaka-player.ui.debug.d.ts +274 -21
- package/dist/shaka-player.ui.debug.externs.js +766 -429
- package/dist/shaka-player.ui.debug.js +863 -765
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +766 -429
- package/dist/shaka-player.ui.js +1042 -996
- package/dist/shaka-player.ui.map +4 -4
- package/docs/design/bg-fetch-after.gv +29 -0
- package/docs/design/bg-fetch-after.gv.png +0 -0
- package/docs/design/bg-fetch-before.gv +18 -0
- package/docs/design/bg-fetch-before.gv.png +0 -0
- package/docs/design/bg-fetch.md +134 -0
- package/docs/tutorials/blob-url.md +15 -0
- package/docs/tutorials/index.json +1 -0
- package/docs/tutorials/ui-customization.md +66 -0
- package/docs/tutorials/ui.md +5 -5
- package/externs/aria.js +6 -0
- package/externs/ima.js +3 -0
- package/externs/shaka/ads.js +29 -1
- package/externs/shaka/manifest.js +18 -2
- package/externs/shaka/manifest_parser.js +10 -1
- package/externs/shaka/net.js +20 -4
- package/externs/shaka/offline.js +36 -2
- package/externs/shaka/player.js +182 -13
- package/externs/shaka/text.js +24 -10
- package/externs/texttrack.js +3 -0
- package/externs/webcrypto.js +18 -0
- package/lib/abr/ewma.js +14 -0
- package/lib/abr/ewma_bandwidth_estimator.js +16 -2
- package/lib/abr/simple_abr_manager.js +6 -0
- package/lib/ads/ad_manager.js +16 -15
- package/lib/ads/client_side_ad.js +8 -0
- package/lib/ads/client_side_ad_manager.js +14 -6
- package/lib/ads/server_side_ad.js +7 -0
- package/lib/ads/server_side_ad_manager.js +19 -2
- package/lib/cast/cast_proxy.js +8 -0
- package/lib/cast/cast_utils.js +7 -1
- package/lib/cea/cea608_data_channel.js +56 -56
- package/lib/cea/cea608_memory.js +33 -33
- package/lib/cea/cea708_service.js +43 -43
- package/lib/cea/cea708_window.js +38 -38
- package/lib/cea/cea_decoder.js +13 -14
- package/lib/cea/cea_utils.js +23 -23
- package/lib/cea/dtvcc_packet_builder.js +7 -7
- package/lib/cea/i_caption_decoder.js +2 -3
- package/lib/cea/i_cea_parser.js +2 -2
- package/lib/cea/mp4_cea_parser.js +6 -6
- package/lib/dash/dash_parser.js +53 -14
- package/lib/dash/segment_base.js +25 -1
- package/lib/dash/segment_list.js +18 -9
- package/lib/dash/segment_template.js +23 -10
- package/lib/hls/hls_parser.js +210 -30
- package/lib/media/closed_caption_parser.js +1 -2
- package/lib/media/drm_engine.js +162 -192
- package/lib/media/quality_observer.js +291 -0
- package/lib/media/segment_index.js +9 -1
- package/lib/media/segment_reference.js +37 -5
- package/lib/media/streaming_engine.js +48 -10
- package/lib/net/http_fetch_plugin.js +31 -11
- package/lib/net/http_plugin_utils.js +1 -0
- package/lib/net/http_xhr_plugin.js +40 -14
- package/lib/net/networking_engine.js +82 -18
- package/lib/offline/download_info.js +68 -0
- package/lib/offline/download_manager.js +14 -7
- package/lib/offline/indexeddb/base_storage_cell.js +35 -0
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v5_storage_cell.js +5 -0
- package/lib/offline/manifest_converter.js +3 -1
- package/lib/offline/storage.js +404 -297
- package/lib/offline/stored_content_utils.js +2 -0
- package/lib/player.js +622 -153
- package/lib/polyfill/aria.js +82 -0
- package/lib/polyfill/random_uuid.js +52 -0
- package/lib/routing/walker.js +2 -3
- package/lib/text/cue.js +12 -0
- package/lib/text/srt_text_parser.js +4 -4
- package/lib/text/text_engine.js +2 -2
- package/lib/text/ttml_text_parser.js +25 -2
- package/lib/text/ui_text_displayer.js +2 -2
- package/lib/text/vtt_text_parser.js +2 -2
- package/lib/text/web_vtt_generator.js +55 -12
- package/lib/util/cmcd_manager.js +826 -0
- package/lib/util/error.js +12 -0
- package/lib/util/language_utils.js +12 -0
- package/lib/util/manifest_parser_utils.js +1 -0
- package/lib/util/mp4_box_parsers.js +20 -20
- package/lib/util/multi_map.js +8 -0
- package/lib/util/mutex.js +52 -0
- package/lib/util/periods.js +98 -64
- package/lib/util/player_configuration.js +31 -1
- package/lib/util/stream_utils.js +140 -85
- package/lib/util/xml_utils.js +31 -12
- package/package.json +1 -1
- package/roadmap.md +24 -22
- package/shaka-player.uncompiled.js +4 -0
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/cea/cea608_memory_unit.js +1 -1
- package/test/cea/cea708_service_unit.js +8 -8
- package/test/cea/cea708_window_unit.js +6 -6
- package/test/cea/cea_decoder_unit.js +1 -1
- package/test/cea/dtvcc_packet_builder_unit.js +2 -2
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_live_unit.js +101 -1
- package/test/dash/dash_parser_manifest_unit.js +78 -2
- package/test/dash/dash_parser_segment_base_unit.js +2 -0
- package/test/dash/dash_parser_segment_list_unit.js +2 -1
- package/test/dash/dash_parser_segment_template_unit.js +2 -1
- package/test/hls/hls_live_unit.js +2 -0
- package/test/hls/hls_parser_unit.js +252 -0
- package/test/media/drm_engine_integration.js +86 -12
- package/test/media/drm_engine_unit.js +310 -450
- package/test/media/quality_observer_unit.js +139 -0
- package/test/media/segment_reference_unit.js +16 -1
- package/test/media/streaming_engine_integration.js +2 -1
- package/test/media/streaming_engine_unit.js +2 -0
- package/test/net/http_plugin_unit.js +20 -15
- package/test/offline/manifest_convert_unit.js +2 -0
- package/test/offline/storage_integration.js +117 -23
- package/test/player_integration.js +151 -0
- package/test/player_src_equals_integration.js +52 -0
- package/test/player_unit.js +11 -33
- package/test/test/assets/chapters.srt +11 -0
- package/test/test/assets/chapters.vtt +10 -0
- package/test/test/util/cea_utils.js +12 -12
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad.js +7 -0
- package/test/test/util/fake_ad_manager.js +7 -0
- package/test/test/util/fake_drm_engine.js +9 -2
- package/test/test/util/manifest_generator.js +5 -2
- package/test/test/util/manifest_parser_util.js +3 -1
- package/test/test/util/test_scheme.js +14 -1
- package/test/text/ttml_text_parser_unit.js +47 -0
- package/test/text/web_vtt_generator_unit.js +81 -7
- package/test/ui/ui_unit.js +250 -0
- package/test/util/cmcd_manager_unit.js +277 -0
- package/test/util/stream_utils_unit.js +118 -10
- package/ui/airplay_button.js +2 -1
- package/ui/audio_language_selection.js +9 -5
- package/ui/cast_button.js +5 -6
- package/ui/constants.js +0 -3
- package/ui/context_menu.js +109 -0
- package/ui/controls.js +41 -7
- package/ui/controls.less +1 -0
- package/ui/enums.js +4 -0
- package/ui/externs/ui.js +28 -1
- package/ui/fast_forward_button.js +16 -8
- package/ui/fullscreen_button.js +2 -3
- package/ui/language_utils.js +1 -1
- package/ui/less/buttons.less +0 -4
- package/ui/less/containers.less +74 -0
- package/ui/less/overflow_menu.less +0 -10
- package/ui/less/tooltip.less +97 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/source.json +4 -0
- package/ui/loop_button.js +6 -3
- package/ui/mute_button.js +3 -4
- package/ui/overflow_menu.js +7 -28
- package/ui/pip_button.js +10 -7
- package/ui/play_button.js +2 -2
- package/ui/playback_rate_selection.js +11 -15
- package/ui/presentation_time.js +1 -3
- package/ui/resolution_selection.js +11 -7
- package/ui/rewind_button.js +17 -9
- package/ui/seek_bar.js +6 -6
- package/ui/settings_menu.js +36 -4
- package/ui/small_play_button.js +1 -0
- package/ui/spacer.js +1 -1
- package/ui/statistics_button.js +253 -0
- package/ui/text_selection.js +19 -15
- package/ui/ui.js +30 -0
- package/ui/ui_utils.js +1 -1
- package/ui/volume_bar.js +2 -4
|
@@ -0,0 +1,826 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.util.CmcdManager');
|
|
8
|
+
|
|
9
|
+
goog.require('shaka.log');
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @summary
|
|
14
|
+
* A CmcdManager maintains CMCD state as well as a collection of utility
|
|
15
|
+
* functions.
|
|
16
|
+
*/
|
|
17
|
+
shaka.util.CmcdManager = class {
|
|
18
|
+
/**
|
|
19
|
+
* @param {shaka.util.CmcdManager.PlayerInterface} playerInterface
|
|
20
|
+
* @param {shaka.extern.CmcdConfiguration} config
|
|
21
|
+
*/
|
|
22
|
+
constructor(playerInterface, config) {
|
|
23
|
+
/** @private {shaka.util.CmcdManager.PlayerInterface} */
|
|
24
|
+
this.playerInterface_ = playerInterface;
|
|
25
|
+
|
|
26
|
+
/** @private {?shaka.extern.CmcdConfiguration} */
|
|
27
|
+
this.config_ = config;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Session ID
|
|
31
|
+
*
|
|
32
|
+
* @private {string}
|
|
33
|
+
*/
|
|
34
|
+
this.sid_ = config.sessionId || window.crypto.randomUUID();
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Streaming format
|
|
38
|
+
*
|
|
39
|
+
* @private {(shaka.util.CmcdManager.StreamingFormat|undefined)}
|
|
40
|
+
*/
|
|
41
|
+
this.sf_ = undefined;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @private {boolean}
|
|
45
|
+
*/
|
|
46
|
+
this.playbackStarted_ = false;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @private {boolean}
|
|
50
|
+
*/
|
|
51
|
+
this.buffering_ = true;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @private {boolean}
|
|
55
|
+
*/
|
|
56
|
+
this.starved_ = false;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Set the buffering state
|
|
61
|
+
*
|
|
62
|
+
* @param {boolean} buffering
|
|
63
|
+
*/
|
|
64
|
+
setBuffering(buffering) {
|
|
65
|
+
if (!buffering && !this.playbackStarted_) {
|
|
66
|
+
this.playbackStarted_ = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (this.playbackStarted_ && buffering) {
|
|
70
|
+
this.starved_ = true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
this.buffering_ = buffering;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Apply CMCD data to a manifest request.
|
|
78
|
+
*
|
|
79
|
+
* @param {!shaka.extern.Request} request
|
|
80
|
+
* The request to apply CMCD data to
|
|
81
|
+
* @param {shaka.util.CmcdManager.ManifestInfo} manifestInfo
|
|
82
|
+
* The manifest format
|
|
83
|
+
*/
|
|
84
|
+
applyManifestData(request, manifestInfo) {
|
|
85
|
+
try {
|
|
86
|
+
if (!this.config_.enabled) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
this.sf_ = manifestInfo.format;
|
|
91
|
+
|
|
92
|
+
this.apply_(request, {
|
|
93
|
+
ot: shaka.util.CmcdManager.ObjectType.MANIFEST,
|
|
94
|
+
su: !this.playbackStarted_,
|
|
95
|
+
});
|
|
96
|
+
} catch (error) {
|
|
97
|
+
shaka.log.warnOnce('CMCD_MANIFEST_ERROR',
|
|
98
|
+
'Could not generate manifest CMCD data.', error);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Apply CMCD data to a segment request
|
|
104
|
+
*
|
|
105
|
+
* @param {!shaka.extern.Request} request
|
|
106
|
+
* @param {shaka.util.CmcdManager.SegmentInfo} segmentInfo
|
|
107
|
+
*/
|
|
108
|
+
applySegmentData(request, segmentInfo) {
|
|
109
|
+
try {
|
|
110
|
+
if (!this.config_.enabled) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const data = {
|
|
115
|
+
d: segmentInfo.duration * 1000,
|
|
116
|
+
st: this.getStreamType_(),
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
data.ot = this.getObjectType_(segmentInfo);
|
|
120
|
+
|
|
121
|
+
const isMedia = data.ot === shaka.util.CmcdManager.ObjectType.VIDEO ||
|
|
122
|
+
data.ot === shaka.util.CmcdManager.ObjectType.AUDIO ||
|
|
123
|
+
data.ot === shaka.util.CmcdManager.ObjectType.MUXED ||
|
|
124
|
+
data.ot === shaka.util.CmcdManager.ObjectType.TIMED_TEXT;
|
|
125
|
+
|
|
126
|
+
if (isMedia) {
|
|
127
|
+
data.bl = this.getBufferLength_(segmentInfo.type);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
if (segmentInfo.bandwidth) {
|
|
131
|
+
data.br = segmentInfo.bandwidth / 1000;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
data.tb = this.getTopBandwidth_(segmentInfo.type) / 1000;
|
|
135
|
+
|
|
136
|
+
this.apply_(request, data);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
shaka.log.warnOnce('CMCD_SEGMENT_ERROR',
|
|
139
|
+
'Could not generate segment CMCD data.', error);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Apply CMCD data to a text request
|
|
145
|
+
*
|
|
146
|
+
* @param {!shaka.extern.Request} request
|
|
147
|
+
*/
|
|
148
|
+
applyTextData(request) {
|
|
149
|
+
try {
|
|
150
|
+
this.apply_(request, {
|
|
151
|
+
ot: shaka.util.CmcdManager.ObjectType.CAPTION,
|
|
152
|
+
su: true,
|
|
153
|
+
});
|
|
154
|
+
} catch (error) {
|
|
155
|
+
shaka.log.warnOnce('CMCD_TEXT_ERROR',
|
|
156
|
+
'Could not generate text CMCD data.', error);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Apply CMCD data to streams loaded via src=.
|
|
162
|
+
*
|
|
163
|
+
* @param {string} uri
|
|
164
|
+
* @param {string} mimeType
|
|
165
|
+
* @return {string}
|
|
166
|
+
*/
|
|
167
|
+
appendSrcData(uri, mimeType) {
|
|
168
|
+
try {
|
|
169
|
+
if (!this.config_.enabled) {
|
|
170
|
+
return uri;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const data = this.createData_();
|
|
174
|
+
data.ot = this.getObjectTypeFromMimeType_(mimeType);
|
|
175
|
+
data.su = true;
|
|
176
|
+
|
|
177
|
+
const query = shaka.util.CmcdManager.toQuery(data);
|
|
178
|
+
|
|
179
|
+
return shaka.util.CmcdManager.appendQueryToUri(uri, query);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
shaka.log.warnOnce('CMCD_SRC_ERROR',
|
|
182
|
+
'Could not generate src CMCD data.', error);
|
|
183
|
+
return uri;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Apply CMCD data to side car text track uri.
|
|
189
|
+
*
|
|
190
|
+
* @param {string} uri
|
|
191
|
+
* @return {string}
|
|
192
|
+
*/
|
|
193
|
+
appendTextTrackData(uri) {
|
|
194
|
+
try {
|
|
195
|
+
if (!this.config_.enabled) {
|
|
196
|
+
return uri;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const data = this.createData_();
|
|
200
|
+
data.ot = shaka.util.CmcdManager.ObjectType.CAPTION;
|
|
201
|
+
data.su = true;
|
|
202
|
+
|
|
203
|
+
const query = shaka.util.CmcdManager.toQuery(data);
|
|
204
|
+
|
|
205
|
+
return shaka.util.CmcdManager.appendQueryToUri(uri, query);
|
|
206
|
+
} catch (error) {
|
|
207
|
+
shaka.log.warnOnce('CMCD_TEXT_TRACK_ERROR',
|
|
208
|
+
'Could not generate text track CMCD data.', error);
|
|
209
|
+
return uri;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Create baseline CMCD data
|
|
215
|
+
*
|
|
216
|
+
* @return {shaka.util.CmcdManager.Data}
|
|
217
|
+
* @private
|
|
218
|
+
*/
|
|
219
|
+
createData_() {
|
|
220
|
+
return {
|
|
221
|
+
v: shaka.util.CmcdManager.Version,
|
|
222
|
+
sf: this.sf_,
|
|
223
|
+
sid: this.sid_,
|
|
224
|
+
cid: this.config_.contentId,
|
|
225
|
+
mtp: this.playerInterface_.getBandwidthEstimate() / 1000,
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Apply CMCD data to a request.
|
|
231
|
+
*
|
|
232
|
+
* @param {!shaka.extern.Request} request The request to apply CMCD data to
|
|
233
|
+
* @param {!shaka.util.CmcdManager.Data} data The data object
|
|
234
|
+
* @param {boolean} useHeaders Send data via request headers
|
|
235
|
+
* @private
|
|
236
|
+
*/
|
|
237
|
+
apply_(request, data = {}, useHeaders = this.config_.useHeaders) {
|
|
238
|
+
if (!this.config_.enabled) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// apply baseline data
|
|
243
|
+
Object.assign(data, this.createData_());
|
|
244
|
+
|
|
245
|
+
data.pr = this.playerInterface_.getPlaybackRate();
|
|
246
|
+
|
|
247
|
+
const isVideo = data.ot === shaka.util.CmcdManager.ObjectType.VIDEO ||
|
|
248
|
+
data.ot === shaka.util.CmcdManager.ObjectType.MUXED;
|
|
249
|
+
|
|
250
|
+
if (this.starved_ && isVideo) {
|
|
251
|
+
data.bs = true;
|
|
252
|
+
data.su = true;
|
|
253
|
+
this.starved_ = false;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (data.su == null) {
|
|
257
|
+
data.su = this.buffering_;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// TODO: Implement rtp, nrr, nor, dl
|
|
261
|
+
|
|
262
|
+
if (useHeaders) {
|
|
263
|
+
const headers = shaka.util.CmcdManager.toHeaders(data);
|
|
264
|
+
if (!Object.keys(headers).length) {
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
Object.assign(request.headers, headers);
|
|
269
|
+
} else {
|
|
270
|
+
const query = shaka.util.CmcdManager.toQuery(data);
|
|
271
|
+
if (!query) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
request.uris = request.uris.map((uri) => {
|
|
276
|
+
return shaka.util.CmcdManager.appendQueryToUri(uri, query);
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* The CMCD object type.
|
|
283
|
+
*
|
|
284
|
+
* @param {shaka.util.CmcdManager.SegmentInfo} segmentInfo
|
|
285
|
+
* @private
|
|
286
|
+
*/
|
|
287
|
+
getObjectType_(segmentInfo) {
|
|
288
|
+
const type = segmentInfo.type;
|
|
289
|
+
|
|
290
|
+
if (segmentInfo.init) {
|
|
291
|
+
return shaka.util.CmcdManager.ObjectType.INIT;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
if (type == 'video') {
|
|
295
|
+
if (segmentInfo.codecs.includes(',')) {
|
|
296
|
+
return shaka.util.CmcdManager.ObjectType.MUXED;
|
|
297
|
+
}
|
|
298
|
+
return shaka.util.CmcdManager.ObjectType.VIDEO;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (type == 'audio') {
|
|
302
|
+
return shaka.util.CmcdManager.ObjectType.AUDIO;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (type == 'text') {
|
|
306
|
+
if (segmentInfo.mimeType === 'application/mp4') {
|
|
307
|
+
return shaka.util.CmcdManager.ObjectType.TIMED_TEXT;
|
|
308
|
+
}
|
|
309
|
+
return shaka.util.CmcdManager.ObjectType.CAPTION;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
return undefined;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* The CMCD object type from mimeType.
|
|
317
|
+
*
|
|
318
|
+
* @param {!string} mimeType
|
|
319
|
+
* @return {(shaka.util.CmcdManager.ObjectType|undefined)}
|
|
320
|
+
* @private
|
|
321
|
+
*/
|
|
322
|
+
getObjectTypeFromMimeType_(mimeType) {
|
|
323
|
+
switch (mimeType) {
|
|
324
|
+
case 'video/webm':
|
|
325
|
+
case 'video/mp4':
|
|
326
|
+
return shaka.util.CmcdManager.ObjectType.MUXED;
|
|
327
|
+
|
|
328
|
+
case 'application/x-mpegurl':
|
|
329
|
+
return shaka.util.CmcdManager.ObjectType.MANIFEST;
|
|
330
|
+
|
|
331
|
+
default:
|
|
332
|
+
return undefined;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* Get the buffer length for a media type in milliseconds
|
|
338
|
+
*
|
|
339
|
+
* @param {string} type
|
|
340
|
+
* @return {number}
|
|
341
|
+
* @private
|
|
342
|
+
*/
|
|
343
|
+
getBufferLength_(type) {
|
|
344
|
+
const ranges = this.playerInterface_.getBufferedInfo()[type];
|
|
345
|
+
|
|
346
|
+
if (!ranges.length) {
|
|
347
|
+
return NaN;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const start = this.playerInterface_.getCurrentTime();
|
|
351
|
+
const range = ranges.find((r) => r.start <= start && r.end >= start);
|
|
352
|
+
|
|
353
|
+
if (!range) {
|
|
354
|
+
return NaN;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return (range.end - start) * 1000;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Get the stream type
|
|
362
|
+
*
|
|
363
|
+
* @return {shaka.util.CmcdManager.StreamType}
|
|
364
|
+
* @private
|
|
365
|
+
*/
|
|
366
|
+
getStreamType_() {
|
|
367
|
+
const isLive = this.playerInterface_.isLive();
|
|
368
|
+
if (isLive) {
|
|
369
|
+
return shaka.util.CmcdManager.StreamType.LIVE;
|
|
370
|
+
} else {
|
|
371
|
+
return shaka.util.CmcdManager.StreamType.VOD;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Get the highest bandwidth for a given type.
|
|
377
|
+
*
|
|
378
|
+
* @param {string} type
|
|
379
|
+
* @return {number}
|
|
380
|
+
* @private
|
|
381
|
+
*/
|
|
382
|
+
getTopBandwidth_(type) {
|
|
383
|
+
const manifest = this.playerInterface_.getManifest();
|
|
384
|
+
if (!manifest) {
|
|
385
|
+
return NaN;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const variants = (type === 'text') ?
|
|
389
|
+
manifest.textStreams : manifest.variants;
|
|
390
|
+
let top = variants[0][type] || variants[0];
|
|
391
|
+
|
|
392
|
+
for (const variant of variants) {
|
|
393
|
+
const stream = variant[type] || variant;
|
|
394
|
+
if (stream.bandwidth > top.bandwidth) {
|
|
395
|
+
top = stream;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return top.bandwidth;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Serialize a CMCD data object according to the rules defined in the
|
|
404
|
+
* section 3.2 of
|
|
405
|
+
* [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
|
|
406
|
+
*
|
|
407
|
+
* @param {shaka.util.CmcdManager.Data} data The CMCD data object
|
|
408
|
+
* @return {string}
|
|
409
|
+
*/
|
|
410
|
+
static serialize(data) {
|
|
411
|
+
const results = [];
|
|
412
|
+
const isValid = (value) =>
|
|
413
|
+
!Number.isNaN(value) && value != null && value !== '' && value !== false;
|
|
414
|
+
const toRounded = (value) => Math.round(value);
|
|
415
|
+
const toHundred = (value) => toRounded(value / 100) * 100;
|
|
416
|
+
const toUrlSafe = (value) => encodeURIComponent(value);
|
|
417
|
+
const formatters = {
|
|
418
|
+
br: toRounded,
|
|
419
|
+
d: toRounded,
|
|
420
|
+
bl: toHundred,
|
|
421
|
+
dl: toHundred,
|
|
422
|
+
mtp: toHundred,
|
|
423
|
+
nor: toUrlSafe,
|
|
424
|
+
rtp: toHundred,
|
|
425
|
+
tb: toRounded,
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
const keys = Object.keys(data || {}).sort();
|
|
429
|
+
|
|
430
|
+
for (const key of keys) {
|
|
431
|
+
let value = data[key];
|
|
432
|
+
|
|
433
|
+
// ignore invalid values
|
|
434
|
+
if (!isValid(value)) {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
// Version should only be reported if not equal to 1.
|
|
439
|
+
if (key === 'v' && value === 1) {
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Playback rate should only be sent if not equal to 1.
|
|
444
|
+
if (key == 'pr' && value === 1) {
|
|
445
|
+
continue;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Certain values require special formatting
|
|
449
|
+
const formatter = formatters[key];
|
|
450
|
+
if (formatter) {
|
|
451
|
+
value = formatter(value);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Serialize the key/value pair
|
|
455
|
+
const type = typeof value;
|
|
456
|
+
let result;
|
|
457
|
+
|
|
458
|
+
if (type === 'string' && key !== 'ot' && key !== 'sf' && key !== 'st') {
|
|
459
|
+
result = `${key}="${value.replace(/"/g, '"')}"`;
|
|
460
|
+
} else if (type === 'boolean') {
|
|
461
|
+
result = key;
|
|
462
|
+
} else if (type === 'symbol') {
|
|
463
|
+
result = `${key}=${value.description}`;
|
|
464
|
+
} else {
|
|
465
|
+
result = `${key}=${value}`;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
results.push(result);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
return results.join(',');
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/**
|
|
475
|
+
* Convert a CMCD data object to request headers according to the rules
|
|
476
|
+
* defined in the section 2.1 and 3.2 of
|
|
477
|
+
* [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
|
|
478
|
+
*
|
|
479
|
+
* @param {shaka.util.CmcdManager.Data} data The CMCD data object
|
|
480
|
+
* @return {!Object}
|
|
481
|
+
*/
|
|
482
|
+
static toHeaders(data) {
|
|
483
|
+
const keys = Object.keys(data);
|
|
484
|
+
const headers = {};
|
|
485
|
+
const headerNames = ['Object', 'Request', 'Session', 'Status'];
|
|
486
|
+
const headerGroups = [{}, {}, {}, {}];
|
|
487
|
+
const headerMap = {
|
|
488
|
+
br: 0, d: 0, ot: 0, tb: 0,
|
|
489
|
+
bl: 1, dl: 1, mtp: 1, nor: 1, nrr: 1, su: 1,
|
|
490
|
+
cid: 2, pr: 2, sf: 2, sid: 2, st: 2, v: 2,
|
|
491
|
+
bs: 3, rtp: 3,
|
|
492
|
+
};
|
|
493
|
+
|
|
494
|
+
for (const key of keys) {
|
|
495
|
+
// Unmapped fields are mapped to the Request header
|
|
496
|
+
const index = (headerMap[key] != null) ? headerMap[key] : 1;
|
|
497
|
+
headerGroups[index][key] = data[key];
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
for (let i = 0; i < headerGroups.length; i++) {
|
|
501
|
+
const value = shaka.util.CmcdManager.serialize(headerGroups[i]);
|
|
502
|
+
if (value) {
|
|
503
|
+
headers[`CMCD-${headerNames[i]}`] = value;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
return headers;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Convert a CMCD data object to query args according to the rules
|
|
512
|
+
* defined in the section 2.2 and 3.2 of
|
|
513
|
+
* [CTA-5004](https://cdn.cta.tech/cta/media/media/resources/standards/pdfs/cta-5004-final.pdf).
|
|
514
|
+
*
|
|
515
|
+
* @param {shaka.util.CmcdManager.Data} data The CMCD data object
|
|
516
|
+
* @return {string}
|
|
517
|
+
*/
|
|
518
|
+
static toQuery(data) {
|
|
519
|
+
return `CMCD=${encodeURIComponent(shaka.util.CmcdManager.serialize(data))}`;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Append query args to a uri.
|
|
524
|
+
*
|
|
525
|
+
* @param {string} uri
|
|
526
|
+
* @param {string} query
|
|
527
|
+
* @return {string}
|
|
528
|
+
*/
|
|
529
|
+
static appendQueryToUri(uri, query) {
|
|
530
|
+
if (!query) {
|
|
531
|
+
return uri;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (uri.includes('offline:')) {
|
|
535
|
+
return uri;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
const separator = uri.includes('?') ? '&' : '?';
|
|
539
|
+
return `${uri}${separator}${query}`;
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
/**
|
|
545
|
+
* @typedef {{
|
|
546
|
+
* getBandwidthEstimate: function():number,
|
|
547
|
+
* getBufferedInfo: function():shaka.extern.BufferedInfo,
|
|
548
|
+
* getCurrentTime: function():number,
|
|
549
|
+
* getManifest: function():shaka.extern.Manifest,
|
|
550
|
+
* getPlaybackRate: function():number,
|
|
551
|
+
* isLive: function():boolean
|
|
552
|
+
* }}
|
|
553
|
+
*
|
|
554
|
+
* @property {function():number} getBandwidthEstimate
|
|
555
|
+
* Get the estimated bandwidth in bits per second.
|
|
556
|
+
* @property {function():shaka.extern.BufferedInfo} getBufferedInfo
|
|
557
|
+
* Get information about what the player has buffered.
|
|
558
|
+
* @property {function():number} getCurrentTime
|
|
559
|
+
* Get the current time
|
|
560
|
+
* @property {function():shaka.extern.Manifest} getManifest
|
|
561
|
+
* Get the manifest
|
|
562
|
+
* @property {function():number} getPlaybackRate
|
|
563
|
+
* Get the playback rate
|
|
564
|
+
* @property {function():boolean} isLive
|
|
565
|
+
* Get if the player is playing live content.
|
|
566
|
+
*/
|
|
567
|
+
shaka.util.CmcdManager.PlayerInterface;
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @typedef {{
|
|
572
|
+
* type: string,
|
|
573
|
+
* init: boolean,
|
|
574
|
+
* duration: number,
|
|
575
|
+
* mimeType: string,
|
|
576
|
+
* codecs: string,
|
|
577
|
+
* bandwidth: (number|undefined)
|
|
578
|
+
* }}
|
|
579
|
+
*
|
|
580
|
+
* @property {string} type
|
|
581
|
+
* The media type
|
|
582
|
+
* @property {boolean} init
|
|
583
|
+
* Flag indicating whether the segment is an init segment
|
|
584
|
+
* @property {number} duration
|
|
585
|
+
* The duration of the segment in seconds
|
|
586
|
+
* @property {string} mimeType
|
|
587
|
+
* The segment's mime type
|
|
588
|
+
* @property {string} codecs
|
|
589
|
+
* The segment's codecs
|
|
590
|
+
* @property {(number|undefined)} bandwidth
|
|
591
|
+
* The segment's variation bandwidth
|
|
592
|
+
*
|
|
593
|
+
* @export
|
|
594
|
+
*/
|
|
595
|
+
shaka.util.CmcdManager.SegmentInfo;
|
|
596
|
+
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* @typedef {{
|
|
600
|
+
* format: shaka.util.CmcdManager.StreamingFormat
|
|
601
|
+
* }}
|
|
602
|
+
*
|
|
603
|
+
* @property {shaka.util.CmcdManager.StreamingFormat} format
|
|
604
|
+
* The manifest's stream format
|
|
605
|
+
*
|
|
606
|
+
* @export
|
|
607
|
+
*/
|
|
608
|
+
shaka.util.CmcdManager.ManifestInfo;
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* @typedef {{
|
|
613
|
+
* br: (number|undefined),
|
|
614
|
+
* d: (number|undefined),
|
|
615
|
+
* ot: (shaka.util.CmcdManager.ObjectType|undefined),
|
|
616
|
+
* tb: (number|undefined),
|
|
617
|
+
* bl: (number|undefined),
|
|
618
|
+
* dl: (number|undefined),
|
|
619
|
+
* mtp: (number|undefined),
|
|
620
|
+
* nor: (string|undefined),
|
|
621
|
+
* nrr: (string|undefined),
|
|
622
|
+
* su: (boolean|undefined),
|
|
623
|
+
* cid: (string|undefined),
|
|
624
|
+
* pr: (number|undefined),
|
|
625
|
+
* sf: (shaka.util.CmcdManager.StreamingFormat|undefined),
|
|
626
|
+
* sid: (string|undefined),
|
|
627
|
+
* st: (shaka.util.CmcdManager.StreamType|undefined),
|
|
628
|
+
* v: (number|undefined),
|
|
629
|
+
* bs: (boolean|undefined),
|
|
630
|
+
* rtp: (number|undefined)
|
|
631
|
+
* }}
|
|
632
|
+
*
|
|
633
|
+
* @description
|
|
634
|
+
* Client Media Common Data (CMCD) data.
|
|
635
|
+
*
|
|
636
|
+
* @property {number} br
|
|
637
|
+
* The encoded bitrate of the audio or video object being requested. This may
|
|
638
|
+
* not be known precisely by the player; however, it MAY be estimated based
|
|
639
|
+
* upon playlist/manifest declarations. If the playlist declares both peak and
|
|
640
|
+
* average bitrate values, the peak value should be transmitted.
|
|
641
|
+
*
|
|
642
|
+
* @property {number} d
|
|
643
|
+
* The playback duration in milliseconds of the object being requested. If a
|
|
644
|
+
* partial segment is being requested, then this value MUST indicate the
|
|
645
|
+
* playback duration of that part and not that of its parent segment. This
|
|
646
|
+
* value can be an approximation of the estimated duration if the explicit
|
|
647
|
+
* value is not known.
|
|
648
|
+
*
|
|
649
|
+
* @property {shaka.util.CmcdManager.ObjectType} ot
|
|
650
|
+
* The media type of the current object being requested:
|
|
651
|
+
* - `m` = text file, such as a manifest or playlist
|
|
652
|
+
* - `a` = audio only
|
|
653
|
+
* - `v` = video only
|
|
654
|
+
* - `av` = muxed audio and video
|
|
655
|
+
* - `i` = init segment
|
|
656
|
+
* - `c` = caption or subtitle
|
|
657
|
+
* - `tt` = ISOBMFF timed text track
|
|
658
|
+
* - `k` = cryptographic key, license or certificate.
|
|
659
|
+
* - `o` = other
|
|
660
|
+
*
|
|
661
|
+
* If the object type being requested is unknown, then this key MUST NOT be
|
|
662
|
+
* used.
|
|
663
|
+
*
|
|
664
|
+
* @property {number} tb
|
|
665
|
+
* The highest bitrate rendition in the manifest or playlist that the client
|
|
666
|
+
* is allowed to play, given current codec, licensing and sizing constraints.
|
|
667
|
+
*
|
|
668
|
+
* @property {number} bl
|
|
669
|
+
* The buffer length associated with the media object being requested. This
|
|
670
|
+
* value MUST be rounded to the nearest 100 ms. This key SHOULD only be sent
|
|
671
|
+
* with an object type of ‘a’, ‘v’ or ‘av’.
|
|
672
|
+
*
|
|
673
|
+
* @property {number} dl
|
|
674
|
+
* Deadline from the request time until the first sample of this
|
|
675
|
+
* Segment/Object needs to be available in order to not create a buffer
|
|
676
|
+
* underrun or any other playback problems. This value MUST be rounded to the
|
|
677
|
+
* nearest 100ms. For a playback rate of 1, this may be equivalent to the
|
|
678
|
+
* player’s remaining buffer length.
|
|
679
|
+
*
|
|
680
|
+
* @property {number} mtp
|
|
681
|
+
* The throughput between client and server, as measured by the client and
|
|
682
|
+
* MUST be rounded to the nearest 100 kbps. This value, however derived,
|
|
683
|
+
* SHOULD be the value that the client is using to make its next Adaptive
|
|
684
|
+
* Bitrate switching decision. If the client is connected to multiple
|
|
685
|
+
* servers concurrently, it must take care to report only the throughput
|
|
686
|
+
* measured against the receiving server. If the client has multiple
|
|
687
|
+
* concurrent connections to the server, then the intent is that this value
|
|
688
|
+
* communicates the aggregate throughput the client sees across all those
|
|
689
|
+
* connections.
|
|
690
|
+
*
|
|
691
|
+
* @property {string} nor
|
|
692
|
+
* Relative path of the next object to be requested. This can be used to
|
|
693
|
+
* trigger pre-fetching by the CDN. This MUST be a path relative to the
|
|
694
|
+
* current request. This string MUST be URLEncoded. The client SHOULD NOT
|
|
695
|
+
* depend upon any pre-fetch action being taken - it is merely a request for
|
|
696
|
+
* such a pre-fetch to take place.
|
|
697
|
+
*
|
|
698
|
+
* @property {string} nrr
|
|
699
|
+
* If the next request will be a partial object request, then this string
|
|
700
|
+
* denotes the byte range to be requested. If the ‘nor’ field is not set, then
|
|
701
|
+
* the object is assumed to match the object currently being requested. The
|
|
702
|
+
* client SHOULD NOT depend upon any pre-fetch action being taken – it is
|
|
703
|
+
* merely a request for such a pre-fetch to take place. Formatting is similar
|
|
704
|
+
* to the HTTP Range header, except that the unit MUST be ‘byte’, the ‘Range:’
|
|
705
|
+
* prefix is NOT required and specifying multiple ranges is NOT allowed. Valid
|
|
706
|
+
* combinations are:
|
|
707
|
+
*
|
|
708
|
+
* - `"\<range-start\>-"`
|
|
709
|
+
* - `"\<range-start\>-\<range-end\>"`
|
|
710
|
+
* - `"-\<suffix-length\>"`
|
|
711
|
+
*
|
|
712
|
+
* @property {boolean} su
|
|
713
|
+
* Key is included without a value if the object is needed urgently due to
|
|
714
|
+
* startup, seeking or recovery after a buffer-empty event. The media SHOULD
|
|
715
|
+
* not be rendering when this request is made. This key MUST not be sent if it
|
|
716
|
+
* is FALSE.
|
|
717
|
+
*
|
|
718
|
+
* @property {string} cid
|
|
719
|
+
* A unique string identifying the current content. Maximum length is 64
|
|
720
|
+
* characters. This value is consistent across multiple different sessions and
|
|
721
|
+
* devices and is defined and updated at the discretion of the service
|
|
722
|
+
* provider.
|
|
723
|
+
*
|
|
724
|
+
* @property {number} pr
|
|
725
|
+
* The playback rate. `1` if real-time, `2` if double speed, `0` if not
|
|
726
|
+
* playing. SHOULD only be sent if not equal to `1`.
|
|
727
|
+
*
|
|
728
|
+
* @property {shaka.util.CmcdManager.StreamingFormat} sf
|
|
729
|
+
* The streaming format that defines the current request.
|
|
730
|
+
*
|
|
731
|
+
* - `d` = MPEG DASH
|
|
732
|
+
* - `h` = HTTP Live Streaming (HLS)
|
|
733
|
+
* - `s` = Smooth Streaming
|
|
734
|
+
* - `o` = other
|
|
735
|
+
*
|
|
736
|
+
* If the streaming format being requested is unknown, then this key MUST NOT
|
|
737
|
+
* be used.
|
|
738
|
+
*
|
|
739
|
+
* @property {string} sid
|
|
740
|
+
* A GUID identifying the current playback session. A playback session
|
|
741
|
+
* typically ties together segments belonging to a single media asset. Maximum
|
|
742
|
+
* length is 64 characters. It is RECOMMENDED to conform to the UUID
|
|
743
|
+
* specification.
|
|
744
|
+
*
|
|
745
|
+
* @property {shaka.util.CmcdManager.StreamType} st
|
|
746
|
+
* Stream type
|
|
747
|
+
* - `v` = all segments are available – e.g., VOD
|
|
748
|
+
* - `l` = segments become available over time – e.g., LIVE
|
|
749
|
+
*
|
|
750
|
+
* @property {number} v
|
|
751
|
+
* The version of this specification used for interpreting the defined key
|
|
752
|
+
* names and values. If this key is omitted, the client and server MUST
|
|
753
|
+
* interpret the values as being defined by version 1. Client SHOULD omit this
|
|
754
|
+
* field if the version is 1.
|
|
755
|
+
*
|
|
756
|
+
* @property {boolean} bs
|
|
757
|
+
* Buffer starvation key is included without a value if the buffer was starved
|
|
758
|
+
* at some point between the prior request and this object request, resulting
|
|
759
|
+
* in the player being in a rebuffering state and the video or audio playback
|
|
760
|
+
* being stalled. This key MUST NOT be sent if the buffer was not starved
|
|
761
|
+
* since the prior request.
|
|
762
|
+
*
|
|
763
|
+
* If the object type `ot` key is sent along with this key, then the `bs` key
|
|
764
|
+
* refers to the buffer associated with the particular object type. If no
|
|
765
|
+
* object type is communicated, then the buffer state applies to the current
|
|
766
|
+
* session.
|
|
767
|
+
*
|
|
768
|
+
* @property {number} rtp
|
|
769
|
+
* Requested maximum throughput
|
|
770
|
+
*
|
|
771
|
+
* The requested maximum throughput that the client considers sufficient for
|
|
772
|
+
* delivery of the asset. Values MUST be rounded to the nearest 100kbps. For
|
|
773
|
+
* example, a client would indicate that the current segment, encoded at
|
|
774
|
+
* 2Mbps, is to be delivered at no more than 10Mbps, by using rtp=10000.
|
|
775
|
+
*
|
|
776
|
+
* Note: This can benefit clients by preventing buffer saturation through
|
|
777
|
+
* over-delivery and can also deliver a community benefit through fair-share
|
|
778
|
+
* delivery. The concept is that each client receives the throughput necessary
|
|
779
|
+
* for great performance, but no more. The CDN may not support the rtp
|
|
780
|
+
* feature.
|
|
781
|
+
*/
|
|
782
|
+
shaka.util.CmcdManager.Data;
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* @enum {string}
|
|
787
|
+
*/
|
|
788
|
+
shaka.util.CmcdManager.ObjectType = {
|
|
789
|
+
MANIFEST: 'm',
|
|
790
|
+
AUDIO: 'a',
|
|
791
|
+
VIDEO: 'v',
|
|
792
|
+
MUXED: 'av',
|
|
793
|
+
INIT: 'i',
|
|
794
|
+
CAPTION: 'c',
|
|
795
|
+
TIMED_TEXT: 'tt',
|
|
796
|
+
KEY: 'k',
|
|
797
|
+
OTHER: 'o',
|
|
798
|
+
};
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* @enum {string}
|
|
803
|
+
*/
|
|
804
|
+
shaka.util.CmcdManager.StreamType = {
|
|
805
|
+
VOD: 'v',
|
|
806
|
+
LIVE: 'l',
|
|
807
|
+
};
|
|
808
|
+
|
|
809
|
+
|
|
810
|
+
/**
|
|
811
|
+
* @enum {string}
|
|
812
|
+
* @export
|
|
813
|
+
*/
|
|
814
|
+
shaka.util.CmcdManager.StreamingFormat = {
|
|
815
|
+
DASH: 'd',
|
|
816
|
+
HLS: 'h',
|
|
817
|
+
SMOOTH: 's',
|
|
818
|
+
OTHER: 'o',
|
|
819
|
+
};
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
/**
|
|
823
|
+
* The CMCD spec version
|
|
824
|
+
* @const {number}
|
|
825
|
+
*/
|
|
826
|
+
shaka.util.CmcdManager.Version = 1;
|