shaka-player 4.3.5 → 4.3.6
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/workflows/selenium-lab-tests.yaml +23 -1
- package/AUTHORS +2 -1
- package/CHANGELOG.md +32 -0
- package/CONTRIBUTORS +4 -1
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +167 -296
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +167 -296
- package/dist/demo.compiled.map +4 -4
- package/dist/deps.js +1 -1
- package/dist/locales.js +32 -32
- package/dist/receiver.compiled.debug.js +34 -63
- package/dist/receiver.compiled.debug.map +4 -4
- package/dist/receiver.compiled.js +34 -63
- package/dist/receiver.compiled.map +4 -4
- package/dist/shaka-player.compiled.d.ts +12 -3
- package/dist/shaka-player.compiled.debug.d.ts +12 -3
- package/dist/shaka-player.compiled.debug.externs.js +20 -14
- package/dist/shaka-player.compiled.debug.js +261 -255
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +20 -14
- package/dist/shaka-player.compiled.js +862 -858
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +12 -3
- package/dist/shaka-player.ui.debug.d.ts +12 -3
- package/dist/shaka-player.ui.debug.externs.js +8 -2
- package/dist/shaka-player.ui.debug.js +271 -264
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +8 -2
- package/dist/shaka-player.ui.js +1005 -1002
- package/dist/shaka-player.ui.map +3 -3
- package/docs/tutorials/a11y.md +0 -4
- package/docs/tutorials/ad_monetization.md +0 -4
- package/docs/tutorials/basic-usage.md +0 -5
- package/docs/tutorials/config.md +0 -5
- package/docs/tutorials/debugging.md +0 -5
- package/docs/tutorials/drm-config.md +0 -5
- package/docs/tutorials/fairplay.md +2 -2
- package/docs/tutorials/license-server-auth.md +0 -5
- package/docs/tutorials/license-wrapping.md +0 -5
- package/docs/tutorials/network-and-buffering-config.md +0 -5
- package/docs/tutorials/ui-customization.md +0 -5
- package/docs/tutorials/ui.md +0 -7
- package/docs/tutorials/welcome.md +0 -5
- package/externs/network_information.js +7 -2
- package/externs/shaka/abr_manager.js +6 -0
- package/externs/shaka/net.js +1 -0
- package/externs/shaka/player.js +13 -7
- package/lib/abr/simple_abr_manager.js +27 -3
- package/lib/ads/client_side_ad_manager.js +6 -3
- package/lib/dash/dash_parser.js +49 -48
- package/lib/debug/log.js +9 -13
- package/lib/hls/hls_parser.js +17 -5
- package/lib/media/media_source_engine.js +27 -9
- package/lib/media/presentation_timeline.js +9 -2
- package/lib/media/segment_index.js +2 -0
- package/lib/media/segment_reference.js +3 -2
- package/lib/media/streaming_engine.js +31 -7
- package/lib/net/http_fetch_plugin.js +79 -57
- package/lib/net/networking_engine.js +1 -0
- package/lib/player.js +22 -3
- package/lib/polyfill/media_capabilities.js +13 -0
- package/lib/text/mp4_vtt_parser.js +4 -0
- package/lib/text/text_engine.js +1 -0
- package/lib/util/manifest_parser_utils.js +1 -2
- package/lib/util/mime_utils.js +11 -0
- package/lib/util/periods.js +5 -5
- package/lib/util/stream_utils.js +2 -2
- package/maintained-branches.md +2 -3
- package/package.json +1 -1
- package/test/dash/dash_parser_live_unit.js +3 -2
- package/test/hls/hls_parser_unit.js +156 -0
- package/test/media/content_workarounds_unit.js +43 -0
- package/test/media/drm_engine_integration.js +4 -17
- package/test/media/streaming_engine_unit.js +6 -1
- package/test/net/networking_engine_unit.js +6 -1
- package/test/player_integration.js +39 -0
- package/test/player_unit.js +57 -0
- package/test/polyfill/media_capabilities_unit.js +1 -0
- package/test/test/assets/text-clip-alt.vtt +63 -0
- package/test/test/util/fake_drm_engine.js +3 -0
- package/test/test/util/fake_media_source_engine.js +4 -0
- package/test/test/util/simple_fakes.js +6 -0
- package/test/test/util/test_scheme.js +9 -14
- package/test/text/mp4_vtt_parser_unit.js +8 -0
- package/test/util/mime_utils_unit.js +10 -0
- package/ui/less/containers.less +4 -0
package/docs/tutorials/a11y.md
CHANGED
|
@@ -222,7 +222,3 @@ before instantiating the player.
|
|
|
222
222
|
// myapp.CustomAdManager is a placeholder name for your ad manager implementation.
|
|
223
223
|
shaka.Player.setAdManagerFactory(() => new myapp.CustomAdManager());
|
|
224
224
|
```
|
|
225
|
-
|
|
226
|
-
#### Continue the Tutorials
|
|
227
|
-
|
|
228
|
-
Next, check out {@tutorial plugins}.
|
package/docs/tutorials/config.md
CHANGED
|
@@ -142,8 +142,3 @@ player.configure({
|
|
|
142
142
|
|
|
143
143
|
For more detail on individual configuration options, please see the API docs for
|
|
144
144
|
{@link shaka.extern.PlayerConfiguration} and {@link shaka.Player#configure}.
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
#### Continue the Tutorials
|
|
148
|
-
|
|
149
|
-
Next, check out {@tutorial network-and-buffering-config}.
|
|
@@ -187,8 +187,3 @@ To sum up, remember these points when debugging your application:
|
|
|
187
187
|
- Use the debug version of Shaka Player for debugging and integration work
|
|
188
188
|
- Refer to the docs for error codes
|
|
189
189
|
- Increase the log level when you need more detail
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
#### Continue the Tutorials
|
|
193
|
-
|
|
194
|
-
Next, check out {@tutorial config}.
|
|
@@ -208,8 +208,3 @@ you should provide an empty string as robustness
|
|
|
208
208
|
##### Other key-systems
|
|
209
209
|
|
|
210
210
|
Values for other key systems are not known to us at this time.
|
|
211
|
-
|
|
212
|
-
#### Continue the Tutorials
|
|
213
|
-
|
|
214
|
-
Next, check out {@tutorial license-server-auth}.
|
|
215
|
-
Or check out {@tutorial fairplay}.
|
|
@@ -72,13 +72,13 @@ is used by the browser to generate the license request. If you don't use the
|
|
|
72
72
|
default content ID derivation, you need to specify a custom init data transform:
|
|
73
73
|
|
|
74
74
|
```js
|
|
75
|
-
player.configure('drm.initDataTransform', (initData, initDataType) => {
|
|
75
|
+
player.configure('drm.initDataTransform', (initData, initDataType, drmInfo) => {
|
|
76
76
|
if (initDataType != 'skd')
|
|
77
77
|
return initData;
|
|
78
78
|
// 'initData' is a buffer containing an 'skd://' URL as a UTF-8 string.
|
|
79
79
|
const skdUri = shaka.util.StringUtils.fromBytesAutoDetect(initData);
|
|
80
80
|
const contentId = getMyContentId(skdUri);
|
|
81
|
-
const cert =
|
|
81
|
+
const cert = drmInfo.serverCertificate;
|
|
82
82
|
return shaka.util.FairPlayUtils.initDataTransform(initData, contentId, cert);
|
|
83
83
|
});
|
|
84
84
|
```
|
|
@@ -166,8 +166,3 @@ using a request filter:
|
|
|
166
166
|
|
|
167
167
|
Load the page again, and the license response will be accepted by the Widevine
|
|
168
168
|
CDM. Open the JavaScript console to see what the server sent back.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
#### Continue the Tutorials
|
|
172
|
-
|
|
173
|
-
Next, check out {@tutorial ui}.
|
|
@@ -117,8 +117,3 @@ URLs in your manifests always use `https:`, or by having it not include the
|
|
|
117
117
|
scheme (e.g., `//example.com/file.mp4`).
|
|
118
118
|
|
|
119
119
|
[CORS]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
#### Continue the Tutorials
|
|
123
|
-
|
|
124
|
-
Next, check out {@tutorial drm-config}.
|
|
@@ -265,8 +265,3 @@ PR contributions to [the gallery repo][] are welcome.
|
|
|
265
265
|
[@lucksy]: https://github.com/lucksy
|
|
266
266
|
[pre-packaged Shaka UI themes]: https://lucksy.github.io/shaka-player-themes/
|
|
267
267
|
[the gallery repo]: https://github.com/lucksy/shaka-player-themes
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
#### Continue the Tutorials
|
|
271
|
-
|
|
272
|
-
Next, check out {@tutorial a11y} to make your custom buttons accessible to screen readers.
|
package/docs/tutorials/ui.md
CHANGED
|
@@ -106,8 +106,3 @@ To subscribe to new releases on GitHub, you can follow
|
|
|
106
106
|
To receive infrequent announcements and surveys from us, you can join our
|
|
107
107
|
[mailing list](https://groups.google.com/forum/#!forum/shaka-player-users).
|
|
108
108
|
The list is very low volume, and can only be written to by us.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
#### Continue the Tutorials
|
|
112
|
-
|
|
113
|
-
Next, check out {@tutorial basic-usage}.
|
|
@@ -19,5 +19,10 @@ NetworkInformation.prototype.saveData;
|
|
|
19
19
|
* @param {string} type
|
|
20
20
|
* @param {Function} listener
|
|
21
21
|
*/
|
|
22
|
-
NetworkInformation.prototype.addEventListener =
|
|
23
|
-
|
|
22
|
+
NetworkInformation.prototype.addEventListener = function(type, listener) {};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param {string} type
|
|
26
|
+
* @param {Function} listener
|
|
27
|
+
*/
|
|
28
|
+
NetworkInformation.prototype.removeEventListener = function(type, listener) {};
|
package/externs/shaka/net.js
CHANGED
package/externs/shaka/player.js
CHANGED
|
@@ -688,9 +688,7 @@ shaka.extern.AdvancedDrmConfiguration;
|
|
|
688
688
|
* clearKeys: !Object.<string, string>,
|
|
689
689
|
* delayLicenseRequestUntilPlayed: boolean,
|
|
690
690
|
* advanced: Object.<string, shaka.extern.AdvancedDrmConfiguration>,
|
|
691
|
-
* initDataTransform:
|
|
692
|
-
* ((function(!Uint8Array, string, ?shaka.extern.DrmInfo):!Uint8Array)|
|
|
693
|
-
* undefined),
|
|
691
|
+
* initDataTransform:(shaka.extern.InitDataTransform|undefined),
|
|
694
692
|
* logLicenseExchange: boolean,
|
|
695
693
|
* updateExpirationTime: number,
|
|
696
694
|
* preferredKeySystems: !Array.<string>,
|
|
@@ -716,10 +714,7 @@ shaka.extern.AdvancedDrmConfiguration;
|
|
|
716
714
|
* <i>Optional.</i> <br>
|
|
717
715
|
* A dictionary which maps key system IDs to advanced DRM configuration for
|
|
718
716
|
* those key systems.
|
|
719
|
-
* @property
|
|
720
|
-
* {((function(!Uint8Array, string, ?shaka.extern.DrmInfo):!Uint8Array)|
|
|
721
|
-
* undefined)}
|
|
722
|
-
* initDataTransform
|
|
717
|
+
* @property {shaka.extern.InitDataTransform|undefined} initDataTransform
|
|
723
718
|
* <i>Optional.</i><br>
|
|
724
719
|
* If given, this function is called with the init data from the
|
|
725
720
|
* manifest/media and should return the (possibly transformed) init data to
|
|
@@ -748,6 +743,17 @@ shaka.extern.AdvancedDrmConfiguration;
|
|
|
748
743
|
*/
|
|
749
744
|
shaka.extern.DrmConfiguration;
|
|
750
745
|
|
|
746
|
+
/**
|
|
747
|
+
* @typedef {function(!Uint8Array, string, ?shaka.extern.DrmInfo):!Uint8Array}
|
|
748
|
+
*
|
|
749
|
+
* @description
|
|
750
|
+
* A callback function to handle custom content ID signaling for FairPlay
|
|
751
|
+
* content.
|
|
752
|
+
*
|
|
753
|
+
* @exportDoc
|
|
754
|
+
*/
|
|
755
|
+
shaka.extern.InitDataTransform;
|
|
756
|
+
|
|
751
757
|
|
|
752
758
|
/**
|
|
753
759
|
* @typedef {{
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
goog.provide('shaka.abr.SimpleAbrManager');
|
|
8
8
|
|
|
9
|
+
goog.require('shaka.util.IReleasable');
|
|
9
10
|
goog.require('goog.asserts');
|
|
10
11
|
goog.require('shaka.abr.EwmaBandwidthEstimator');
|
|
11
12
|
goog.require('shaka.log');
|
|
@@ -32,6 +33,7 @@ goog.require('shaka.util.Timer');
|
|
|
32
33
|
* </p>
|
|
33
34
|
*
|
|
34
35
|
* @implements {shaka.extern.AbrManager}
|
|
36
|
+
* @implements {shaka.util.IReleasable}
|
|
35
37
|
* @export
|
|
36
38
|
*/
|
|
37
39
|
shaka.abr.SimpleAbrManager = class {
|
|
@@ -50,8 +52,8 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
50
52
|
// retrieving information about a user's network connection. We listen
|
|
51
53
|
// to the change event to be able to make quick changes in case the type
|
|
52
54
|
// of connectivity changes.
|
|
53
|
-
if (navigator.connection) {
|
|
54
|
-
|
|
55
|
+
if (navigator.connection && navigator.connection.addEventListener) {
|
|
56
|
+
this.onNetworkInformationChange_ = () => {
|
|
55
57
|
if (this.config_.useNetworkInformation && this.enabled_) {
|
|
56
58
|
this.bandwidthEstimator_ = new shaka.abr.EwmaBandwidthEstimator();
|
|
57
59
|
if (this.config_) {
|
|
@@ -62,7 +64,10 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
62
64
|
this.switch_(chosenVariant);
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
|
-
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
navigator.connection.addEventListener(
|
|
70
|
+
'change', this.onNetworkInformationChange_);
|
|
66
71
|
}
|
|
67
72
|
|
|
68
73
|
/**
|
|
@@ -93,6 +98,9 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
93
98
|
/** @private {ResizeObserver} */
|
|
94
99
|
this.resizeObserver_ = null;
|
|
95
100
|
|
|
101
|
+
/** @private {?function():void} */
|
|
102
|
+
this.onNetworkInformationChange_ = null;
|
|
103
|
+
|
|
96
104
|
/** @private {shaka.util.Timer} */
|
|
97
105
|
this.resizeObserverTimer_ = new shaka.util.Timer(() => {
|
|
98
106
|
if (this.config_.restrictToElementSize) {
|
|
@@ -128,6 +136,22 @@ shaka.abr.SimpleAbrManager = class {
|
|
|
128
136
|
// can start using bandwidth estimates right away after init() is called.
|
|
129
137
|
}
|
|
130
138
|
|
|
139
|
+
/**
|
|
140
|
+
* @override
|
|
141
|
+
* @export
|
|
142
|
+
*/
|
|
143
|
+
release() {
|
|
144
|
+
// stop() should already have been called for unload
|
|
145
|
+
|
|
146
|
+
if (navigator.connection && navigator.connection.removeEventListener) {
|
|
147
|
+
navigator.connection.removeEventListener(
|
|
148
|
+
'change', this.onNetworkInformationChange_);
|
|
149
|
+
this.onNetworkInformationChange_ = null;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.resizeObserverTimer_ = null;
|
|
153
|
+
}
|
|
154
|
+
|
|
131
155
|
|
|
132
156
|
/**
|
|
133
157
|
* @override
|
|
@@ -219,9 +219,9 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
219
219
|
// seen the ads actually play until requestAds() is called.
|
|
220
220
|
// Note: We listen for a play event to avoid autoplay issues that might
|
|
221
221
|
// crash IMA.
|
|
222
|
-
this.
|
|
222
|
+
this.eventManager_.listenOnce(this.video_, 'play', () => {
|
|
223
223
|
this.imaAdsManager_.start();
|
|
224
|
-
}
|
|
224
|
+
});
|
|
225
225
|
} catch (adError) {
|
|
226
226
|
// If there was a problem with the VAST response,
|
|
227
227
|
// we we won't be getting an ad. Hide ad UI if we showed it already
|
|
@@ -440,7 +440,10 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
440
440
|
if (this.ad_.isLinear()) {
|
|
441
441
|
this.adContainer_.setAttribute('ad-active', 'true');
|
|
442
442
|
this.video_.pause();
|
|
443
|
-
this.ad_.setVolume(this.video_.
|
|
443
|
+
this.ad_.setVolume(this.video_.volume);
|
|
444
|
+
if (this.video_.muted) {
|
|
445
|
+
this.ad_.setMuted(true);
|
|
446
|
+
}
|
|
444
447
|
}
|
|
445
448
|
}
|
|
446
449
|
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -1279,55 +1279,56 @@ shaka.dash.DashParser = class {
|
|
|
1279
1279
|
context.period.id + ',' + context.representation.id : '';
|
|
1280
1280
|
|
|
1281
1281
|
/** @type {shaka.extern.Stream} */
|
|
1282
|
-
|
|
1283
|
-
id: this.globalId_++,
|
|
1284
|
-
originalId: context.representation.id,
|
|
1285
|
-
createSegmentIndex: async () => {
|
|
1286
|
-
// If we have a stream with the same context id stored in the map
|
|
1287
|
-
// that has no segmentIndex, we should set the segmentIndex for it.
|
|
1288
|
-
const storedInMap = contextId && context.dynamic &&
|
|
1289
|
-
this.streamMap_[contextId];
|
|
1290
|
-
|
|
1291
|
-
const currentStream = storedInMap ? this.streamMap_[contextId] : stream;
|
|
1292
|
-
if (!currentStream.segmentIndex) {
|
|
1293
|
-
currentStream.segmentIndex = await streamInfo.generateSegmentIndex();
|
|
1294
|
-
}
|
|
1295
|
-
},
|
|
1282
|
+
let stream;
|
|
1296
1283
|
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1284
|
+
if (contextId && this.streamMap_[contextId]) {
|
|
1285
|
+
stream = this.streamMap_[contextId];
|
|
1286
|
+
} else {
|
|
1287
|
+
stream = {
|
|
1288
|
+
id: this.globalId_++,
|
|
1289
|
+
originalId: context.representation.id,
|
|
1290
|
+
createSegmentIndex: () => Promise.resolve(),
|
|
1291
|
+
closeSegmentIndex: () => {
|
|
1292
|
+
if (stream.segmentIndex) {
|
|
1293
|
+
stream.segmentIndex.release();
|
|
1294
|
+
stream.segmentIndex = null;
|
|
1295
|
+
}
|
|
1296
|
+
},
|
|
1297
|
+
segmentIndex: null,
|
|
1298
|
+
mimeType: context.representation.mimeType,
|
|
1299
|
+
codecs: context.representation.codecs,
|
|
1300
|
+
frameRate: context.representation.frameRate,
|
|
1301
|
+
pixelAspectRatio: context.representation.pixelAspectRatio,
|
|
1302
|
+
bandwidth: context.bandwidth,
|
|
1303
|
+
width: context.representation.width,
|
|
1304
|
+
height: context.representation.height,
|
|
1305
|
+
kind,
|
|
1306
|
+
encrypted: contentProtection.drmInfos.length > 0,
|
|
1307
|
+
drmInfos: contentProtection.drmInfos,
|
|
1308
|
+
keyIds,
|
|
1309
|
+
language,
|
|
1310
|
+
label,
|
|
1311
|
+
type: context.adaptationSet.contentType,
|
|
1312
|
+
primary: isPrimary,
|
|
1313
|
+
trickModeVideo: null,
|
|
1314
|
+
emsgSchemeIdUris:
|
|
1315
|
+
context.representation.emsgSchemeIdUris,
|
|
1316
|
+
roles,
|
|
1317
|
+
forced,
|
|
1318
|
+
channelsCount: context.representation.numChannels,
|
|
1319
|
+
audioSamplingRate: context.representation.audioSamplingRate,
|
|
1320
|
+
spatialAudio,
|
|
1321
|
+
closedCaptions,
|
|
1322
|
+
hdr,
|
|
1323
|
+
tilesLayout,
|
|
1324
|
+
matchedStreams: [],
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
stream.createSegmentIndex = async () => {
|
|
1329
|
+
if (!stream.segmentIndex) {
|
|
1330
|
+
stream.segmentIndex = await streamInfo.generateSegmentIndex();
|
|
1331
|
+
}
|
|
1331
1332
|
};
|
|
1332
1333
|
|
|
1333
1334
|
if (contextId && context.dynamic && !this.streamMap_[contextId]) {
|
package/lib/debug/log.js
CHANGED
|
@@ -134,23 +134,19 @@ shaka.log.MAX_LOG_LEVEL = 3;
|
|
|
134
134
|
shaka.log.oneTimeWarningIssued_ = new Set();
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
|
|
138
|
-
// IE9 console methods are not Functions and have no bind.
|
|
139
|
-
if (window.console && window.console.log.bind) {
|
|
137
|
+
if (window.console) {
|
|
140
138
|
/** @private {!Object.<shaka.log.Level, function(...*)>} */
|
|
141
139
|
shaka.log.logMap_ = {
|
|
142
|
-
|
|
143
|
-
[shaka.log.Level.
|
|
144
|
-
[shaka.log.Level.
|
|
145
|
-
[shaka.log.Level.
|
|
146
|
-
[shaka.log.Level.
|
|
147
|
-
[shaka.log.Level.
|
|
148
|
-
[shaka.log.Level.V2]: console.debug.bind(console),
|
|
149
|
-
/* eslint-enable no-restricted-syntax */
|
|
140
|
+
[shaka.log.Level.ERROR]: (...args) => console.error(...args),
|
|
141
|
+
[shaka.log.Level.WARNING]: (...args) => console.warn(...args),
|
|
142
|
+
[shaka.log.Level.INFO]: (...args) => console.info(...args),
|
|
143
|
+
[shaka.log.Level.DEBUG]: (...args) => console.log(...args),
|
|
144
|
+
[shaka.log.Level.V1]: (...args) => console.debug(...args),
|
|
145
|
+
[shaka.log.Level.V2]: (...args) => console.debug(...args),
|
|
150
146
|
};
|
|
151
147
|
|
|
152
|
-
shaka.log.alwaysWarn =
|
|
153
|
-
shaka.log.alwaysError =
|
|
148
|
+
shaka.log.alwaysWarn = (...args) => console.warn(...args);
|
|
149
|
+
shaka.log.alwaysError = (...args) => console.error(...args);
|
|
154
150
|
|
|
155
151
|
if (goog.DEBUG) {
|
|
156
152
|
// Since we don't want to export shaka.log in production builds, we don't
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -1458,9 +1458,9 @@ shaka.hls.HlsParser = class {
|
|
|
1458
1458
|
let codecs = '';
|
|
1459
1459
|
/** @type {string} */
|
|
1460
1460
|
const type = this.getType_(tag);
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1461
|
+
if (type == shaka.util.ManifestParserUtils.ContentType.TEXT) {
|
|
1462
|
+
codecs = tag.getAttributeValue('CODECS') || '';
|
|
1463
|
+
} else if (groupId && this.groupIdToCodecsMap_.has(groupId)) {
|
|
1464
1464
|
codecs = this.groupIdToCodecsMap_.get(groupId);
|
|
1465
1465
|
}
|
|
1466
1466
|
|
|
@@ -1736,6 +1736,13 @@ shaka.hls.HlsParser = class {
|
|
|
1736
1736
|
}
|
|
1737
1737
|
}
|
|
1738
1738
|
|
|
1739
|
+
if (type == ContentType.TEXT) {
|
|
1740
|
+
const firstSegment = realStream.segmentIndex.get(0);
|
|
1741
|
+
if (firstSegment && firstSegment.initSegmentReference) {
|
|
1742
|
+
stream.mimeType = 'application/mp4';
|
|
1743
|
+
}
|
|
1744
|
+
}
|
|
1745
|
+
|
|
1739
1746
|
// Add finishing touches to the stream that can only be done once we have
|
|
1740
1747
|
// more full context on the media as a whole.
|
|
1741
1748
|
if (this.hasEnoughInfoToFinalizeStreams_()) {
|
|
@@ -2371,13 +2378,15 @@ shaka.hls.HlsParser = class {
|
|
|
2371
2378
|
* @param {!Map.<string, string>} variables
|
|
2372
2379
|
* @param {string} absoluteMediaPlaylistUri
|
|
2373
2380
|
* @param {string} type
|
|
2381
|
+
* @param {number} timestampOffset
|
|
2374
2382
|
* @param {shaka.extern.HlsAes128Key=} hlsAes128Key
|
|
2375
2383
|
* @return {shaka.media.SegmentReference}
|
|
2376
2384
|
* @private
|
|
2377
2385
|
*/
|
|
2378
2386
|
createSegmentReference_(
|
|
2379
2387
|
initSegmentReference, previousReference, hlsSegment, startTime,
|
|
2380
|
-
variables, absoluteMediaPlaylistUri, type,
|
|
2388
|
+
variables, absoluteMediaPlaylistUri, type, timestampOffset,
|
|
2389
|
+
hlsAes128Key) {
|
|
2381
2390
|
const tags = hlsSegment.tags;
|
|
2382
2391
|
const absoluteSegmentUri = this.variableSubstitution_(
|
|
2383
2392
|
hlsSegment.absoluteUri, variables);
|
|
@@ -2547,7 +2556,7 @@ shaka.hls.HlsParser = class {
|
|
|
2547
2556
|
startByte,
|
|
2548
2557
|
endByte,
|
|
2549
2558
|
initSegmentReference,
|
|
2550
|
-
|
|
2559
|
+
timestampOffset, // This value is ignored in sequence mode.
|
|
2551
2560
|
/* appendWindowStart= */ 0,
|
|
2552
2561
|
/* appendWindowEnd= */ Infinity,
|
|
2553
2562
|
partialSegmentRefs,
|
|
@@ -2632,6 +2641,7 @@ shaka.hls.HlsParser = class {
|
|
|
2632
2641
|
const references = [];
|
|
2633
2642
|
|
|
2634
2643
|
let previousReference = null;
|
|
2644
|
+
let lastDiscontinuityStartTime = firstStartTime;
|
|
2635
2645
|
|
|
2636
2646
|
for (let i = 0; i < hlsSegments.length; i++) {
|
|
2637
2647
|
const item = hlsSegments[i];
|
|
@@ -2643,6 +2653,7 @@ shaka.hls.HlsParser = class {
|
|
|
2643
2653
|
item.tags, 'EXT-X-DISCONTINUITY');
|
|
2644
2654
|
if (discontinuityTag) {
|
|
2645
2655
|
discontinuitySequence++;
|
|
2656
|
+
lastDiscontinuityStartTime = startTime;
|
|
2646
2657
|
}
|
|
2647
2658
|
|
|
2648
2659
|
// Apply new AES-128 tags as you see them, keeping a running total.
|
|
@@ -2681,6 +2692,7 @@ shaka.hls.HlsParser = class {
|
|
|
2681
2692
|
variables,
|
|
2682
2693
|
playlist.absoluteUri,
|
|
2683
2694
|
type,
|
|
2695
|
+
lastDiscontinuityStartTime,
|
|
2684
2696
|
hlsAes128Key);
|
|
2685
2697
|
previousReference = reference;
|
|
2686
2698
|
|
|
@@ -202,6 +202,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
202
202
|
'audio/mp4; codecs="ec-3"',
|
|
203
203
|
'audio/mp4; codecs="opus"',
|
|
204
204
|
'audio/mp4; codecs="flac"',
|
|
205
|
+
'audio/mp4; codecs="dtsc"', // DTS Digital Surround
|
|
206
|
+
'audio/mp4; codecs="dtse"', // DTS Express
|
|
207
|
+
'audio/mp4; codecs="dtsx"', // DTS:X
|
|
205
208
|
// WebM types
|
|
206
209
|
'video/webm; codecs="vp8"',
|
|
207
210
|
'video/webm; codecs="vp9"',
|
|
@@ -375,7 +378,22 @@ shaka.media.MediaSourceEngine = class {
|
|
|
375
378
|
shaka.media.Transmuxer.convertCodecs(contentType, mimeType);
|
|
376
379
|
}
|
|
377
380
|
const type = mimeType + this.config_.sourceBufferExtraFeatures;
|
|
378
|
-
|
|
381
|
+
|
|
382
|
+
this.destroyer_.ensureNotDestroyed();
|
|
383
|
+
|
|
384
|
+
let sourceBuffer;
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
sourceBuffer = this.mediaSource_.addSourceBuffer(type);
|
|
388
|
+
} catch (exception) {
|
|
389
|
+
throw new shaka.util.Error(
|
|
390
|
+
shaka.util.Error.Severity.CRITICAL,
|
|
391
|
+
shaka.util.Error.Category.MEDIA,
|
|
392
|
+
shaka.util.Error.Code.MEDIA_SOURCE_OPERATION_THREW,
|
|
393
|
+
exception,
|
|
394
|
+
'The mediaSource_ status was' + this.mediaSource_.readyState +
|
|
395
|
+
'expected \'open\'');
|
|
396
|
+
}
|
|
379
397
|
|
|
380
398
|
this.eventManager_.listen(
|
|
381
399
|
sourceBuffer, 'error',
|
|
@@ -628,7 +646,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
628
646
|
// For HLS CEA-608/708 CLOSED-CAPTIONS, text data is embedded in
|
|
629
647
|
// the video stream, so textEngine may not have been initialized.
|
|
630
648
|
if (!this.textEngine_) {
|
|
631
|
-
this.reinitText(
|
|
649
|
+
this.reinitText(shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE,
|
|
650
|
+
this.sequenceMode_);
|
|
632
651
|
}
|
|
633
652
|
// This doesn't work for native TS support (ex. Edge/Chromecast),
|
|
634
653
|
// since no transmuxing is needed for native TS.
|
|
@@ -647,7 +666,8 @@ shaka.media.MediaSourceEngine = class {
|
|
|
647
666
|
data = transmuxedData.data;
|
|
648
667
|
} else if (hasClosedCaptions && contentType == ContentType.VIDEO) {
|
|
649
668
|
if (!this.textEngine_) {
|
|
650
|
-
this.reinitText(
|
|
669
|
+
this.reinitText(shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE,
|
|
670
|
+
this.sequenceMode_);
|
|
651
671
|
}
|
|
652
672
|
if (!this.captionParser_) {
|
|
653
673
|
this.captionParser_ = this.getCaptionParser(mimeType);
|
|
@@ -937,7 +957,6 @@ shaka.media.MediaSourceEngine = class {
|
|
|
937
957
|
|
|
938
958
|
/**
|
|
939
959
|
* Adjust timestamp offset to maintain AV sync across discontinuities.
|
|
940
|
-
* Only used in sequence mode.
|
|
941
960
|
*
|
|
942
961
|
* @param {shaka.util.ManifestParserUtils.ContentType} contentType
|
|
943
962
|
* @param {number} timestampOffset
|
|
@@ -946,9 +965,6 @@ shaka.media.MediaSourceEngine = class {
|
|
|
946
965
|
async resync(contentType, timestampOffset) {
|
|
947
966
|
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
948
967
|
|
|
949
|
-
goog.asserts.assert(this.sequenceMode_,
|
|
950
|
-
'resync only used with sequence mode!');
|
|
951
|
-
|
|
952
968
|
if (contentType == ContentType.TEXT) {
|
|
953
969
|
// This operation is for audio and video only.
|
|
954
970
|
return;
|
|
@@ -978,8 +994,10 @@ shaka.media.MediaSourceEngine = class {
|
|
|
978
994
|
async endOfStream(reason) {
|
|
979
995
|
await this.enqueueBlockingOperation_(() => {
|
|
980
996
|
// If endOfStream() has already been called on the media source,
|
|
981
|
-
// don't call it again.
|
|
982
|
-
|
|
997
|
+
// don't call it again. Also do not call if readyState is
|
|
998
|
+
// 'closed' (not attached to video element) since it is not a
|
|
999
|
+
// valid operation.
|
|
1000
|
+
if (this.ended() || this.mediaSource_.readyState === 'closed') {
|
|
983
1001
|
return;
|
|
984
1002
|
}
|
|
985
1003
|
// Tizen won't let us pass undefined, but it will let us omit the
|
|
@@ -236,7 +236,16 @@ shaka.media.PresentationTimeline = class {
|
|
|
236
236
|
|
|
237
237
|
let firstReferenceStartTime = references[0].startTime;
|
|
238
238
|
let lastReferenceEndTime = references[0].endTime;
|
|
239
|
+
|
|
240
|
+
// Date.now() is in milliseconds, from which we compute "now" in seconds.
|
|
241
|
+
const now = (Date.now() + this.clockOffset_) / 1000.0;
|
|
242
|
+
|
|
239
243
|
for (const reference of references) {
|
|
244
|
+
// Exclude segments that are in the "future".
|
|
245
|
+
if (now < reference.startTime) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
|
|
240
249
|
firstReferenceStartTime = Math.min(
|
|
241
250
|
firstReferenceStartTime, reference.startTime);
|
|
242
251
|
lastReferenceEndTime = Math.max(lastReferenceEndTime, reference.endTime);
|
|
@@ -251,8 +260,6 @@ shaka.media.PresentationTimeline = class {
|
|
|
251
260
|
!this.startTimeLocked_) {
|
|
252
261
|
// Since we have explicit segment end times, calculate a presentation
|
|
253
262
|
// start based on them. This start time accounts for drift.
|
|
254
|
-
// Date.now() is in milliseconds, from which we compute "now" in seconds.
|
|
255
|
-
const now = (Date.now() + this.clockOffset_) / 1000.0;
|
|
256
263
|
this.presentationStartTime_ =
|
|
257
264
|
now - this.maxSegmentEndTime_ - this.maxSegmentDuration_;
|
|
258
265
|
}
|
|
@@ -144,8 +144,9 @@ shaka.media.SegmentReference = class {
|
|
|
144
144
|
* minus the first segment's tfdt box's 'baseMediaDecodeTime' field (after
|
|
145
145
|
* it has been converted to seconds).
|
|
146
146
|
* <br>
|
|
147
|
-
* For HLS, this value should be
|
|
148
|
-
*
|
|
147
|
+
* For HLS, this value should be the start time of the most recent
|
|
148
|
+
* discontinuity, or 0 if there is no preceding discontinuity. Only used
|
|
149
|
+
* in segments mode.
|
|
149
150
|
* @param {number} appendWindowStart
|
|
150
151
|
* The start of the append window for this reference, relative to the
|
|
151
152
|
* presentation. Any content from before this time will be removed by
|