shaka-player 4.12.8 → 4.13.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/AUTHORS +1 -0
- package/CONTRIBUTORS +4 -0
- package/README.md +22 -21
- package/cspell.config.yaml +18 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/deps.js +29 -24
- package/dist/locales.js +33 -33
- package/dist/shaka-player.compiled.d.ts +138 -36
- package/dist/shaka-player.compiled.debug.d.ts +138 -36
- package/dist/shaka-player.compiled.debug.externs.js +367 -107
- package/dist/shaka-player.compiled.debug.js +828 -765
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +367 -107
- package/dist/shaka-player.compiled.js +1451 -1416
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +172 -38
- package/dist/shaka-player.ui.debug.d.ts +172 -38
- package/dist/shaka-player.ui.debug.externs.js +406 -113
- package/dist/shaka-player.ui.debug.js +842 -766
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +406 -113
- package/dist/shaka-player.ui.js +1670 -1628
- package/dist/shaka-player.ui.map +4 -4
- package/eslint.config.mjs +343 -0
- package/externs/airplay.js +1 -1
- package/externs/audiotrack.js +1 -1
- package/externs/awesomplete.js +1 -1
- package/externs/cast-sdk-v2.js +2 -2
- package/externs/cmcd.js +16 -1
- package/externs/device_sensor_event.js +1 -1
- package/externs/ima.js +8 -8
- package/externs/isoboxer.js +31 -31
- package/externs/jwk_set.js +1 -1
- package/externs/lcevc.js +8 -8
- package/externs/mediakeys.js +1 -1
- package/externs/mediasession.js +3 -2
- package/externs/mediatailor.js +18 -18
- package/externs/pictureinpicture.js +41 -1
- package/externs/playstation.js +2 -2
- package/externs/prefixed_eme.js +1 -1
- package/externs/shaka/abortable.js +4 -4
- package/externs/shaka/abr_manager.js +1 -1
- package/externs/shaka/ads.js +45 -6
- package/externs/shaka/cea.js +2 -2
- package/externs/shaka/codecs.js +4 -4
- package/externs/shaka/drm_info.js +6 -6
- package/externs/shaka/error.js +5 -5
- package/externs/shaka/manifest.js +51 -56
- package/externs/shaka/manifest_parser.js +3 -9
- package/externs/shaka/net.js +23 -20
- package/externs/shaka/offline.js +37 -37
- package/externs/shaka/offline_compat_v1.js +10 -10
- package/externs/shaka/offline_compat_v2.js +10 -10
- package/externs/shaka/player.js +139 -109
- package/externs/shaka/text.js +10 -3
- package/externs/shaka/transmuxer.js +1 -1
- package/externs/videotrack.js +1 -1
- package/lib/abr/ewma.js +1 -1
- package/lib/abr/simple_abr_manager.js +70 -22
- package/lib/ads/ad_manager.js +43 -18
- package/lib/ads/ad_utils.js +160 -58
- package/lib/ads/ads_stats.js +1 -1
- package/lib/ads/client_side_ad_manager.js +2 -2
- package/lib/ads/interstitial_ad.js +16 -11
- package/lib/ads/interstitial_ad_manager.js +419 -72
- package/lib/ads/interstitial_static_ad.js +299 -0
- package/lib/ads/media_tailor_ad.js +1 -0
- package/lib/ads/media_tailor_ad_manager.js +37 -36
- package/lib/ads/server_side_ad_manager.js +7 -6
- package/lib/cast/cast_receiver.js +5 -3
- package/lib/cast/cast_sender.js +2 -2
- package/lib/cast/cast_utils.js +20 -13
- package/lib/cea/cea608_data_channel.js +53 -53
- package/lib/cea/cea708_service.js +42 -40
- package/lib/cea/cea708_window.js +5 -2
- package/lib/cea/cea_decoder.js +5 -7
- package/lib/cea/mp4_cea_parser.js +1 -1
- package/lib/cea/sei_processor.js +1 -1
- package/lib/dash/content_protection.js +62 -192
- package/lib/dash/dash_parser.js +119 -119
- package/lib/dash/mpd_utils.js +14 -13
- package/lib/dash/segment_base.js +5 -5
- package/lib/dash/segment_list.js +10 -10
- package/lib/dash/segment_template.js +55 -53
- package/lib/debug/log.js +2 -2
- package/lib/dependencies/all.js +2 -1
- package/lib/{media → drm}/drm_engine.js +274 -143
- package/lib/{util → drm}/drm_utils.js +20 -11
- package/lib/drm/playready.js +233 -0
- package/lib/hls/hls_classes.js +14 -14
- package/lib/hls/hls_parser.js +257 -196
- package/lib/hls/hls_utils.js +14 -14
- package/lib/hls/manifest_text_parser.js +10 -10
- package/lib/media/adaptation_set.js +6 -5
- package/lib/media/adaptation_set_criteria.js +51 -379
- package/lib/media/buffering_observer.js +5 -4
- package/lib/media/closed_caption_parser.js +2 -2
- package/lib/media/content_workarounds.js +2 -2
- package/lib/media/example_based_criteria.js +69 -0
- package/lib/media/gap_jumping_controller.js +14 -1
- package/lib/media/manifest_filterer.js +8 -8
- package/lib/media/manifest_parser.js +2 -2
- package/lib/media/media_source_capabilities.js +20 -1
- package/lib/media/media_source_engine.js +84 -35
- package/lib/media/mp4_segment_index_parser.js +5 -5
- package/lib/media/playhead.js +2 -8
- package/lib/media/playhead_observer.js +1 -1
- package/lib/media/preference_based_criteria.js +333 -0
- package/lib/media/preload_manager.js +53 -37
- package/lib/media/presentation_timeline.js +2 -2
- package/lib/media/quality_observer.js +35 -35
- package/lib/media/region_observer.js +2 -2
- package/lib/media/region_timeline.js +3 -3
- package/lib/media/segment_index.js +14 -14
- package/lib/media/segment_prefetch.js +17 -13
- package/lib/media/segment_reference.js +7 -7
- package/lib/media/segment_utils.js +9 -9
- package/lib/media/streaming_engine.js +77 -38
- package/lib/media/time_ranges_utils.js +1 -1
- package/lib/media/video_wrapper.js +1 -1
- package/lib/media/webm_segment_index_parser.js +4 -4
- package/lib/mss/content_protection.js +17 -222
- package/lib/mss/mss_parser.js +23 -24
- package/lib/net/data_uri_plugin.js +1 -0
- package/lib/net/http_fetch_plugin.js +8 -7
- package/lib/net/http_plugin_utils.js +5 -2
- package/lib/net/http_xhr_plugin.js +4 -3
- package/lib/net/networking_engine.js +72 -17
- package/lib/net/networking_utils.js +5 -2
- package/lib/offline/download_info.js +5 -1
- package/lib/offline/download_manager.js +15 -4
- package/lib/offline/download_progress_estimator.js +1 -1
- package/lib/offline/indexeddb/base_storage_cell.js +9 -9
- package/lib/offline/indexeddb/db_connection.js +1 -1
- package/lib/offline/indexeddb/db_operation.js +2 -2
- package/lib/offline/indexeddb/eme_session_storage_cell.js +1 -1
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v1_storage_cell.js +3 -3
- package/lib/offline/indexeddb/v2_storage_cell.js +2 -2
- package/lib/offline/manifest_converter.js +11 -12
- package/lib/offline/offline_scheme.js +8 -4
- package/lib/offline/session_deleter.js +11 -11
- package/lib/offline/storage.js +137 -88
- package/lib/offline/storage_muxer.js +8 -8
- package/lib/offline/stored_content_utils.js +3 -3
- package/lib/offline/stream_bandwidth_estimator.js +1 -1
- package/lib/player.js +291 -207
- package/lib/polyfill/all.js +1 -1
- package/lib/polyfill/media_capabilities.js +5 -5
- package/lib/polyfill/patchedmediakeys_apple.js +6 -6
- package/lib/polyfill/patchedmediakeys_webkit.js +8 -8
- package/lib/polyfill/video_play_promise.js +0 -1
- package/lib/text/cue.js +3 -2
- package/lib/text/lrc_text_parser.js +1 -1
- package/lib/text/mp4_ttml_parser.js +1 -1
- package/lib/text/mp4_vtt_parser.js +3 -3
- package/lib/text/sbv_text_parser.js +1 -1
- package/lib/text/simple_text_displayer.js +37 -10
- package/lib/text/ssa_text_parser.js +3 -1
- package/lib/text/stub_text_displayer.js +12 -5
- package/lib/text/text_engine.js +5 -4
- package/lib/text/text_utils.js +4 -4
- package/lib/text/ttml_text_parser.js +21 -20
- package/lib/text/ui_text_displayer.js +20 -13
- package/lib/text/vtt_text_parser.js +10 -10
- package/lib/text/web_vtt_generator.js +2 -2
- package/lib/transmuxer/aac_transmuxer.js +2 -2
- package/lib/transmuxer/ac3_transmuxer.js +2 -2
- package/lib/transmuxer/adts.js +2 -0
- package/lib/transmuxer/ec3.js +3 -3
- package/lib/transmuxer/ec3_transmuxer.js +2 -2
- package/lib/transmuxer/h264.js +5 -5
- package/lib/transmuxer/h265.js +3 -3
- package/lib/transmuxer/mp3_transmuxer.js +2 -2
- package/lib/transmuxer/mpeg_audio.js +6 -6
- package/lib/transmuxer/mss_transmuxer.js +2 -0
- package/lib/transmuxer/transmuxer_engine.js +1 -1
- package/lib/transmuxer/ts_transmuxer.js +10 -10
- package/lib/util/abortable_operation.js +10 -10
- package/lib/util/array_utils.js +6 -6
- package/lib/util/cmcd_manager.js +149 -18
- package/lib/util/cmsd_manager.js +11 -11
- package/lib/util/config_utils.js +3 -3
- package/lib/util/content_steering_manager.js +17 -17
- package/lib/util/data_view_reader.js +3 -3
- package/lib/util/ebml_parser.js +1 -1
- package/lib/util/error.js +11 -6
- package/lib/util/event_manager.js +1 -1
- package/lib/util/exp_golomb.js +1 -1
- package/lib/util/fairplay_utils.js +6 -1
- package/lib/util/fake_event.js +3 -2
- package/lib/util/fake_event_target.js +1 -1
- package/lib/util/functional.js +8 -8
- package/lib/util/id3_utils.js +1 -1
- package/lib/util/iterables.js +6 -6
- package/lib/util/language_utils.js +17 -17
- package/lib/util/manifest_parser_utils.js +13 -13
- package/lib/util/map_utils.js +6 -6
- package/lib/util/media_ready_state_utils.js +1 -1
- package/lib/util/mime_utils.js +15 -4
- package/lib/util/mp4_box_parsers.js +5 -5
- package/lib/util/mp4_generator.js +31 -30
- package/lib/util/mp4_parser.js +2 -2
- package/lib/util/multi_map.js +5 -5
- package/lib/util/mutex.js +1 -1
- package/lib/util/networking.js +1 -1
- package/lib/util/object_utils.js +5 -1
- package/lib/util/operation_manager.js +1 -1
- package/lib/util/periods.js +24 -24
- package/lib/util/platform.js +8 -4
- package/lib/util/player_configuration.js +50 -17
- package/lib/util/pssh.js +34 -6
- package/lib/util/public_promise.js +2 -2
- package/lib/util/state_history.js +2 -2
- package/lib/util/stream_utils.js +138 -120
- package/lib/util/string_utils.js +4 -3
- package/lib/util/switch_history.js +2 -2
- package/lib/util/tXml.js +22 -17
- package/lib/util/text_parser.js +2 -2
- package/lib/util/timer.js +1 -1
- package/lib/util/ts_parser.js +22 -22
- package/lib/util/xml_utils.js +1 -0
- package/package.json +7 -4
- package/project-words.txt +485 -0
- package/shaka-player.uncompiled.js +1 -1
- package/third_party/closure-uri/uri.js +2 -2
- package/third_party/closure-uri/utils.js +2 -2
- package/third_party/language-mapping-list/language-mapping-list.js +1 -1
- package/ui/ad_statistics_button.js +9 -5
- package/ui/airplay_button.js +1 -0
- package/ui/audio_language_selection.js +2 -1
- package/ui/context_menu.js +2 -2
- package/ui/controls.js +7 -7
- package/ui/externs/ui.js +29 -21
- package/ui/externs/watermark.js +64 -0
- package/ui/fast_forward_button.js +1 -1
- package/ui/gl_matrix/matrix_4x4.js +11 -5
- package/ui/hidden_fast_forward_button.js +1 -1
- package/ui/hidden_seek_button.js +1 -1
- package/ui/language_utils.js +27 -26
- package/ui/less/buttons.less +2 -2
- package/ui/localization.js +21 -21
- package/ui/loop_button.js +2 -2
- package/ui/overflow_menu.js +2 -2
- package/ui/playback_rate_selection.js +1 -1
- package/ui/presentation_time.js +4 -1
- package/ui/range_element.js +2 -2
- package/ui/resolution_selection.js +42 -6
- package/ui/rewind_button.js +1 -1
- package/ui/seek_bar.js +5 -5
- package/ui/statistics_button.js +8 -4
- package/ui/text_selection.js +3 -2
- package/ui/ui.js +32 -2
- package/ui/vr_manager.js +3 -3
- package/ui/vr_utils.js +14 -14
- package/ui/vr_webgl.js +5 -5
- package/ui/watermark.js +313 -0
- package/.eslintignore +0 -4
- package/.eslintrc.js +0 -310
- package/lib/polyfill/patchedmediakeys_nop.js +0 -148
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
goog.provide('shaka.
|
|
7
|
+
goog.provide('shaka.drm.DrmUtils');
|
|
8
8
|
|
|
9
9
|
goog.require('shaka.util.BufferUtils');
|
|
10
10
|
goog.require('shaka.util.Lazy');
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
shaka.
|
|
13
|
+
shaka.drm.DrmUtils = class {
|
|
14
14
|
/**
|
|
15
15
|
* Returns true if the browser has recent EME APIs.
|
|
16
16
|
*
|
|
@@ -45,7 +45,7 @@ shaka.util.DrmUtils = class {
|
|
|
45
45
|
return true;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
return shaka.
|
|
48
|
+
return shaka.drm.DrmUtils.getCommonDrmInfos(
|
|
49
49
|
drms1, drms2).length > 0;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -108,7 +108,8 @@ shaka.util.DrmUtils = class {
|
|
|
108
108
|
|
|
109
109
|
/**
|
|
110
110
|
* @param {?shaka.extern.DrmInfo} drmInfo
|
|
111
|
-
* @return {string}
|
|
111
|
+
* @return {string}
|
|
112
|
+
*/
|
|
112
113
|
static keySystem(drmInfo) {
|
|
113
114
|
return drmInfo ? drmInfo.keySystem : '';
|
|
114
115
|
}
|
|
@@ -157,6 +158,14 @@ shaka.util.DrmUtils = class {
|
|
|
157
158
|
return false;
|
|
158
159
|
}
|
|
159
160
|
|
|
161
|
+
/**
|
|
162
|
+
* @param {?string} keySystem
|
|
163
|
+
* @return {boolean}
|
|
164
|
+
*/
|
|
165
|
+
static isWisePlayKeySystem(keySystem) {
|
|
166
|
+
return keySystem === 'com.huawei.wiseplay';
|
|
167
|
+
}
|
|
168
|
+
|
|
160
169
|
/**
|
|
161
170
|
* A method for generating a key for the MediaKeySystemAccessRequests cache.
|
|
162
171
|
*
|
|
@@ -180,7 +189,7 @@ shaka.util.DrmUtils = class {
|
|
|
180
189
|
* @return {boolean}
|
|
181
190
|
*/
|
|
182
191
|
static hasMediaKeySystemAccess(videoCodec, audioCodec, keySystem) {
|
|
183
|
-
const DrmUtils = shaka.
|
|
192
|
+
const DrmUtils = shaka.drm.DrmUtils;
|
|
184
193
|
const key = DrmUtils.generateKeySystemCacheKey_(
|
|
185
194
|
videoCodec, audioCodec, keySystem);
|
|
186
195
|
return DrmUtils.memoizedMediaKeySystemAccessRequests_.has(key);
|
|
@@ -195,7 +204,7 @@ shaka.util.DrmUtils = class {
|
|
|
195
204
|
* @return {?MediaKeySystemAccess}
|
|
196
205
|
*/
|
|
197
206
|
static getMediaKeySystemAccess(videoCodec, audioCodec, keySystem) {
|
|
198
|
-
const DrmUtils = shaka.
|
|
207
|
+
const DrmUtils = shaka.drm.DrmUtils;
|
|
199
208
|
const key = DrmUtils.generateKeySystemCacheKey_(
|
|
200
209
|
videoCodec, audioCodec, keySystem);
|
|
201
210
|
return DrmUtils.memoizedMediaKeySystemAccessRequests_.get(key) || null;
|
|
@@ -210,17 +219,17 @@ shaka.util.DrmUtils = class {
|
|
|
210
219
|
* @param {!MediaKeySystemAccess} mksa
|
|
211
220
|
*/
|
|
212
221
|
static setMediaKeySystemAccess(videoCodec, audioCodec, keySystem, mksa) {
|
|
213
|
-
const DrmUtils = shaka.
|
|
222
|
+
const DrmUtils = shaka.drm.DrmUtils;
|
|
214
223
|
const key = DrmUtils.generateKeySystemCacheKey_(
|
|
215
224
|
videoCodec, audioCodec, keySystem);
|
|
216
|
-
|
|
225
|
+
DrmUtils.memoizedMediaKeySystemAccessRequests_.set(key, mksa);
|
|
217
226
|
}
|
|
218
227
|
|
|
219
228
|
/**
|
|
220
229
|
* Clears underlying cache.
|
|
221
230
|
*/
|
|
222
231
|
static clearMediaKeySystemAccessMap() {
|
|
223
|
-
const DrmUtils = shaka.
|
|
232
|
+
const DrmUtils = shaka.drm.DrmUtils;
|
|
224
233
|
DrmUtils.memoizedMediaKeySystemAccessRequests_.clear();
|
|
225
234
|
}
|
|
226
235
|
};
|
|
@@ -231,7 +240,7 @@ shaka.util.DrmUtils = class {
|
|
|
231
240
|
* have a per-key key status. See w3c/encrypted-media#32.
|
|
232
241
|
* @type {!shaka.util.Lazy<!ArrayBuffer>}
|
|
233
242
|
*/
|
|
234
|
-
shaka.
|
|
243
|
+
shaka.drm.DrmUtils.DUMMY_KEY_ID = new shaka.util.Lazy(
|
|
235
244
|
() => shaka.util.BufferUtils.toArrayBuffer(new Uint8Array([0])));
|
|
236
245
|
|
|
237
246
|
|
|
@@ -242,4 +251,4 @@ shaka.util.DrmUtils.DUMMY_KEY_ID = new shaka.util.Lazy(
|
|
|
242
251
|
*
|
|
243
252
|
* @private {!Map<string, !MediaKeySystemAccess>}
|
|
244
253
|
*/
|
|
245
|
-
shaka.
|
|
254
|
+
shaka.drm.DrmUtils.memoizedMediaKeySystemAccessRequests_ = new Map();
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
goog.provide('shaka.drm.PlayReady');
|
|
8
|
+
|
|
9
|
+
goog.require('shaka.log');
|
|
10
|
+
goog.require('shaka.util.BufferUtils');
|
|
11
|
+
goog.require('shaka.util.StringUtils');
|
|
12
|
+
goog.require('shaka.util.TXml');
|
|
13
|
+
goog.require('shaka.util.Uint8ArrayUtils');
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @summary A set of functions for parsing Microsoft Playready Objects.
|
|
18
|
+
*/
|
|
19
|
+
shaka.drm.PlayReady = class {
|
|
20
|
+
/**
|
|
21
|
+
* Parses an Array buffer starting at byteOffset for PlayReady Object Records.
|
|
22
|
+
* Each PRO Record is preceded by its PlayReady Record type and length in
|
|
23
|
+
* bytes.
|
|
24
|
+
*
|
|
25
|
+
* PlayReady Object Record format: https://goo.gl/FTcu46
|
|
26
|
+
*
|
|
27
|
+
* @param {!DataView} view
|
|
28
|
+
* @param {number} byteOffset
|
|
29
|
+
* @return {!Array<shaka.drm.PlayReady.PlayReadyRecord>}
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
32
|
+
static parseMsProRecords_(view, byteOffset) {
|
|
33
|
+
const records = [];
|
|
34
|
+
|
|
35
|
+
while (byteOffset < view.byteLength - 1) {
|
|
36
|
+
const type = view.getUint16(byteOffset, true);
|
|
37
|
+
byteOffset += 2;
|
|
38
|
+
|
|
39
|
+
const byteLength = view.getUint16(byteOffset, true);
|
|
40
|
+
byteOffset += 2;
|
|
41
|
+
|
|
42
|
+
if ((byteLength & 1) != 0 || byteLength + byteOffset > view.byteLength) {
|
|
43
|
+
shaka.log.warning('Malformed MS PRO object');
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const recordValue = shaka.util.BufferUtils.toUint8(
|
|
48
|
+
view, byteOffset, byteLength);
|
|
49
|
+
records.push({
|
|
50
|
+
type: type,
|
|
51
|
+
value: recordValue,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
byteOffset += byteLength;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return records;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Parses a buffer for PlayReady Objects. The data
|
|
62
|
+
* should contain a 32-bit integer indicating the length of
|
|
63
|
+
* the PRO in bytes. Following that, a 16-bit integer for
|
|
64
|
+
* the number of PlayReady Object Records in the PRO. Lastly,
|
|
65
|
+
* a byte array of the PRO Records themselves.
|
|
66
|
+
*
|
|
67
|
+
* PlayReady Object format: https://goo.gl/W8yAN4
|
|
68
|
+
*
|
|
69
|
+
* @param {BufferSource} data
|
|
70
|
+
* @return {!Array<shaka.drm.PlayReady.PlayReadyRecord>}
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
static parseMsPro_(data) {
|
|
74
|
+
let byteOffset = 0;
|
|
75
|
+
const view = shaka.util.BufferUtils.toDataView(data);
|
|
76
|
+
|
|
77
|
+
// First 4 bytes is the PRO length (DWORD)
|
|
78
|
+
const byteLength = view.getUint32(byteOffset, /* littleEndian= */ true);
|
|
79
|
+
byteOffset += 4;
|
|
80
|
+
|
|
81
|
+
if (byteLength != data.byteLength) {
|
|
82
|
+
// Malformed PRO
|
|
83
|
+
shaka.log.warning('PlayReady Object with invalid length encountered.');
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Skip PRO Record count (WORD)
|
|
88
|
+
byteOffset += 2;
|
|
89
|
+
|
|
90
|
+
// Rest of the data contains the PRO Records
|
|
91
|
+
return shaka.drm.PlayReady.parseMsProRecords_(view, byteOffset);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* PlayReady Header format: https://goo.gl/dBzxNA
|
|
96
|
+
*
|
|
97
|
+
* @param {!shaka.extern.xml.Node} xml
|
|
98
|
+
* @return {string}
|
|
99
|
+
* @private
|
|
100
|
+
*/
|
|
101
|
+
static getLaurl_(xml) {
|
|
102
|
+
const TXml = shaka.util.TXml;
|
|
103
|
+
// LA_URL element is optional and no more than one is
|
|
104
|
+
// allowed inside the DATA element. Only absolute URLs are allowed.
|
|
105
|
+
// If the LA_URL element exists, it must not be empty.
|
|
106
|
+
for (const elem of TXml.getElementsByTagName(xml, 'DATA')) {
|
|
107
|
+
if (elem.children) {
|
|
108
|
+
for (const child of elem.children) {
|
|
109
|
+
if (child.tagName == 'LA_URL') {
|
|
110
|
+
return /** @type {string} */(
|
|
111
|
+
shaka.util.TXml.getTextContents(child));
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Not found
|
|
118
|
+
return '';
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Gets a PlayReady Header Object
|
|
123
|
+
*
|
|
124
|
+
* @param {!shaka.extern.xml.Node} element
|
|
125
|
+
* @return {?shaka.extern.xml.Node}
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
128
|
+
static getPlayReadyHeaderObject_(element) {
|
|
129
|
+
const PLAYREADY_RECORD_TYPES = shaka.drm.PlayReady.PLAYREADY_RECORD_TYPES;
|
|
130
|
+
|
|
131
|
+
const bytes = shaka.util.Uint8ArrayUtils.fromBase64(
|
|
132
|
+
/** @type {string} */ (shaka.util.TXml.getTextContents(element)));
|
|
133
|
+
const records = shaka.drm.PlayReady.parseMsPro_(bytes);
|
|
134
|
+
const record = records.filter((record) => {
|
|
135
|
+
return record.type === PLAYREADY_RECORD_TYPES.RIGHTS_MANAGEMENT;
|
|
136
|
+
})[0];
|
|
137
|
+
|
|
138
|
+
if (!record) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const xml = shaka.util.StringUtils.fromUTF16(record.value, true);
|
|
143
|
+
const rootElement = shaka.util.TXml.parseXmlString(xml, 'WRMHEADER');
|
|
144
|
+
if (!rootElement) {
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
return rootElement;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Gets a PlayReady license URL from a PlayReady Header Object
|
|
152
|
+
*
|
|
153
|
+
* @param {!shaka.extern.xml.Node} element
|
|
154
|
+
* @return {string}
|
|
155
|
+
*/
|
|
156
|
+
static getLicenseUrl(element) {
|
|
157
|
+
try {
|
|
158
|
+
const headerObject =
|
|
159
|
+
shaka.drm.PlayReady.getPlayReadyHeaderObject_(element);
|
|
160
|
+
if (!headerObject) {
|
|
161
|
+
return '';
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return shaka.drm.PlayReady.getLaurl_(headerObject);
|
|
165
|
+
} catch (e) {
|
|
166
|
+
return '';
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Gets a PlayReady KID from a protection element containing a
|
|
172
|
+
* PlayReady Header Object
|
|
173
|
+
*
|
|
174
|
+
* @param {!shaka.extern.xml.Node} element
|
|
175
|
+
* @return {?string}
|
|
176
|
+
*/
|
|
177
|
+
static getPlayReadyKID(element) {
|
|
178
|
+
const rootElement = shaka.drm.PlayReady.getPlayReadyHeaderObject_(element);
|
|
179
|
+
if (!rootElement) {
|
|
180
|
+
return null;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const TXml = shaka.util.TXml;
|
|
184
|
+
// KID element is optional and no more than one is
|
|
185
|
+
// allowed inside the DATA element.
|
|
186
|
+
for (const elem of TXml.getElementsByTagName(rootElement, 'DATA')) {
|
|
187
|
+
const kid = TXml.findChild(elem, 'KID');
|
|
188
|
+
if (kid) {
|
|
189
|
+
// GUID: [DWORD, WORD, WORD, 8-BYTE]
|
|
190
|
+
const guidBytes =
|
|
191
|
+
shaka.util.Uint8ArrayUtils.fromBase64(
|
|
192
|
+
/** @type {string} */ (shaka.util.TXml.getTextContents(kid)));
|
|
193
|
+
// Reverse byte order from little-endian to big-endian
|
|
194
|
+
const kidBytes = new Uint8Array([
|
|
195
|
+
guidBytes[3], guidBytes[2], guidBytes[1], guidBytes[0],
|
|
196
|
+
guidBytes[5], guidBytes[4],
|
|
197
|
+
guidBytes[7], guidBytes[6],
|
|
198
|
+
...guidBytes.slice(8),
|
|
199
|
+
]);
|
|
200
|
+
return shaka.util.Uint8ArrayUtils.toHex(kidBytes);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Not found
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @typedef {{
|
|
211
|
+
* type: number,
|
|
212
|
+
* value: !Uint8Array
|
|
213
|
+
* }}
|
|
214
|
+
*
|
|
215
|
+
* @description
|
|
216
|
+
* The parsed result of a PlayReady object record.
|
|
217
|
+
*
|
|
218
|
+
* @property {number} type
|
|
219
|
+
* Type of data stored in the record.
|
|
220
|
+
* @property {!Uint8Array} value
|
|
221
|
+
* Record content.
|
|
222
|
+
*/
|
|
223
|
+
shaka.drm.PlayReady.PlayReadyRecord;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Enum for PlayReady record types.
|
|
227
|
+
* @enum {number}
|
|
228
|
+
*/
|
|
229
|
+
shaka.drm.PlayReady.PLAYREADY_RECORD_TYPES = {
|
|
230
|
+
RIGHTS_MANAGEMENT: 0x001,
|
|
231
|
+
RESERVED: 0x002,
|
|
232
|
+
EMBEDDED_LICENSE: 0x003,
|
|
233
|
+
};
|
package/lib/hls/hls_classes.js
CHANGED
|
@@ -20,17 +20,17 @@ goog.require('shaka.util.Error');
|
|
|
20
20
|
shaka.hls.Playlist = class {
|
|
21
21
|
/**
|
|
22
22
|
* @param {!shaka.hls.PlaylistType} type
|
|
23
|
-
* @param {!Array
|
|
24
|
-
* @param {!Array
|
|
23
|
+
* @param {!Array<shaka.hls.Tag>} tags
|
|
24
|
+
* @param {!Array<shaka.hls.Segment>=} segments
|
|
25
25
|
*/
|
|
26
26
|
constructor(type, tags, segments) {
|
|
27
27
|
/** @const {shaka.hls.PlaylistType} */
|
|
28
28
|
this.type = type;
|
|
29
29
|
|
|
30
|
-
/** @const {!Array
|
|
30
|
+
/** @const {!Array<!shaka.hls.Tag>} */
|
|
31
31
|
this.tags = tags;
|
|
32
32
|
|
|
33
|
-
/** @const {Array
|
|
33
|
+
/** @const {Array<!shaka.hls.Segment>} */
|
|
34
34
|
this.segments = segments || null;
|
|
35
35
|
}
|
|
36
36
|
};
|
|
@@ -52,7 +52,7 @@ shaka.hls.Tag = class {
|
|
|
52
52
|
/**
|
|
53
53
|
* @param {number} id
|
|
54
54
|
* @param {string} name
|
|
55
|
-
* @param {!Array
|
|
55
|
+
* @param {!Array<shaka.hls.Attribute>} attributes
|
|
56
56
|
* @param {?string=} value
|
|
57
57
|
*/
|
|
58
58
|
constructor(id, name, attributes, value = null) {
|
|
@@ -62,7 +62,7 @@ shaka.hls.Tag = class {
|
|
|
62
62
|
/** @type {string} */
|
|
63
63
|
this.name = name;
|
|
64
64
|
|
|
65
|
-
/** @const {!Array
|
|
65
|
+
/** @const {!Array<shaka.hls.Attribute>} */
|
|
66
66
|
this.attributes = attributes;
|
|
67
67
|
|
|
68
68
|
/** @const {?string} */
|
|
@@ -78,7 +78,7 @@ shaka.hls.Tag = class {
|
|
|
78
78
|
* As in some cases (like in tests) the tag never existed in string form, it
|
|
79
79
|
* is far easier to recreate the tag from the parsed form.
|
|
80
80
|
*
|
|
81
|
-
* @param {?Set
|
|
81
|
+
* @param {?Set<string>=} attributesToSkip
|
|
82
82
|
* @return {string}
|
|
83
83
|
* @override
|
|
84
84
|
*/
|
|
@@ -120,11 +120,11 @@ shaka.hls.Tag = class {
|
|
|
120
120
|
/**
|
|
121
121
|
* Create the string key of the tag.
|
|
122
122
|
*
|
|
123
|
-
* @param {boolean}
|
|
123
|
+
* @param {boolean} keepAllAttributes
|
|
124
124
|
* @return {string}
|
|
125
125
|
*/
|
|
126
|
-
getTagKey(
|
|
127
|
-
if (
|
|
126
|
+
getTagKey(keepAllAttributes) {
|
|
127
|
+
if (keepAllAttributes) {
|
|
128
128
|
return this.toString();
|
|
129
129
|
}
|
|
130
130
|
const attributesToSkip = new Set()
|
|
@@ -221,17 +221,17 @@ shaka.hls.Segment = class {
|
|
|
221
221
|
* Creates an HLS segment object.
|
|
222
222
|
*
|
|
223
223
|
* @param {string} verbatimSegmentUri verbatim segment URI.
|
|
224
|
-
* @param {!Array
|
|
225
|
-
* @param {!Array
|
|
224
|
+
* @param {!Array<shaka.hls.Tag>} tags
|
|
225
|
+
* @param {!Array<shaka.hls.Tag>=} partialSegments
|
|
226
226
|
*/
|
|
227
227
|
constructor(verbatimSegmentUri, tags, partialSegments=[]) {
|
|
228
|
-
/** @const {!Array
|
|
228
|
+
/** @const {!Array<shaka.hls.Tag>} */
|
|
229
229
|
this.tags = tags;
|
|
230
230
|
|
|
231
231
|
/** @const {?string} */
|
|
232
232
|
this.verbatimSegmentUri = verbatimSegmentUri;
|
|
233
233
|
|
|
234
|
-
/** @type {!Array
|
|
234
|
+
/** @type {!Array<shaka.hls.Tag>} */
|
|
235
235
|
this.partialSegments = partialSegments;
|
|
236
236
|
}
|
|
237
237
|
};
|