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
|
@@ -6,11 +6,9 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.mss.ContentProtection');
|
|
8
8
|
|
|
9
|
-
goog.require('shaka.
|
|
10
|
-
goog.require('shaka.util.BufferUtils');
|
|
9
|
+
goog.require('shaka.drm.PlayReady');
|
|
11
10
|
goog.require('shaka.util.ManifestParserUtils');
|
|
12
11
|
goog.require('shaka.util.Pssh');
|
|
13
|
-
goog.require('shaka.util.StringUtils');
|
|
14
12
|
goog.require('shaka.util.TXml');
|
|
15
13
|
goog.require('shaka.util.Uint8ArrayUtils');
|
|
16
14
|
|
|
@@ -23,19 +21,19 @@ shaka.mss.ContentProtection = class {
|
|
|
23
21
|
/**
|
|
24
22
|
* Parses info from the Protection elements.
|
|
25
23
|
*
|
|
26
|
-
* @param {!Array
|
|
27
|
-
* @param {!Object
|
|
28
|
-
* @return {!Array
|
|
24
|
+
* @param {!Array<!shaka.extern.xml.Node>} elements
|
|
25
|
+
* @param {!Object<string, string>} keySystemsBySystemId
|
|
26
|
+
* @return {!Array<shaka.extern.DrmInfo>}
|
|
29
27
|
*/
|
|
30
|
-
static parseFromProtection(
|
|
28
|
+
static parseFromProtection(elements, keySystemsBySystemId) {
|
|
31
29
|
const ContentProtection = shaka.mss.ContentProtection;
|
|
32
30
|
const TXml = shaka.util.TXml;
|
|
33
31
|
|
|
34
|
-
/** @type {!Array
|
|
32
|
+
/** @type {!Array<!shaka.extern.xml.Node>} */
|
|
35
33
|
let protectionHeader = [];
|
|
36
|
-
for (const
|
|
34
|
+
for (const element of elements) {
|
|
37
35
|
protectionHeader = protectionHeader.concat(
|
|
38
|
-
TXml.findChildren(
|
|
36
|
+
TXml.findChildren(element, 'ProtectionHeader'));
|
|
39
37
|
}
|
|
40
38
|
if (!protectionHeader.length) {
|
|
41
39
|
return [];
|
|
@@ -44,107 +42,6 @@ shaka.mss.ContentProtection = class {
|
|
|
44
42
|
protectionHeader, keySystemsBySystemId);
|
|
45
43
|
}
|
|
46
44
|
|
|
47
|
-
/**
|
|
48
|
-
* Parses an Array buffer starting at byteOffset for PlayReady Object Records.
|
|
49
|
-
* Each PRO Record is preceded by its PlayReady Record type and length in
|
|
50
|
-
* bytes.
|
|
51
|
-
*
|
|
52
|
-
* PlayReady Object Record format: https://goo.gl/FTcu46
|
|
53
|
-
*
|
|
54
|
-
* @param {!DataView} view
|
|
55
|
-
* @param {number} byteOffset
|
|
56
|
-
* @return {!Array.<shaka.mss.ContentProtection.PlayReadyRecord>}
|
|
57
|
-
* @private
|
|
58
|
-
*/
|
|
59
|
-
static parseMsProRecords_(view, byteOffset) {
|
|
60
|
-
const records = [];
|
|
61
|
-
|
|
62
|
-
while (byteOffset < view.byteLength - 1) {
|
|
63
|
-
const type = view.getUint16(byteOffset, true);
|
|
64
|
-
byteOffset += 2;
|
|
65
|
-
|
|
66
|
-
const byteLength = view.getUint16(byteOffset, true);
|
|
67
|
-
byteOffset += 2;
|
|
68
|
-
|
|
69
|
-
if ((byteLength & 1) != 0 || byteLength + byteOffset > view.byteLength) {
|
|
70
|
-
shaka.log.warning('Malformed MS PRO object');
|
|
71
|
-
return [];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const recordValue = shaka.util.BufferUtils.toUint8(
|
|
75
|
-
view, byteOffset, byteLength);
|
|
76
|
-
records.push({
|
|
77
|
-
type: type,
|
|
78
|
-
value: recordValue,
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
byteOffset += byteLength;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return records;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Parses a buffer for PlayReady Objects. The data
|
|
89
|
-
* should contain a 32-bit integer indicating the length of
|
|
90
|
-
* the PRO in bytes. Following that, a 16-bit integer for
|
|
91
|
-
* the number of PlayReady Object Records in the PRO. Lastly,
|
|
92
|
-
* a byte array of the PRO Records themselves.
|
|
93
|
-
*
|
|
94
|
-
* PlayReady Object format: https://goo.gl/W8yAN4
|
|
95
|
-
*
|
|
96
|
-
* @param {BufferSource} data
|
|
97
|
-
* @return {!Array.<shaka.mss.ContentProtection.PlayReadyRecord>}
|
|
98
|
-
* @private
|
|
99
|
-
*/
|
|
100
|
-
static parseMsPro_(data) {
|
|
101
|
-
let byteOffset = 0;
|
|
102
|
-
const view = shaka.util.BufferUtils.toDataView(data);
|
|
103
|
-
|
|
104
|
-
// First 4 bytes is the PRO length (DWORD)
|
|
105
|
-
const byteLength = view.getUint32(byteOffset, /* littleEndian= */ true);
|
|
106
|
-
byteOffset += 4;
|
|
107
|
-
|
|
108
|
-
if (byteLength != data.byteLength) {
|
|
109
|
-
// Malformed PRO
|
|
110
|
-
shaka.log.warning('PlayReady Object with invalid length encountered.');
|
|
111
|
-
return [];
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Skip PRO Record count (WORD)
|
|
115
|
-
byteOffset += 2;
|
|
116
|
-
|
|
117
|
-
// Rest of the data contains the PRO Records
|
|
118
|
-
const ContentProtection = shaka.mss.ContentProtection;
|
|
119
|
-
return ContentProtection.parseMsProRecords_(view, byteOffset);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Parse a PlayReady Header format: https://goo.gl/dBzxNA
|
|
124
|
-
* a try to find the LA_URL value.
|
|
125
|
-
*
|
|
126
|
-
* @param {!shaka.extern.xml.Node} xml
|
|
127
|
-
* @return {string}
|
|
128
|
-
* @private
|
|
129
|
-
*/
|
|
130
|
-
static getLaurl_(xml) {
|
|
131
|
-
const TXml = shaka.util.TXml;
|
|
132
|
-
// LA_URL element is optional and no more than one is
|
|
133
|
-
// allowed inside the DATA element. Only absolute URLs are allowed.
|
|
134
|
-
// If the LA_URL element exists, it must not be empty.
|
|
135
|
-
for (const elem of TXml.getElementsByTagName(xml, 'DATA')) {
|
|
136
|
-
const laUrl = TXml.findChild(elem, 'LA_URL');
|
|
137
|
-
if (laUrl) {
|
|
138
|
-
return /** @type {string} */ (shaka.util.TXml.getTextContents(laUrl));
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Not found
|
|
143
|
-
// We return a empty string instead null because is the default value for
|
|
144
|
-
// a License in our model.
|
|
145
|
-
return '';
|
|
146
|
-
}
|
|
147
|
-
|
|
148
45
|
/**
|
|
149
46
|
* Gets a PlayReady license URL from a protection element
|
|
150
47
|
* containing a PlayReady Header Object
|
|
@@ -153,47 +50,7 @@ shaka.mss.ContentProtection = class {
|
|
|
153
50
|
* @return {string}
|
|
154
51
|
*/
|
|
155
52
|
static getPlayReadyLicenseUrl(element) {
|
|
156
|
-
|
|
157
|
-
const rootElement = ContentProtection.getPlayReadyHeaderObject_(element);
|
|
158
|
-
if (!rootElement) {
|
|
159
|
-
return '';
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
return ContentProtection.getLaurl_(rootElement);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Parse a PlayReady Header format: https://goo.gl/dBzxNA
|
|
167
|
-
* a try to find the KID value.
|
|
168
|
-
*
|
|
169
|
-
* @param {!shaka.extern.xml.Node} xml
|
|
170
|
-
* @return {?string}
|
|
171
|
-
* @private
|
|
172
|
-
*/
|
|
173
|
-
static getKID_(xml) {
|
|
174
|
-
const TXml = shaka.util.TXml;
|
|
175
|
-
// KID element is optional and no more than one is
|
|
176
|
-
// allowed inside the DATA element.
|
|
177
|
-
for (const elem of TXml.getElementsByTagName(xml, 'DATA')) {
|
|
178
|
-
const kid = TXml.findChild(elem, 'KID');
|
|
179
|
-
if (kid) {
|
|
180
|
-
// GUID: [DWORD, WORD, WORD, 8-BYTE]
|
|
181
|
-
const guidBytes =
|
|
182
|
-
shaka.util.Uint8ArrayUtils.fromBase64(
|
|
183
|
-
/** @type{string} */ (shaka.util.TXml.getTextContents(kid)));
|
|
184
|
-
// Reverse byte order from little-endian to big-endian
|
|
185
|
-
const kidBytes = new Uint8Array([
|
|
186
|
-
guidBytes[3], guidBytes[2], guidBytes[1], guidBytes[0],
|
|
187
|
-
guidBytes[5], guidBytes[4],
|
|
188
|
-
guidBytes[7], guidBytes[6],
|
|
189
|
-
...guidBytes.slice(8),
|
|
190
|
-
]);
|
|
191
|
-
return shaka.util.Uint8ArrayUtils.toHex(kidBytes);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Not found
|
|
196
|
-
return null;
|
|
53
|
+
return shaka.drm.PlayReady.getLicenseUrl(element);
|
|
197
54
|
}
|
|
198
55
|
|
|
199
56
|
/**
|
|
@@ -205,43 +62,7 @@ shaka.mss.ContentProtection = class {
|
|
|
205
62
|
* @private
|
|
206
63
|
*/
|
|
207
64
|
static getPlayReadyKID_(element) {
|
|
208
|
-
|
|
209
|
-
const rootElement = ContentProtection.getPlayReadyHeaderObject_(element);
|
|
210
|
-
if (!rootElement) {
|
|
211
|
-
return null;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return ContentProtection.getKID_(rootElement);
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Gets a PlayReady Header Object from a protection element
|
|
219
|
-
*
|
|
220
|
-
* @param {!shaka.extern.xml.Node} element
|
|
221
|
-
* @return {?shaka.extern.xml.Node}
|
|
222
|
-
* @private
|
|
223
|
-
*/
|
|
224
|
-
static getPlayReadyHeaderObject_(element) {
|
|
225
|
-
const ContentProtection = shaka.mss.ContentProtection;
|
|
226
|
-
const PLAYREADY_RECORD_TYPES = ContentProtection.PLAYREADY_RECORD_TYPES;
|
|
227
|
-
|
|
228
|
-
const bytes = shaka.util.Uint8ArrayUtils.fromBase64(
|
|
229
|
-
/** @type{string} */ (shaka.util.TXml.getTextContents(element)));
|
|
230
|
-
const records = ContentProtection.parseMsPro_(bytes);
|
|
231
|
-
const record = records.filter((record) => {
|
|
232
|
-
return record.type === PLAYREADY_RECORD_TYPES.RIGHTS_MANAGEMENT;
|
|
233
|
-
})[0];
|
|
234
|
-
|
|
235
|
-
if (!record) {
|
|
236
|
-
return null;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const xml = shaka.util.StringUtils.fromUTF16(record.value, true);
|
|
240
|
-
const rootElement = shaka.util.TXml.parseXmlString(xml, 'WRMHEADER');
|
|
241
|
-
if (!rootElement) {
|
|
242
|
-
return null;
|
|
243
|
-
}
|
|
244
|
-
return rootElement;
|
|
65
|
+
return shaka.drm.PlayReady.getPlayReadyKID(element);
|
|
245
66
|
}
|
|
246
67
|
|
|
247
68
|
/**
|
|
@@ -250,13 +71,13 @@ shaka.mss.ContentProtection = class {
|
|
|
250
71
|
* @param {!shaka.extern.xml.Node} element
|
|
251
72
|
* @param {string} systemID
|
|
252
73
|
* @param {?string} keyId
|
|
253
|
-
* @return {?Array
|
|
74
|
+
* @return {?Array<shaka.extern.InitDataOverride>}
|
|
254
75
|
* @private
|
|
255
76
|
*/
|
|
256
77
|
static getInitDataFromPro_(element, systemID, keyId) {
|
|
257
78
|
const Uint8ArrayUtils = shaka.util.Uint8ArrayUtils;
|
|
258
79
|
const data = Uint8ArrayUtils.fromBase64(
|
|
259
|
-
/** @type{string} */ (shaka.util.TXml.getTextContents(element)));
|
|
80
|
+
/** @type {string} */ (shaka.util.TXml.getTextContents(element)));
|
|
260
81
|
const systemId = Uint8ArrayUtils.fromHex(systemID.replace(/-/g, ''));
|
|
261
82
|
const keyIds = new Set();
|
|
262
83
|
const psshVersion = 0;
|
|
@@ -274,9 +95,9 @@ shaka.mss.ContentProtection = class {
|
|
|
274
95
|
/**
|
|
275
96
|
* Creates DrmInfo objects from an array of elements.
|
|
276
97
|
*
|
|
277
|
-
* @param {!Array
|
|
278
|
-
* @param {!Object
|
|
279
|
-
* @return {!Array
|
|
98
|
+
* @param {!Array<!shaka.extern.xml.Node>} elements
|
|
99
|
+
* @param {!Object<string, string>} keySystemsBySystemId
|
|
100
|
+
* @return {!Array<shaka.extern.DrmInfo>}
|
|
280
101
|
* @private
|
|
281
102
|
*/
|
|
282
103
|
static convertElements_(elements, keySystemsBySystemId) {
|
|
@@ -284,7 +105,7 @@ shaka.mss.ContentProtection = class {
|
|
|
284
105
|
const ManifestParserUtils = shaka.util.ManifestParserUtils;
|
|
285
106
|
const licenseUrlParsers = ContentProtection.licenseUrlParsers_;
|
|
286
107
|
|
|
287
|
-
/** @type {!Array
|
|
108
|
+
/** @type {!Array<shaka.extern.DrmInfo>} */
|
|
288
109
|
const out = [];
|
|
289
110
|
|
|
290
111
|
for (let i = 0; i < elements.length; i++) {
|
|
@@ -315,36 +136,10 @@ shaka.mss.ContentProtection = class {
|
|
|
315
136
|
}
|
|
316
137
|
};
|
|
317
138
|
|
|
318
|
-
/**
|
|
319
|
-
* @typedef {{
|
|
320
|
-
* type: number,
|
|
321
|
-
* value: !Uint8Array
|
|
322
|
-
* }}
|
|
323
|
-
*
|
|
324
|
-
* @description
|
|
325
|
-
* The parsed result of a PlayReady object record.
|
|
326
|
-
*
|
|
327
|
-
* @property {number} type
|
|
328
|
-
* Type of data stored in the record.
|
|
329
|
-
* @property {!Uint8Array} value
|
|
330
|
-
* Record content.
|
|
331
|
-
*/
|
|
332
|
-
shaka.mss.ContentProtection.PlayReadyRecord;
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Enum for PlayReady record types.
|
|
336
|
-
* @enum {number}
|
|
337
|
-
*/
|
|
338
|
-
shaka.mss.ContentProtection.PLAYREADY_RECORD_TYPES = {
|
|
339
|
-
RIGHTS_MANAGEMENT: 0x001,
|
|
340
|
-
RESERVED: 0x002,
|
|
341
|
-
EMBEDDED_LICENSE: 0x003,
|
|
342
|
-
};
|
|
343
|
-
|
|
344
139
|
/**
|
|
345
140
|
* A map of key system name to license server url parser.
|
|
346
141
|
*
|
|
347
|
-
* @const {!Map
|
|
142
|
+
* @const {!Map<string, function(!shaka.extern.xml.Node)>}
|
|
348
143
|
* @private
|
|
349
144
|
*/
|
|
350
145
|
shaka.mss.ContentProtection.licenseUrlParsers_ = new Map()
|
package/lib/mss/mss_parser.js
CHANGED
|
@@ -45,7 +45,7 @@ shaka.mss.MssParser = class {
|
|
|
45
45
|
/** @private {?shaka.extern.ManifestParser.PlayerInterface} */
|
|
46
46
|
this.playerInterface_ = null;
|
|
47
47
|
|
|
48
|
-
/** @private {!Array
|
|
48
|
+
/** @private {!Array<string>} */
|
|
49
49
|
this.manifestUris_ = [];
|
|
50
50
|
|
|
51
51
|
/** @private {?shaka.extern.Manifest} */
|
|
@@ -79,7 +79,7 @@ shaka.mss.MssParser = class {
|
|
|
79
79
|
this.operationManager_ = new shaka.util.OperationManager();
|
|
80
80
|
|
|
81
81
|
/**
|
|
82
|
-
* @private {!Map
|
|
82
|
+
* @private {!Map<number, !BufferSource>}
|
|
83
83
|
*/
|
|
84
84
|
this.initSegmentDataByStreamId_ = new Map();
|
|
85
85
|
|
|
@@ -431,7 +431,6 @@ shaka.mss.MssParser = class {
|
|
|
431
431
|
textStreams: context.textStreams,
|
|
432
432
|
imageStreams: [],
|
|
433
433
|
offlineSessionIds: [],
|
|
434
|
-
minBufferTime: 0,
|
|
435
434
|
sequenceMode: this.config_.mss.sequenceMode,
|
|
436
435
|
ignoreManifestTimestampsInSegmentsMode: false,
|
|
437
436
|
type: shaka.media.ManifestParser.MSS,
|
|
@@ -469,9 +468,9 @@ shaka.mss.MssParser = class {
|
|
|
469
468
|
const TXml = shaka.util.TXml;
|
|
470
469
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
471
470
|
|
|
472
|
-
const
|
|
471
|
+
const protectionElements = TXml.findChildren(mss, 'Protection');
|
|
473
472
|
const drmInfos = ContentProtection.parseFromProtection(
|
|
474
|
-
|
|
473
|
+
protectionElements, this.config_.mss.keySystemsBySystemId);
|
|
475
474
|
|
|
476
475
|
const audioStreams = [];
|
|
477
476
|
const videoStreams = [];
|
|
@@ -515,8 +514,8 @@ shaka.mss.MssParser = class {
|
|
|
515
514
|
/**
|
|
516
515
|
* @param {!shaka.extern.xml.Node} streamIndex
|
|
517
516
|
* @param {!shaka.extern.xml.Node} qualityLevel
|
|
518
|
-
* @param {!Array
|
|
519
|
-
* @param {!Array
|
|
517
|
+
* @param {!Array<shaka.mss.MssParser.TimeRange>} timeline
|
|
518
|
+
* @param {!Array<shaka.extern.DrmInfo>} drmInfos
|
|
520
519
|
* @param {!shaka.mss.MssParser.Context} context
|
|
521
520
|
* @return {?shaka.extern.Stream}
|
|
522
521
|
* @private
|
|
@@ -715,7 +714,7 @@ shaka.mss.MssParser = class {
|
|
|
715
714
|
videoConfig: new Uint8Array([]),
|
|
716
715
|
hSpacing: 0,
|
|
717
716
|
vSpacing: 0,
|
|
718
|
-
data: null, // Data is not necessary for init
|
|
717
|
+
data: null, // Data is not necessary for init segment.
|
|
719
718
|
stream: stream,
|
|
720
719
|
};
|
|
721
720
|
const mp4Generator = new shaka.util.Mp4Generator([streamInfo]);
|
|
@@ -793,7 +792,7 @@ shaka.mss.MssParser = class {
|
|
|
793
792
|
const objectType = 0x05;
|
|
794
793
|
// 4 bytes :
|
|
795
794
|
// XXXXX XXXX XXXX XXXX
|
|
796
|
-
// 'ObjectType' 'Freq Index' 'Channels value' '
|
|
795
|
+
// 'ObjectType' 'Freq Index' 'Channels value' 'Extension Sampling Freq'
|
|
797
796
|
// XXXXX XXX XXXXXXX
|
|
798
797
|
// 'ObjectType' 'GAS' 'alignment = 0'
|
|
799
798
|
const data = new Uint8Array(4);
|
|
@@ -808,7 +807,7 @@ shaka.mss.MssParser = class {
|
|
|
808
807
|
(extensionSamplingFrequencyIndex >> 1);
|
|
809
808
|
// Origin object type equals to 2 => AAC Main Low Complexity
|
|
810
809
|
data[2] = (extensionSamplingFrequencyIndex << 7) | (0x02 << 2);
|
|
811
|
-
//
|
|
810
|
+
// Alignment bits
|
|
812
811
|
data[3] = 0x0;
|
|
813
812
|
// Put the 4 bytes in an 16 bits array
|
|
814
813
|
const arr16 = new Uint16Array(2);
|
|
@@ -882,18 +881,18 @@ shaka.mss.MssParser = class {
|
|
|
882
881
|
return '';
|
|
883
882
|
}
|
|
884
883
|
// => Find the 6 characters after the SPS nalHeader (if it exists)
|
|
885
|
-
const
|
|
884
|
+
const avcOti = codecPrivateData.substr(
|
|
886
885
|
codecPrivateData.indexOf(nalHeader[0]) + 10, 6);
|
|
887
886
|
|
|
888
|
-
return 'avc1.' +
|
|
887
|
+
return 'avc1.' + avcOti;
|
|
889
888
|
}
|
|
890
889
|
|
|
891
890
|
/**
|
|
892
891
|
* @param {!shaka.media.InitSegmentReference} initSegmentRef
|
|
893
892
|
* @param {!shaka.extern.Stream} stream
|
|
894
893
|
* @param {!shaka.extern.xml.Node} streamIndex
|
|
895
|
-
* @param {!Array
|
|
896
|
-
* @return {!Array
|
|
894
|
+
* @param {!Array<shaka.mss.MssParser.TimeRange>} timeline
|
|
895
|
+
* @return {!Array<!shaka.media.SegmentReference>}
|
|
897
896
|
* @private
|
|
898
897
|
*/
|
|
899
898
|
createSegments_(initSegmentRef, stream, streamIndex, timeline) {
|
|
@@ -930,7 +929,7 @@ shaka.mss.MssParser = class {
|
|
|
930
929
|
* @param {!shaka.extern.xml.Node} streamIndex
|
|
931
930
|
* @param {number} timescale
|
|
932
931
|
* @param {number} duration The duration in seconds.
|
|
933
|
-
* @return {!Array
|
|
932
|
+
* @return {!Array<shaka.mss.MssParser.TimeRange>}
|
|
934
933
|
* @private
|
|
935
934
|
*/
|
|
936
935
|
createTimeline_(streamIndex, timescale, duration) {
|
|
@@ -944,7 +943,7 @@ shaka.mss.MssParser = class {
|
|
|
944
943
|
|
|
945
944
|
const timePoints = TXml.findChildren(streamIndex, 'c');
|
|
946
945
|
|
|
947
|
-
/** @type {!Array
|
|
946
|
+
/** @type {!Array<shaka.mss.MssParser.TimeRange>} */
|
|
948
947
|
const timeline = [];
|
|
949
948
|
let lastEndTime = 0;
|
|
950
949
|
|
|
@@ -985,7 +984,7 @@ shaka.mss.MssParser = class {
|
|
|
985
984
|
return timeline;
|
|
986
985
|
} else if (startTime >= nextStartTime) {
|
|
987
986
|
shaka.log.warning(
|
|
988
|
-
'An "c" element cannot have a negative
|
|
987
|
+
'An "c" element cannot have a negative repeat if its start ',
|
|
989
988
|
'time exceeds the next "c" element\'s start time:',
|
|
990
989
|
'ignoring the remaining "c" elements.', timePoint);
|
|
991
990
|
return timeline;
|
|
@@ -1006,7 +1005,7 @@ shaka.mss.MssParser = class {
|
|
|
1006
1005
|
shaka.log.warning(
|
|
1007
1006
|
'The last "c" element cannot have a negative repeat',
|
|
1008
1007
|
'if its start time exceeds the duration:',
|
|
1009
|
-
'
|
|
1008
|
+
'ignoring the last "c" element.', timePoint);
|
|
1010
1009
|
return timeline;
|
|
1011
1010
|
}
|
|
1012
1011
|
repeat = Math.ceil((duration * timescale - startTime) / d) - 1;
|
|
@@ -1090,7 +1089,7 @@ shaka.mss.MssParser.DEFAULT_TIME_SCALE_ = 1e7;
|
|
|
1090
1089
|
* MSS supported codecs.
|
|
1091
1090
|
*
|
|
1092
1091
|
* @private
|
|
1093
|
-
* @const {!Array
|
|
1092
|
+
* @const {!Array<string>}
|
|
1094
1093
|
*/
|
|
1095
1094
|
shaka.mss.MssParser.SUPPORTED_CODECS_ = [
|
|
1096
1095
|
'AAC',
|
|
@@ -1108,7 +1107,7 @@ shaka.mss.MssParser.SUPPORTED_CODECS_ = [
|
|
|
1108
1107
|
* MPEG-DASH Role and accessibility mapping for text tracks according to
|
|
1109
1108
|
* ETSI TS 103 285 v1.1.1 (section 7.1.2)
|
|
1110
1109
|
*
|
|
1111
|
-
* @const {!Object
|
|
1110
|
+
* @const {!Object<string, string>}
|
|
1112
1111
|
* @private
|
|
1113
1112
|
*/
|
|
1114
1113
|
shaka.mss.MssParser.ROLE_MAPPING_ = {
|
|
@@ -1120,15 +1119,15 @@ shaka.mss.MssParser.ROLE_MAPPING_ = {
|
|
|
1120
1119
|
|
|
1121
1120
|
/**
|
|
1122
1121
|
* @typedef {{
|
|
1123
|
-
* variants: !Array
|
|
1124
|
-
* textStreams: !Array
|
|
1122
|
+
* variants: !Array<shaka.extern.Variant>,
|
|
1123
|
+
* textStreams: !Array<shaka.extern.Stream>,
|
|
1125
1124
|
* timescale: number,
|
|
1126
1125
|
* duration: number
|
|
1127
1126
|
* }}
|
|
1128
1127
|
*
|
|
1129
|
-
* @property {!Array
|
|
1128
|
+
* @property {!Array<shaka.extern.Variant>} variants
|
|
1130
1129
|
* The presentation's Variants.
|
|
1131
|
-
* @property {!Array
|
|
1130
|
+
* @property {!Array<shaka.extern.Stream>} textStreams
|
|
1132
1131
|
* The presentation's text streams.
|
|
1133
1132
|
* @property {number} timescale
|
|
1134
1133
|
* The presentation's timescale.
|
|
@@ -61,8 +61,8 @@ shaka.net.HttpFetchPlugin = class {
|
|
|
61
61
|
const minBytes = config.minBytesForProgressEvents || 0;
|
|
62
62
|
|
|
63
63
|
const pendingRequest = shaka.net.HttpFetchPlugin.request_(
|
|
64
|
-
uri, requestType, init, abortStatus, progressUpdated,
|
|
65
|
-
request.streamDataCallback, minBytes);
|
|
64
|
+
uri, request, requestType, init, abortStatus, progressUpdated,
|
|
65
|
+
headersReceived, request.streamDataCallback, minBytes);
|
|
66
66
|
|
|
67
67
|
/** @type {!shaka.util.AbortableOperation} */
|
|
68
68
|
const op = new shaka.util.AbortableOperation(pendingRequest, () => {
|
|
@@ -94,6 +94,7 @@ shaka.net.HttpFetchPlugin = class {
|
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
96
|
* @param {string} uri
|
|
97
|
+
* @param {shaka.extern.Request} request
|
|
97
98
|
* @param {shaka.net.NetworkingEngine.RequestType} requestType
|
|
98
99
|
* @param {!RequestInit} init
|
|
99
100
|
* @param {shaka.net.HttpFetchPlugin.AbortStatus} abortStatus
|
|
@@ -104,8 +105,8 @@ shaka.net.HttpFetchPlugin = class {
|
|
|
104
105
|
* @return {!Promise<!shaka.extern.Response>}
|
|
105
106
|
* @private
|
|
106
107
|
*/
|
|
107
|
-
static async request_(uri, requestType, init, abortStatus,
|
|
108
|
-
headersReceived, streamDataCallback, minBytes) {
|
|
108
|
+
static async request_(uri, request, requestType, init, abortStatus,
|
|
109
|
+
progressUpdated, headersReceived, streamDataCallback, minBytes) {
|
|
109
110
|
const fetch = shaka.net.HttpFetchPlugin.fetch_;
|
|
110
111
|
const ReadableStream = shaka.net.HttpFetchPlugin.ReadableStream_;
|
|
111
112
|
let response;
|
|
@@ -225,13 +226,13 @@ shaka.net.HttpFetchPlugin = class {
|
|
|
225
226
|
const headers = shaka.net.HttpFetchPlugin.headersToGenericObject_(
|
|
226
227
|
response.headers);
|
|
227
228
|
|
|
228
|
-
return shaka.net.HttpPluginUtils.makeResponse(
|
|
229
|
-
|
|
229
|
+
return shaka.net.HttpPluginUtils.makeResponse(headers, arrayBuffer,
|
|
230
|
+
response.status, uri, response.url, request, requestType);
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
/**
|
|
233
234
|
* @param {!Headers} headers
|
|
234
|
-
* @return {!Object
|
|
235
|
+
* @return {!Object<string, string>}
|
|
235
236
|
* @private
|
|
236
237
|
*/
|
|
237
238
|
static headersToGenericObject_(headers) {
|
|
@@ -19,15 +19,17 @@ goog.requireType('shaka.net.NetworkingEngine');
|
|
|
19
19
|
*/
|
|
20
20
|
shaka.net.HttpPluginUtils = class {
|
|
21
21
|
/**
|
|
22
|
-
* @param {!Object
|
|
22
|
+
* @param {!Object<string, string>} headers
|
|
23
23
|
* @param {BufferSource} data
|
|
24
24
|
* @param {number} status
|
|
25
25
|
* @param {string} uri
|
|
26
26
|
* @param {string} responseURL
|
|
27
|
+
* @param {shaka.extern.Request} request
|
|
27
28
|
* @param {shaka.net.NetworkingEngine.RequestType} requestType
|
|
28
29
|
* @return {!shaka.extern.Response}
|
|
29
30
|
*/
|
|
30
|
-
static makeResponse(headers, data, status, uri, responseURL,
|
|
31
|
+
static makeResponse(headers, data, status, uri, responseURL, request,
|
|
32
|
+
requestType) {
|
|
31
33
|
goog.asserts.assert(data, 'Data should be non-null!');
|
|
32
34
|
|
|
33
35
|
if (status >= 200 && status <= 299 && status != 202) {
|
|
@@ -40,6 +42,7 @@ shaka.net.HttpPluginUtils = class {
|
|
|
40
42
|
status: status,
|
|
41
43
|
headers: headers,
|
|
42
44
|
fromCache: !!headers['x-shaka-from-cache'],
|
|
45
|
+
originalRequest: request,
|
|
43
46
|
};
|
|
44
47
|
return response;
|
|
45
48
|
} else {
|
|
@@ -74,7 +74,8 @@ shaka.net.HttpXHRPlugin = class {
|
|
|
74
74
|
progressUpdated(currentTime - lastTime, event.loaded - lastLoaded,
|
|
75
75
|
/* numBytesRemaining= */ 0);
|
|
76
76
|
const response = shaka.net.HttpPluginUtils.makeResponse(headers,
|
|
77
|
-
xhrResponse, xhr.status, uri, xhr.responseURL,
|
|
77
|
+
xhrResponse, xhr.status, uri, xhr.responseURL, request,
|
|
78
|
+
requestType);
|
|
78
79
|
resolve(response);
|
|
79
80
|
} catch (error) {
|
|
80
81
|
goog.asserts.assert(error instanceof shaka.util.Error,
|
|
@@ -133,7 +134,7 @@ shaka.net.HttpXHRPlugin = class {
|
|
|
133
134
|
|
|
134
135
|
/**
|
|
135
136
|
* @param {!XMLHttpRequest} xhr
|
|
136
|
-
* @return {!Object
|
|
137
|
+
* @return {!Object<string, string>}
|
|
137
138
|
* @private
|
|
138
139
|
*/
|
|
139
140
|
static headersToGenericObject_(xhr) {
|
|
@@ -142,7 +143,7 @@ shaka.net.HttpXHRPlugin = class {
|
|
|
142
143
|
const headerLines = xhr.getAllResponseHeaders().trim().split('\r\n');
|
|
143
144
|
const headers = {};
|
|
144
145
|
for (const header of headerLines) {
|
|
145
|
-
/** @type {!Array
|
|
146
|
+
/** @type {!Array<string>} */
|
|
146
147
|
const parts = header.split(': ');
|
|
147
148
|
headers[parts[0].toLowerCase()] = parts.slice(1).join(': ');
|
|
148
149
|
}
|