shaka-player 3.2.2 → 3.3.2
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/.github/workflows/build_and_test.yaml +73 -0
- package/.github/workflows/release.yaml +53 -0
- package/AUTHORS +6 -5
- package/CHANGELOG.md +314 -1
- package/CONTRIBUTORS +4 -2
- package/build/checkversion.py +1 -1
- package/build/conformance.textproto +183 -169
- package/build/test.py +6 -0
- package/build/types/core +3 -0
- package/build/types/offline +1 -0
- package/build/types/polyfill +1 -0
- package/build/types/ui +2 -0
- package/demo/common/assets.js +18 -0
- package/demo/common/message_ids.js +13 -1
- package/demo/config.js +31 -1
- package/demo/index.html +1 -1
- package/demo/locales/en.json +12 -0
- package/demo/locales/source.json +48 -0
- package/dist/controls.css +26 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +19 -16
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +19 -16
- package/dist/demo.compiled.map +3 -3
- package/dist/deps.js +21 -14
- package/dist/locales.js +31 -29
- package/dist/receiver.compiled.debug.js +11 -9
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +11 -9
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +232 -18
- package/dist/shaka-player.compiled.debug.d.ts +232 -18
- package/dist/shaka-player.compiled.debug.externs.js +293 -17
- package/dist/shaka-player.compiled.debug.js +481 -422
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +293 -17
- package/dist/shaka-player.compiled.js +846 -817
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +250 -30
- package/dist/shaka-player.ui.debug.d.ts +250 -30
- package/dist/shaka-player.ui.debug.externs.js +322 -28
- package/dist/shaka-player.ui.debug.js +630 -553
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +322 -28
- package/dist/shaka-player.ui.js +1048 -1006
- 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/cmcd.js +186 -0
- package/externs/ima.js +3 -0
- package/externs/shaka/ads.js +5 -0
- package/externs/shaka/manifest.js +12 -1
- package/externs/shaka/manifest_parser.js +10 -1
- package/externs/shaka/net.js +20 -4
- package/externs/shaka/offline.js +31 -2
- package/externs/shaka/player.js +138 -5
- package/externs/shaka/text.js +24 -0
- package/externs/webcrypto.js +18 -0
- package/karma.conf.js +19 -15
- 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 +1 -0
- package/lib/ads/client_side_ad.js +8 -0
- package/lib/ads/client_side_ad_manager.js +8 -4
- package/lib/ads/server_side_ad.js +7 -0
- package/lib/cast/cast_proxy.js +3 -0
- package/lib/cast/cast_receiver.js +3 -0
- package/lib/cast/cast_utils.js +1 -0
- package/lib/dash/dash_parser.js +79 -33
- 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 +116 -23
- package/lib/hls/manifest_text_parser.js +1 -0
- package/lib/media/quality_observer.js +274 -0
- package/lib/media/region_observer.js +39 -33
- package/lib/media/region_timeline.js +17 -19
- package/lib/media/segment_index.js +8 -1
- package/lib/media/segment_reference.js +37 -4
- package/lib/media/streaming_engine.js +47 -6
- 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 +85 -18
- package/lib/offline/download_info.js +68 -0
- package/lib/offline/download_manager.js +13 -5
- package/lib/offline/indexeddb/base_storage_cell.js +35 -0
- package/lib/offline/indexeddb/storage_mechanism.js +1 -1
- package/lib/offline/indexeddb/v5_storage_cell.js +5 -0
- package/lib/offline/storage.js +401 -293
- package/lib/offline/stored_content_utils.js +2 -0
- package/lib/player.js +254 -27
- package/lib/polyfill/media_capabilities.js +30 -15
- package/lib/polyfill/random_uuid.js +52 -0
- package/lib/text/cue.js +18 -0
- package/lib/text/ttml_text_parser.js +109 -60
- package/lib/text/ui_text_displayer.js +19 -13
- package/lib/util/cmcd_manager.js +672 -0
- package/lib/util/error.js +6 -0
- package/lib/util/fake_event_target.js +21 -1
- package/lib/util/language_utils.js +12 -0
- package/lib/util/mutex.js +52 -0
- package/lib/util/periods.js +98 -64
- package/lib/util/player_configuration.js +18 -0
- package/lib/util/stream_utils.js +86 -10
- package/lib/util/xml_utils.js +19 -0
- package/package.json +3 -6
- package/shaka-player.uncompiled.js +3 -0
- package/test/dash/dash_parser_content_protection_unit.js +2 -0
- package/test/dash/dash_parser_live_unit.js +144 -1
- package/test/dash/dash_parser_manifest_unit.js +37 -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 +76 -0
- package/test/media/drm_engine_unit.js +3 -3
- package/test/media/quality_observer_unit.js +142 -0
- package/test/media/region_observer_unit.js +40 -5
- package/test/media/region_timeline_unit.js +40 -22
- package/test/media/segment_reference_unit.js +16 -1
- package/test/media/streaming_engine_integration.js +4 -2
- package/test/media/streaming_engine_unit.js +147 -0
- package/test/net/http_plugin_unit.js +20 -15
- package/test/offline/storage_integration.js +108 -4
- package/test/player_integration.js +140 -8
- package/test/player_src_equals_integration.js +41 -8
- package/test/player_unit.js +19 -9
- package/test/test/assets/chapters.vtt +2 -2
- package/test/test/assets/chapters2.vtt +10 -0
- package/test/test/util/dash_parser_util.js +4 -0
- package/test/test/util/fake_ad.js +7 -0
- package/test/test/util/fake_drm_engine.js +9 -2
- package/test/test/util/manifest_generator.js +3 -2
- package/test/test/util/test_scheme.js +14 -1
- package/test/test/util/ttml_utils.js +81 -0
- package/test/test/util/util.js +10 -7
- package/test/text/mp4_ttml_parser_unit.js +11 -18
- package/test/text/ttml_text_parser_unit.js +544 -228
- package/test/ui/text_displayer_layout_unit.js +8 -7
- package/test/ui/ui_unit.js +250 -0
- package/test/util/cmcd_manager_unit.js +291 -0
- package/test/util/stream_utils_unit.js +36 -30
- package/third_party/closure-uri/uri.js +21 -0
- package/ui/airplay_button.js +1 -0
- package/ui/audio_language_selection.js +7 -0
- package/ui/cast_button.js +1 -0
- package/ui/context_menu.js +109 -0
- package/ui/controls.js +44 -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 +14 -5
- package/ui/fullscreen_button.js +1 -0
- 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/localization.js +12 -36
- package/ui/loop_button.js +5 -0
- package/ui/mute_button.js +2 -1
- package/ui/overflow_menu.js +5 -25
- package/ui/pip_button.js +5 -0
- package/ui/play_button.js +2 -2
- package/ui/playback_rate_selection.js +8 -9
- package/ui/resolution_selection.js +7 -0
- package/ui/rewind_button.js +15 -6
- package/ui/seek_bar.js +4 -2
- package/ui/settings_menu.js +36 -4
- package/ui/small_play_button.js +1 -0
- package/ui/statistics_button.js +253 -0
- package/ui/text_selection.js +12 -4
- package/ui/ui.js +30 -0
- package/ui/volume_bar.js +1 -1
- package/externs/media_capabilities.js +0 -16
|
@@ -47,6 +47,7 @@ shaka.offline.StoredContentUtils = class {
|
|
|
47
47
|
expiration: Infinity,
|
|
48
48
|
tracks: tracks,
|
|
49
49
|
appMetadata: metadata,
|
|
50
|
+
isIncomplete: false,
|
|
50
51
|
};
|
|
51
52
|
|
|
52
53
|
return content;
|
|
@@ -87,6 +88,7 @@ shaka.offline.StoredContentUtils = class {
|
|
|
87
88
|
expiration: manifestDB.expiration,
|
|
88
89
|
tracks: tracks,
|
|
89
90
|
appMetadata: metadata,
|
|
91
|
+
isIncomplete: (manifestDB.isIncomplete || false),
|
|
90
92
|
};
|
|
91
93
|
|
|
92
94
|
return content;
|
package/lib/player.js
CHANGED
|
@@ -22,6 +22,7 @@ goog.require('shaka.media.PlayRateController');
|
|
|
22
22
|
goog.require('shaka.media.Playhead');
|
|
23
23
|
goog.require('shaka.media.PlayheadObserverManager');
|
|
24
24
|
goog.require('shaka.media.PreferenceBasedCriteria');
|
|
25
|
+
goog.require('shaka.media.QualityObserver');
|
|
25
26
|
goog.require('shaka.media.RegionObserver');
|
|
26
27
|
goog.require('shaka.media.RegionTimeline');
|
|
27
28
|
goog.require('shaka.media.SegmentIndex');
|
|
@@ -36,6 +37,7 @@ goog.require('shaka.text.UITextDisplayer');
|
|
|
36
37
|
goog.require('shaka.text.WebVttGenerator');
|
|
37
38
|
goog.require('shaka.util.AbortableOperation');
|
|
38
39
|
goog.require('shaka.util.BufferUtils');
|
|
40
|
+
goog.require('shaka.util.CmcdManager');
|
|
39
41
|
goog.require('shaka.util.ConfigUtils');
|
|
40
42
|
goog.require('shaka.util.Error');
|
|
41
43
|
goog.require('shaka.util.EventManager');
|
|
@@ -106,6 +108,32 @@ goog.requireType('shaka.routing.Payload');
|
|
|
106
108
|
*/
|
|
107
109
|
|
|
108
110
|
|
|
111
|
+
/**
|
|
112
|
+
* @event shaka.Player.DownloadFailed
|
|
113
|
+
* @description Fired when a download has failed, for any reason.
|
|
114
|
+
* 'downloadfailed'
|
|
115
|
+
* @property {!shaka.extern.Request} request
|
|
116
|
+
* @property {?shaka.util.Error} error
|
|
117
|
+
* @param {number} httpResponseCode
|
|
118
|
+
* @param {boolean} aborted
|
|
119
|
+
* @exportDoc
|
|
120
|
+
*/
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* @event shaka.Player.DownloadHeadersReceived
|
|
125
|
+
* @description Fired when the networking engine has received the headers for
|
|
126
|
+
* a download, but before the body has been downloaded.
|
|
127
|
+
* If the HTTP plugin being used does not track this information, this event
|
|
128
|
+
* will default to being fired when the body is received, instead.
|
|
129
|
+
* @property {!Object.<string, string>} headers
|
|
130
|
+
* @property {!shaka.extern.Request} request
|
|
131
|
+
* @property {!shaka.net.NetworkingEngine.RequestType} type
|
|
132
|
+
* 'downloadheadersreceived'
|
|
133
|
+
* @exportDoc
|
|
134
|
+
*/
|
|
135
|
+
|
|
136
|
+
|
|
109
137
|
/**
|
|
110
138
|
* @event shaka.Player.DrmSessionUpdateEvent
|
|
111
139
|
* @description Fired when the CDM has accepted the license response.
|
|
@@ -147,6 +175,21 @@ goog.requireType('shaka.routing.Payload');
|
|
|
147
175
|
* @exportDoc
|
|
148
176
|
*/
|
|
149
177
|
|
|
178
|
+
/**
|
|
179
|
+
* @event shaka.Player.MediaQualityChangedEvent
|
|
180
|
+
* @description Fired when the media quality changes at the playhead.
|
|
181
|
+
* That may be caused by an adaptation change or a DASH period transition.
|
|
182
|
+
* Separate events are emitted for audio and video contentTypes.
|
|
183
|
+
* This is supported for only DASH streams at this time.
|
|
184
|
+
* @property {string} type
|
|
185
|
+
* 'mediaqualitychanged'
|
|
186
|
+
* @property {shaka.extern.MediaQualityInfo} mediaQuality
|
|
187
|
+
* Information about media quality at the playhead position.
|
|
188
|
+
* @property {number} position
|
|
189
|
+
* The playhead position.
|
|
190
|
+
* @exportDoc
|
|
191
|
+
*/
|
|
192
|
+
|
|
150
193
|
|
|
151
194
|
/**
|
|
152
195
|
* @event shaka.Player.BufferingEvent
|
|
@@ -441,6 +484,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
441
484
|
/** @private {shaka.media.RegionTimeline} */
|
|
442
485
|
this.regionTimeline_ = null;
|
|
443
486
|
|
|
487
|
+
/** @private {shaka.util.CmcdManager} */
|
|
488
|
+
this.cmcdManager_ = null;
|
|
489
|
+
|
|
490
|
+
/** @private {shaka.media.QualityObserver} */
|
|
491
|
+
this.qualityObserver_ = null;
|
|
492
|
+
|
|
444
493
|
/** @private {shaka.media.StreamingEngine} */
|
|
445
494
|
this.streamingEngine_ = null;
|
|
446
495
|
|
|
@@ -507,6 +556,15 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
507
556
|
/** @private {!Array.<function():(!Promise|undefined)>} */
|
|
508
557
|
this.cleanupOnUnload_ = [];
|
|
509
558
|
|
|
559
|
+
/**
|
|
560
|
+
* This playback start position will be used when
|
|
561
|
+
* <code>updateStartTime()</code> has been called to provide an updated
|
|
562
|
+
* start position during the media loading process.
|
|
563
|
+
*
|
|
564
|
+
* @private {?number}
|
|
565
|
+
*/
|
|
566
|
+
this.updatedStartTime_ = null;
|
|
567
|
+
|
|
510
568
|
if (dependencyInjector) {
|
|
511
569
|
dependencyInjector(this);
|
|
512
570
|
}
|
|
@@ -723,11 +781,15 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
723
781
|
this.config_ = null;
|
|
724
782
|
this.stats_ = null;
|
|
725
783
|
this.videoContainer_ = null;
|
|
784
|
+
this.cmcdManager_ = null;
|
|
726
785
|
|
|
727
786
|
if (this.networkingEngine_) {
|
|
728
787
|
await this.networkingEngine_.destroy();
|
|
729
788
|
this.networkingEngine_ = null;
|
|
730
789
|
}
|
|
790
|
+
|
|
791
|
+
// FakeEventTarget implements IReleasable
|
|
792
|
+
super.release();
|
|
731
793
|
}
|
|
732
794
|
|
|
733
795
|
/**
|
|
@@ -1020,6 +1082,19 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1020
1082
|
return this.wrapWalkerListenersWithPromise_(events);
|
|
1021
1083
|
}
|
|
1022
1084
|
|
|
1085
|
+
/**
|
|
1086
|
+
* Provides a way to update the stream start position during the media loading
|
|
1087
|
+
* process. Can for example be called from the <code>manifestparsed</code>
|
|
1088
|
+
* event handler to update the start position based on information in the
|
|
1089
|
+
* manifest.
|
|
1090
|
+
*
|
|
1091
|
+
* @param {number} startTime
|
|
1092
|
+
* @export
|
|
1093
|
+
*/
|
|
1094
|
+
updateStartTime(startTime) {
|
|
1095
|
+
this.updatedStartTime_ = startTime;
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1023
1098
|
/**
|
|
1024
1099
|
* Tell the player to load the content at <code>assetUri</code> and start
|
|
1025
1100
|
* playback at <code>startTime</code>. Before calling <code>load</code>,
|
|
@@ -1040,6 +1115,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1040
1115
|
* @export
|
|
1041
1116
|
*/
|
|
1042
1117
|
load(assetUri, startTime, mimeType) {
|
|
1118
|
+
this.updatedStartTime_ = null;
|
|
1119
|
+
|
|
1043
1120
|
// Do not allow the player to be used after |destroy| is called.
|
|
1044
1121
|
if (this.loadMode_ == shaka.Player.LoadMode.DESTROYED) {
|
|
1045
1122
|
return Promise.reject(this.createAbortLoadError_());
|
|
@@ -1093,6 +1170,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1093
1170
|
// before we allow calls to |updateStateHistory|.
|
|
1094
1171
|
this.stats_ = new shaka.util.Stats();
|
|
1095
1172
|
|
|
1173
|
+
// Create the CMCD manager so client data can be attached to all requests
|
|
1174
|
+
this.cmcdManager_ = this.createCmcd_();
|
|
1175
|
+
|
|
1096
1176
|
// Load's request is a little different, so we can't use our normal
|
|
1097
1177
|
// listeners-to-promise method. It is the only request where we may skip the
|
|
1098
1178
|
// request, so we need to set the on skip callback to reject with a specific
|
|
@@ -1594,6 +1674,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1594
1674
|
goog.asserts.assert(
|
|
1595
1675
|
this.networkingEngine_,
|
|
1596
1676
|
'Need networking engine to parse manifest.');
|
|
1677
|
+
goog.asserts.assert(
|
|
1678
|
+
this.cmcdManager_,
|
|
1679
|
+
'Need CMCD manager to populate manifest request data.');
|
|
1597
1680
|
goog.asserts.assert(
|
|
1598
1681
|
this.config_,
|
|
1599
1682
|
'Need player config to parse manifest.');
|
|
@@ -1611,15 +1694,38 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1611
1694
|
// initialize it now even through it appears a little out-of-place.
|
|
1612
1695
|
this.regionTimeline_ =
|
|
1613
1696
|
new shaka.media.RegionTimeline(() => this.seekRange());
|
|
1614
|
-
this.regionTimeline_.
|
|
1697
|
+
this.regionTimeline_.addEventListener('regionadd', (event) => {
|
|
1698
|
+
/** @type {shaka.extern.TimelineRegionInfo} */
|
|
1699
|
+
const region = event['region'];
|
|
1615
1700
|
this.onRegionEvent_(shaka.Player.EventName.TimelineRegionAdded, region);
|
|
1701
|
+
|
|
1616
1702
|
if (this.adManager_) {
|
|
1617
1703
|
this.adManager_.onDashTimedMetadata(region);
|
|
1618
1704
|
}
|
|
1619
1705
|
});
|
|
1620
1706
|
|
|
1707
|
+
this.qualityObserver_ = null;
|
|
1708
|
+
if (this.config_.streaming.observeQualityChanges) {
|
|
1709
|
+
this.qualityObserver_ = new shaka.media.QualityObserver(
|
|
1710
|
+
() => this.getBufferedInfo());
|
|
1711
|
+
|
|
1712
|
+
this.qualityObserver_.addEventListener('qualitychange', (event) => {
|
|
1713
|
+
/** @type {shaka.extern.MediaQualityInfo} */
|
|
1714
|
+
const mediaQualityInfo = event['quality'];
|
|
1715
|
+
/** @type {number} */
|
|
1716
|
+
const position = event['position'];
|
|
1717
|
+
this.onMediaQualityChange_(mediaQualityInfo, position);
|
|
1718
|
+
});
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1621
1721
|
const playerInterface = {
|
|
1622
1722
|
networkingEngine: networkingEngine,
|
|
1723
|
+
modifyManifestRequest: (request, manifestInfo) => {
|
|
1724
|
+
this.cmcdManager_.applyManifestData(request, manifestInfo);
|
|
1725
|
+
},
|
|
1726
|
+
modifySegmentRequest: (request, segmentInfo) => {
|
|
1727
|
+
this.cmcdManager_.applySegmentData(request, segmentInfo);
|
|
1728
|
+
},
|
|
1623
1729
|
filter: (manifest) => this.filterManifest_(manifest),
|
|
1624
1730
|
makeTextStreamsForClosedCaptions: (manifest) => {
|
|
1625
1731
|
return this.makeTextStreamsForClosedCaptions_(manifest);
|
|
@@ -1780,6 +1886,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1780
1886
|
// something we are now depending on.
|
|
1781
1887
|
has.startTime = wants.startTime;
|
|
1782
1888
|
|
|
1889
|
+
// If updateStartTime() has been called since load() was invoked use the
|
|
1890
|
+
// requested startTime
|
|
1891
|
+
if (this.updatedStartTime_ != null) {
|
|
1892
|
+
has.startTime = this.updatedStartTime_;
|
|
1893
|
+
this.updatedStartTime_ = null;
|
|
1894
|
+
}
|
|
1895
|
+
|
|
1783
1896
|
// Store a reference to values in |has| after asserting so that closure will
|
|
1784
1897
|
// know that they will still be non-null between calls to await.
|
|
1785
1898
|
const mediaElement = has.mediaElement;
|
|
@@ -2177,9 +2290,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2177
2290
|
this.video_.textTracks, 'change', () => this.onTracksChanged_());
|
|
2178
2291
|
}
|
|
2179
2292
|
|
|
2293
|
+
const extension = shaka.media.ManifestParser.getExtension(has.uri);
|
|
2294
|
+
const mimeType =
|
|
2295
|
+
shaka.Player.SRC_EQUAL_EXTENSIONS_TO_MIME_TYPES_[extension];
|
|
2296
|
+
|
|
2180
2297
|
// By setting |src| we are done "loading" with src=. We don't need to set
|
|
2181
2298
|
// the current time because |playhead| will do that for us.
|
|
2182
|
-
has.mediaElement.src = has.uri;
|
|
2299
|
+
has.mediaElement.src = this.cmcdManager_.appendSrcData(has.uri, mimeType);
|
|
2183
2300
|
|
|
2184
2301
|
// Tizen 3 / WebOS won't load anything unless you call load() explicitly,
|
|
2185
2302
|
// no matter the value of the preload attribute. This is harmful on some
|
|
@@ -2509,8 +2626,30 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2509
2626
|
this.abrManager_.segmentDownloaded(deltaTimeMs, bytesDownloaded);
|
|
2510
2627
|
}
|
|
2511
2628
|
};
|
|
2629
|
+
/** @type {shaka.net.NetworkingEngine.OnHeadersReceived} */
|
|
2630
|
+
const onHeadersReceived_ = (headers, request, requestType) => {
|
|
2631
|
+
// Release a 'downloadheadersreceived' event.
|
|
2632
|
+
const name = shaka.Player.EventName.DownloadHeadersReceived;
|
|
2633
|
+
const data = new Map()
|
|
2634
|
+
.set('headers', headers)
|
|
2635
|
+
.set('request', request)
|
|
2636
|
+
.set('requestType', requestType);
|
|
2637
|
+
this.dispatchEvent(this.makeEvent_(name, data));
|
|
2638
|
+
};
|
|
2639
|
+
/** @type {shaka.net.NetworkingEngine.OnDownloadFailed} */
|
|
2640
|
+
const onDownloadFailed_ = (request, error, httpResponseCode, aborted) => {
|
|
2641
|
+
// Release a 'downloadfailed' event.
|
|
2642
|
+
const name = shaka.Player.EventName.DownloadFailed;
|
|
2643
|
+
const data = new Map()
|
|
2644
|
+
.set('request', request)
|
|
2645
|
+
.set('error', error)
|
|
2646
|
+
.set('httpResponseCode', httpResponseCode)
|
|
2647
|
+
.set('aborted', aborted);
|
|
2648
|
+
this.dispatchEvent(this.makeEvent_(name, data));
|
|
2649
|
+
};
|
|
2512
2650
|
|
|
2513
|
-
return new shaka.net.NetworkingEngine(
|
|
2651
|
+
return new shaka.net.NetworkingEngine(
|
|
2652
|
+
onProgressUpdated_, onHeadersReceived_, onDownloadFailed_);
|
|
2514
2653
|
}
|
|
2515
2654
|
|
|
2516
2655
|
/**
|
|
@@ -2547,26 +2686,38 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2547
2686
|
// Create the region observer. This will allow us to notify the app when we
|
|
2548
2687
|
// move in and out of timeline regions.
|
|
2549
2688
|
const regionObserver = new shaka.media.RegionObserver(this.regionTimeline_);
|
|
2550
|
-
|
|
2689
|
+
|
|
2690
|
+
regionObserver.addEventListener('enter', (event) => {
|
|
2691
|
+
/** @type {shaka.extern.TimelineRegionInfo} */
|
|
2692
|
+
const region = event['region'];
|
|
2551
2693
|
this.onRegionEvent_(shaka.Player.EventName.TimelineRegionEnter, region);
|
|
2552
|
-
};
|
|
2553
|
-
|
|
2694
|
+
});
|
|
2695
|
+
|
|
2696
|
+
regionObserver.addEventListener('exit', (event) => {
|
|
2697
|
+
/** @type {shaka.extern.TimelineRegionInfo} */
|
|
2698
|
+
const region = event['region'];
|
|
2554
2699
|
this.onRegionEvent_(shaka.Player.EventName.TimelineRegionExit, region);
|
|
2555
|
-
};
|
|
2556
|
-
|
|
2700
|
+
});
|
|
2701
|
+
|
|
2702
|
+
regionObserver.addEventListener('skip', (event) => {
|
|
2703
|
+
/** @type {shaka.extern.TimelineRegionInfo} */
|
|
2704
|
+
const region = event['region'];
|
|
2705
|
+
/** @type {boolean} */
|
|
2706
|
+
const seeking = event['seeking'];
|
|
2557
2707
|
// If we are seeking, we don't want to surface the enter/exit events since
|
|
2558
2708
|
// they didn't play through them.
|
|
2559
2709
|
if (!seeking) {
|
|
2560
2710
|
this.onRegionEvent_(shaka.Player.EventName.TimelineRegionEnter, region);
|
|
2561
2711
|
this.onRegionEvent_(shaka.Player.EventName.TimelineRegionExit, region);
|
|
2562
2712
|
}
|
|
2563
|
-
};
|
|
2564
|
-
regionObserver.setListeners(onEnterRegion, onExitRegion, onSkipRegion);
|
|
2713
|
+
});
|
|
2565
2714
|
|
|
2566
2715
|
// Now that we have all our observers, create a manager for them.
|
|
2567
2716
|
const manager = new shaka.media.PlayheadObserverManager(this.video_);
|
|
2568
2717
|
manager.manage(regionObserver);
|
|
2569
|
-
|
|
2718
|
+
if (this.qualityObserver_) {
|
|
2719
|
+
manager.manage(this.qualityObserver_);
|
|
2720
|
+
}
|
|
2570
2721
|
return manager;
|
|
2571
2722
|
}
|
|
2572
2723
|
|
|
@@ -2682,6 +2833,26 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2682
2833
|
mediaElement, closedCaptionsParser, textDisplayer, onMetadata);
|
|
2683
2834
|
}
|
|
2684
2835
|
|
|
2836
|
+
/**
|
|
2837
|
+
* Create a new CMCD manager.
|
|
2838
|
+
*
|
|
2839
|
+
* @private
|
|
2840
|
+
*/
|
|
2841
|
+
createCmcd_() {
|
|
2842
|
+
/** @type {shaka.util.CmcdManager.PlayerInterface} */
|
|
2843
|
+
const playerInterface = {
|
|
2844
|
+
getBandwidthEstimate: () => this.abrManager_ ?
|
|
2845
|
+
this.abrManager_.getBandwidthEstimate() : NaN,
|
|
2846
|
+
getBufferedInfo: () => this.getBufferedInfo(),
|
|
2847
|
+
getCurrentTime: () => this.video_ ? this.video_.currentTime : 0,
|
|
2848
|
+
getVariantTracks: () => this.getVariantTracks(),
|
|
2849
|
+
getPlaybackRate: () => this.getPlaybackRate(),
|
|
2850
|
+
isLive: () => this.isLive(),
|
|
2851
|
+
};
|
|
2852
|
+
|
|
2853
|
+
return new shaka.util.CmcdManager(playerInterface, this.config_.cmcd);
|
|
2854
|
+
}
|
|
2855
|
+
|
|
2685
2856
|
/**
|
|
2686
2857
|
* Creates a new instance of StreamingEngine. This can be replaced by tests
|
|
2687
2858
|
* to create fake instances instead.
|
|
@@ -2691,19 +2862,28 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2691
2862
|
createStreamingEngine() {
|
|
2692
2863
|
goog.asserts.assert(
|
|
2693
2864
|
this.playhead_ && this.abrManager_ && this.mediaSourceEngine_ &&
|
|
2694
|
-
this.manifest_,
|
|
2865
|
+
this.cmcdManager_ && this.manifest_,
|
|
2695
2866
|
'Must not be destroyed');
|
|
2696
2867
|
|
|
2697
2868
|
/** @type {shaka.media.StreamingEngine.PlayerInterface} */
|
|
2698
2869
|
const playerInterface = {
|
|
2699
2870
|
getPresentationTime: () => this.playhead_.getTime(),
|
|
2700
2871
|
getBandwidthEstimate: () => this.abrManager_.getBandwidthEstimate(),
|
|
2872
|
+
modifySegmentRequest: (request, segmentInfo) => {
|
|
2873
|
+
this.cmcdManager_.applySegmentData(request, segmentInfo);
|
|
2874
|
+
},
|
|
2701
2875
|
mediaSourceEngine: this.mediaSourceEngine_,
|
|
2702
2876
|
netEngine: this.networkingEngine_,
|
|
2703
2877
|
onError: (error) => this.onError_(error),
|
|
2704
2878
|
onEvent: (event) => this.dispatchEvent(event),
|
|
2705
2879
|
onManifestUpdate: () => this.onManifestUpdate_(),
|
|
2706
2880
|
onSegmentAppended: () => this.onSegmentAppended_(),
|
|
2881
|
+
onInitSegmentAppended: (position, initSegment) => {
|
|
2882
|
+
const mediaQuality = initSegment.getMediaQuality();
|
|
2883
|
+
if (mediaQuality && this.qualityObserver_) {
|
|
2884
|
+
this.qualityObserver_.addMediaQualityChange(mediaQuality, position);
|
|
2885
|
+
}
|
|
2886
|
+
},
|
|
2707
2887
|
};
|
|
2708
2888
|
|
|
2709
2889
|
return new shaka.media.StreamingEngine(this.manifest_, playerInterface);
|
|
@@ -3454,7 +3634,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3454
3634
|
const height = fullImageHeight / rows;
|
|
3455
3635
|
const totalImages = columns * rows;
|
|
3456
3636
|
const segmentDuration = reference.trueEndTime - reference.startTime;
|
|
3457
|
-
const thumbnailDuration =
|
|
3637
|
+
const thumbnailDuration =
|
|
3638
|
+
reference.getTileDuration() || (segmentDuration / totalImages);
|
|
3458
3639
|
let thumbnailTime = reference.startTime;
|
|
3459
3640
|
let positionX = 0;
|
|
3460
3641
|
let positionY = 0;
|
|
@@ -3477,6 +3658,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3477
3658
|
positionY = Math.floor(thumbnailPosition / columns) * height;
|
|
3478
3659
|
}
|
|
3479
3660
|
return {
|
|
3661
|
+
imageHeight: fullImageHeight,
|
|
3662
|
+
imageWidth: fullImageWidth,
|
|
3480
3663
|
height: height,
|
|
3481
3664
|
positionX: positionX,
|
|
3482
3665
|
positionY: positionY,
|
|
@@ -3878,20 +4061,24 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3878
4061
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
3879
4062
|
const inputlanguage = LanguageUtils.normalize(language);
|
|
3880
4063
|
const chaptersTracks = this.getChaptersTracks_();
|
|
3881
|
-
const
|
|
3882
|
-
.
|
|
3883
|
-
if (!
|
|
4064
|
+
const chaptersTracksWithLanguage = chaptersTracks
|
|
4065
|
+
.filter((t) => LanguageUtils.normalize(t.language) == inputlanguage);
|
|
4066
|
+
if (!chaptersTracksWithLanguage || !chaptersTracksWithLanguage.length) {
|
|
3884
4067
|
return [];
|
|
3885
4068
|
}
|
|
3886
4069
|
const chapters = [];
|
|
3887
|
-
for (const
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
4070
|
+
for (const chaptersTrack of chaptersTracksWithLanguage) {
|
|
4071
|
+
if (chaptersTrack && chaptersTrack.cues) {
|
|
4072
|
+
for (const cue of chaptersTrack.cues) {
|
|
4073
|
+
/** @type {shaka.extern.Chapter} */
|
|
4074
|
+
const chapter = {
|
|
4075
|
+
title: cue.text,
|
|
4076
|
+
startTime: cue.startTime,
|
|
4077
|
+
endTime: cue.endTime,
|
|
4078
|
+
};
|
|
4079
|
+
chapters.push(chapter);
|
|
4080
|
+
}
|
|
4081
|
+
}
|
|
3895
4082
|
}
|
|
3896
4083
|
return chapters;
|
|
3897
4084
|
}
|
|
@@ -4267,7 +4454,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4267
4454
|
}
|
|
4268
4455
|
const trackElement =
|
|
4269
4456
|
/** @type {!HTMLTrackElement} */(document.createElement('track'));
|
|
4270
|
-
trackElement.src = uri;
|
|
4457
|
+
trackElement.src = this.cmcdManager_.appendTextTrackData(uri);
|
|
4271
4458
|
trackElement.label = label || '';
|
|
4272
4459
|
trackElement.kind = kind;
|
|
4273
4460
|
trackElement.srclang = language;
|
|
@@ -4605,7 +4792,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4605
4792
|
}
|
|
4606
4793
|
const trackElement =
|
|
4607
4794
|
/** @type {!HTMLTrackElement} */(document.createElement('track'));
|
|
4608
|
-
trackElement.src = uri;
|
|
4795
|
+
trackElement.src = this.cmcdManager_.appendTextTrackData(uri);
|
|
4609
4796
|
trackElement.label = label;
|
|
4610
4797
|
trackElement.kind = kind;
|
|
4611
4798
|
trackElement.srclang = language;
|
|
@@ -4634,6 +4821,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4634
4821
|
const request = shaka.net.NetworkingEngine.makeRequest([uri], retryParams);
|
|
4635
4822
|
request.method = 'GET';
|
|
4636
4823
|
|
|
4824
|
+
this.cmcdManager_.applyTextData(request);
|
|
4825
|
+
|
|
4637
4826
|
const response = await netEngine.request(type, request).promise;
|
|
4638
4827
|
|
|
4639
4828
|
return response.data;
|
|
@@ -5031,6 +5220,9 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5031
5220
|
|
|
5032
5221
|
if (loaded) {
|
|
5033
5222
|
this.playRateController_.setBuffering(isBuffering);
|
|
5223
|
+
if (this.cmcdManager_) {
|
|
5224
|
+
this.cmcdManager_.setBuffering(isBuffering);
|
|
5225
|
+
}
|
|
5034
5226
|
this.updateStateHistory_();
|
|
5035
5227
|
}
|
|
5036
5228
|
|
|
@@ -5505,6 +5697,38 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5505
5697
|
this.dispatchEvent(this.makeEvent_(eventName, data));
|
|
5506
5698
|
}
|
|
5507
5699
|
|
|
5700
|
+
/**
|
|
5701
|
+
* When notified of a media quality change we need to emit a
|
|
5702
|
+
* MediaQualityChange event to the app.
|
|
5703
|
+
*
|
|
5704
|
+
* @param {shaka.extern.MediaQualityInfo} mediaQuality
|
|
5705
|
+
* @param {number} position
|
|
5706
|
+
*
|
|
5707
|
+
* @private
|
|
5708
|
+
*/
|
|
5709
|
+
onMediaQualityChange_(mediaQuality, position) {
|
|
5710
|
+
// Always make a copy to avoid exposing our internal data to the app.
|
|
5711
|
+
const clone = {
|
|
5712
|
+
bandwidth: mediaQuality.bandwidth,
|
|
5713
|
+
audioSamplingRate: mediaQuality.audioSamplingRate,
|
|
5714
|
+
codecs: mediaQuality.codecs,
|
|
5715
|
+
contentType: mediaQuality.contentType,
|
|
5716
|
+
frameRate: mediaQuality.frameRate,
|
|
5717
|
+
height: mediaQuality.height,
|
|
5718
|
+
mimeType: mediaQuality.mimeType,
|
|
5719
|
+
channelsCount: mediaQuality.channelsCount,
|
|
5720
|
+
pixelAspectRatio: mediaQuality.pixelAspectRatio,
|
|
5721
|
+
width: mediaQuality.width,
|
|
5722
|
+
};
|
|
5723
|
+
|
|
5724
|
+
const data = new Map()
|
|
5725
|
+
.set('mediaQuality', clone)
|
|
5726
|
+
.set('position', position);
|
|
5727
|
+
|
|
5728
|
+
this.dispatchEvent(this.makeEvent_(
|
|
5729
|
+
shaka.Player.EventName.MediaQualityChanged, data));
|
|
5730
|
+
}
|
|
5731
|
+
|
|
5508
5732
|
/**
|
|
5509
5733
|
* Turn the media element's error object into a Shaka Player error object.
|
|
5510
5734
|
*
|
|
@@ -6268,6 +6492,8 @@ shaka.Player.EventName = {
|
|
|
6268
6492
|
AbrStatusChanged: 'abrstatuschanged',
|
|
6269
6493
|
Adaptation: 'adaptation',
|
|
6270
6494
|
Buffering: 'buffering',
|
|
6495
|
+
DownloadFailed: 'downloadfailed',
|
|
6496
|
+
DownloadHeadersReceived: 'downloadheadersreceived',
|
|
6271
6497
|
DrmSessionUpdate: 'drmsessionupdate',
|
|
6272
6498
|
Emsg: 'emsg',
|
|
6273
6499
|
Error: 'error',
|
|
@@ -6276,6 +6502,7 @@ shaka.Player.EventName = {
|
|
|
6276
6502
|
Loaded: 'loaded',
|
|
6277
6503
|
Loading: 'loading',
|
|
6278
6504
|
ManifestParsed: 'manifestparsed',
|
|
6505
|
+
MediaQualityChanged: 'mediaqualitychanged',
|
|
6279
6506
|
Metadata: 'metadata',
|
|
6280
6507
|
OnStateChange: 'onstatechange',
|
|
6281
6508
|
OnStateIdle: 'onstateidle',
|
|
@@ -6331,7 +6558,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6331
6558
|
* @define {string} A version number taken from git at compile time.
|
|
6332
6559
|
* @export
|
|
6333
6560
|
*/
|
|
6334
|
-
shaka.Player.version = 'v3.
|
|
6561
|
+
shaka.Player.version = 'v3.3.2-uncompiled'; // x-release-please-version
|
|
6335
6562
|
|
|
6336
6563
|
// Initialize the deprecation system using the version string we just set
|
|
6337
6564
|
// on the player.
|
|
@@ -24,8 +24,6 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
24
24
|
* @export
|
|
25
25
|
*/
|
|
26
26
|
static install() {
|
|
27
|
-
shaka.log.debug('MediaCapabilities: install');
|
|
28
|
-
|
|
29
27
|
// Since MediaCapabilities is not fully supported on Chromecast yet, we
|
|
30
28
|
// should always install polyfill for Chromecast.
|
|
31
29
|
// TODO: re-evaluate MediaCapabilities in the future versions of Chromecast.
|
|
@@ -40,21 +38,28 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
40
38
|
// TODO: re-evaluate MediaCapabilities in the future versions of PS5
|
|
41
39
|
// Browsers.
|
|
42
40
|
if (!shaka.util.Platform.isChromecast() &&
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
shaka.log.
|
|
41
|
+
!shaka.util.Platform.isApple() &&
|
|
42
|
+
!shaka.util.Platform.isPS5() &&
|
|
43
|
+
navigator.mediaCapabilities) {
|
|
44
|
+
shaka.log.info(
|
|
47
45
|
'MediaCapabilities: Native mediaCapabilities support found.');
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
shaka.log.info('MediaCapabilities: install');
|
|
50
|
+
|
|
51
|
+
if (!navigator.mediaCapabilities) {
|
|
52
|
+
navigator.mediaCapabilities = /** @type {!MediaCapabilities} */ ({});
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
// MediaCapabilities
|
|
57
|
-
|
|
54
|
+
|
|
55
|
+
// Keep the patched MediaCapabilities object from being garbage-collected in
|
|
56
|
+
// Safari.
|
|
57
|
+
// See https://github.com/google/shaka-player/issues/3696#issuecomment-1009472718
|
|
58
|
+
shaka.polyfill.MediaCapabilities.originalMcap =
|
|
59
|
+
navigator.mediaCapabilities;
|
|
60
|
+
|
|
61
|
+
navigator.mediaCapabilities.decodingInfo =
|
|
62
|
+
shaka.polyfill.MediaCapabilities.decodingInfo_;
|
|
58
63
|
}
|
|
59
64
|
|
|
60
65
|
/**
|
|
@@ -182,6 +187,16 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
182
187
|
}
|
|
183
188
|
};
|
|
184
189
|
|
|
190
|
+
/**
|
|
191
|
+
* A copy of the MediaCapabilities instance, to prevent Safari from
|
|
192
|
+
* garbage-collecting the polyfilled method on it. We make it public and export
|
|
193
|
+
* it to ensure that it is not stripped out by the compiler.
|
|
194
|
+
*
|
|
195
|
+
* @type {MediaCapabilities}
|
|
196
|
+
* @export
|
|
197
|
+
*/
|
|
198
|
+
shaka.polyfill.MediaCapabilities.originalMcap = null;
|
|
199
|
+
|
|
185
200
|
// Install at a lower priority than MediaSource polyfill, so that we have
|
|
186
201
|
// MediaSource available first.
|
|
187
202
|
shaka.polyfill.register(shaka.polyfill.MediaCapabilities.install, -1);
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/*! @license
|
|
2
|
+
* Shaka Player
|
|
3
|
+
* Copyright 2016 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
goog.provide('shaka.polyfill.RandomUUID');
|
|
7
|
+
|
|
8
|
+
goog.require('shaka.log');
|
|
9
|
+
goog.require('shaka.polyfill');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @summary A polyfill to provide window.crypto.randomUUID in all browsers.
|
|
13
|
+
* @export
|
|
14
|
+
*/
|
|
15
|
+
shaka.polyfill.RandomUUID = class {
|
|
16
|
+
/**
|
|
17
|
+
* Install the polyfill if needed.
|
|
18
|
+
* @export
|
|
19
|
+
*/
|
|
20
|
+
static install() {
|
|
21
|
+
shaka.log.debug('randomUUID.install');
|
|
22
|
+
|
|
23
|
+
if (!window.crypto) {
|
|
24
|
+
// See: https://caniuse.com/cryptography
|
|
25
|
+
shaka.log.debug(
|
|
26
|
+
'window.crypto must be available to install randomUUID polyfill.');
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if ('randomUUID' in window.crypto) {
|
|
31
|
+
shaka.log.debug(
|
|
32
|
+
'RandomUUID: Native window.crypto.randomUUID() support found.');
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
window.crypto.randomUUID = shaka.polyfill.RandomUUID.randomUUID_;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @return {string}
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
static randomUUID_() {
|
|
44
|
+
const url = URL.createObjectURL(new Blob());
|
|
45
|
+
const uuid = url.toString();
|
|
46
|
+
URL.revokeObjectURL(url);
|
|
47
|
+
return uuid.substr(uuid.lastIndexOf('/') + 1);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
shaka.polyfill.register(shaka.polyfill.RandomUUID.install);
|
package/lib/text/cue.js
CHANGED
|
@@ -144,6 +144,18 @@ shaka.text.Cue = class {
|
|
|
144
144
|
*/
|
|
145
145
|
this.border = '';
|
|
146
146
|
|
|
147
|
+
/**
|
|
148
|
+
* @override
|
|
149
|
+
* @exportInterface
|
|
150
|
+
*/
|
|
151
|
+
this.textStrokeColor = '';
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @override
|
|
155
|
+
* @exportInterface
|
|
156
|
+
*/
|
|
157
|
+
this.textStrokeWidth = '';
|
|
158
|
+
|
|
147
159
|
/**
|
|
148
160
|
* @override
|
|
149
161
|
* @exportInterface
|
|
@@ -210,6 +222,12 @@ shaka.text.Cue = class {
|
|
|
210
222
|
*/
|
|
211
223
|
this.nestedCues = [];
|
|
212
224
|
|
|
225
|
+
/**
|
|
226
|
+
* @override
|
|
227
|
+
* @exportInterface
|
|
228
|
+
*/
|
|
229
|
+
this.isContainer = false;
|
|
230
|
+
|
|
213
231
|
/**
|
|
214
232
|
* @override
|
|
215
233
|
* @exportInterface
|