shaka-player 3.1.3 → 3.1.4
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 +3 -0
- package/CHANGELOG.md +56 -0
- package/CONTRIBUTORS +3 -0
- package/build/generateExterns.js +1 -1
- package/demo/common/assets.js +1 -1
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +1 -1
- package/dist/demo.compiled.js +1 -1
- package/dist/deps.js +1 -1
- package/dist/locales.js +35 -35
- package/dist/receiver.compiled.debug.js +1 -1
- package/dist/receiver.compiled.js +1 -1
- package/dist/shaka-player.compiled.d.ts +1 -1
- package/dist/shaka-player.compiled.debug.d.ts +1 -1
- package/dist/shaka-player.compiled.debug.externs.js +1 -1
- package/dist/shaka-player.compiled.debug.js +187 -183
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +1 -1
- package/dist/shaka-player.compiled.js +799 -799
- package/dist/shaka-player.compiled.map +2 -2
- package/dist/shaka-player.ui.d.ts +1 -1
- package/dist/shaka-player.ui.debug.d.ts +1 -1
- package/dist/shaka-player.ui.debug.externs.js +3 -3
- package/dist/shaka-player.ui.debug.js +264 -260
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +3 -3
- package/dist/shaka-player.ui.js +896 -895
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +1 -1
- package/karma.conf.js +1 -0
- package/lib/ads/client_side_ad_manager.js +46 -86
- package/lib/ads/server_side_ad_manager.js +7 -10
- package/lib/cast/cast_proxy.js +3 -2
- package/lib/cast/cast_receiver.js +2 -1
- package/lib/cast/cast_sender.js +2 -2
- package/lib/dash/dash_parser.js +93 -2
- package/lib/dash/segment_list.js +1 -1
- package/lib/dash/segment_template.js +1 -1
- package/lib/hls/hls_parser.js +30 -17
- package/lib/media/drm_engine.js +7 -0
- package/lib/media/gap_jumping_controller.js +4 -2
- package/lib/media/media_source_engine.js +1 -2
- package/lib/media/streaming_engine.js +2 -1
- package/lib/net/networking_engine.js +2 -1
- package/lib/player.js +22 -22
- package/lib/polyfill/media_capabilities.js +7 -1
- package/lib/polyfill/mediasource.js +6 -0
- package/lib/polyfill/orientation.js +1 -1
- package/lib/polyfill/patchedmediakeys_apple.js +4 -4
- package/lib/polyfill/patchedmediakeys_ms.js +4 -4
- package/lib/polyfill/patchedmediakeys_webkit.js +4 -4
- package/lib/text/mp4_ttml_parser.js +3 -0
- package/lib/text/text_engine.js +14 -2
- package/lib/text/ttml_text_parser.js +5 -0
- package/lib/text/ui_text_displayer.js +85 -37
- package/lib/util/fake_event.js +53 -7
- package/lib/util/periods.js +4 -1
- package/lib/util/platform.js +13 -1
- package/lib/util/stream_utils.js +13 -0
- package/package.json +1 -1
- package/test/cast/cast_proxy_unit.js +12 -6
- package/test/cast/cast_utils_unit.js +1 -1
- package/test/dash/dash_parser_manifest_unit.js +187 -1
- package/test/hls/hls_parser_unit.js +5 -1
- package/test/media/closed_caption_parser_unit.js +6 -1
- package/test/media/drm_engine_unit.js +43 -0
- package/test/player_integration.js +38 -0
- package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
- package/test/test/assets/3675/dash_0.mpd +30 -0
- package/test/test/assets/3675/dash_1.mpd +30 -0
- package/test/test/assets/3675/dash_2.mpd +30 -0
- package/test/test/assets/3675/dash_3.mpd +30 -0
- package/test/test/assets/3675/dash_4.mpd +30 -0
- package/test/test/assets/3675/dash_5.mpd +26 -0
- package/test/test/assets/3675/init-stream0.m4s +0 -0
- package/test/test/util/fake_ad_manager.js +1 -1
- package/test/text/ttml_text_parser_unit.js +9 -0
- package/test/text/ui_text_displayer_unit.js +29 -17
- package/test/ui/localization_unit.js +15 -14
- package/test/ui/text_displayer_layout_unit.js +13 -1
- package/test/util/stream_utils_unit.js +35 -0
- package/ui/cast_button.js +2 -3
- package/ui/controls.js +4 -6
- package/ui/less/containers.less +3 -7
- package/ui/locales/ru.json +6 -6
- package/ui/localization.js +28 -51
- package/ui/pip_button.js +2 -3
|
@@ -31,7 +31,7 @@ player.configure('drm.initDataTransform', (initData, initDataType) => {
|
|
|
31
31
|
|
|
32
32
|
// 'initData' is a buffer containing an 'skd://' URL as a UTF-8 string.
|
|
33
33
|
const skdUri = shaka.util.StringUtils.fromBytesAutoDetect(initData);
|
|
34
|
-
const contentId = getMyContentId(
|
|
34
|
+
const contentId = getMyContentId(skdUri);
|
|
35
35
|
const cert = player.drmInfo().serverCertificate;
|
|
36
36
|
return shaka.util.FairPlayUtils.initDataTransform(initData, contentId, cert);
|
|
37
37
|
});
|
package/karma.conf.js
CHANGED
|
@@ -140,6 +140,7 @@ module.exports = (config) => {
|
|
|
140
140
|
included: false,
|
|
141
141
|
},
|
|
142
142
|
{pattern: 'test/test/assets/*', included: false},
|
|
143
|
+
{pattern: 'test/test/assets/3675/*', included: false},
|
|
143
144
|
{pattern: 'dist/shaka-player.ui.js', included: false},
|
|
144
145
|
{pattern: 'dist/locales.js', included: false},
|
|
145
146
|
{pattern: 'demo/locales/en.json', included: false},
|
|
@@ -138,7 +138,7 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
138
138
|
// Remove ad breaks from the timeline
|
|
139
139
|
this.onEvent_(
|
|
140
140
|
new shaka.util.FakeEvent(shaka.ads.AdManager.CUEPOINTS_CHANGED,
|
|
141
|
-
|
|
141
|
+
(new Map()).set('cuepoints', [])));
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
|
|
@@ -151,17 +151,14 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
151
151
|
|
|
152
152
|
const now = Date.now() / 1000;
|
|
153
153
|
const loadTime = now - this.requestAdsStartTime_;
|
|
154
|
-
this.onEvent_(
|
|
155
|
-
new
|
|
156
|
-
{'loadTime': loadTime}));
|
|
154
|
+
this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.ADS_LOADED,
|
|
155
|
+
(new Map()).set('loadTime', loadTime)));
|
|
157
156
|
|
|
158
157
|
this.imaAdsManager_ = e.getAdsManager(this.video_);
|
|
159
158
|
|
|
160
159
|
this.onEvent_(new shaka.util.FakeEvent(
|
|
161
160
|
shaka.ads.AdManager.IMA_AD_MANAGER_LOADED,
|
|
162
|
-
|
|
163
|
-
'imaAdManager': this.imaAdsManager_,
|
|
164
|
-
}));
|
|
161
|
+
(new Map()).set('imaAdManager', this.imaAdsManager_)));
|
|
165
162
|
|
|
166
163
|
const cuePointStarts = this.imaAdsManager_.getCuePoints();
|
|
167
164
|
if (cuePointStarts.length) {
|
|
@@ -172,9 +169,9 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
172
169
|
cuePoints.push(shakaCuePoint);
|
|
173
170
|
}
|
|
174
171
|
|
|
175
|
-
this.onEvent_(
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
this.onEvent_(new shaka.util.FakeEvent(
|
|
173
|
+
shaka.ads.AdManager.CUEPOINTS_CHANGED,
|
|
174
|
+
(new Map()).set('cuepoints', cuePoints)));
|
|
178
175
|
}
|
|
179
176
|
|
|
180
177
|
this.addImaEventListeners_();
|
|
@@ -224,6 +221,15 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
224
221
|
* @private
|
|
225
222
|
*/
|
|
226
223
|
addImaEventListeners_() {
|
|
224
|
+
/**
|
|
225
|
+
* @param {!Event} e
|
|
226
|
+
* @param {string} type
|
|
227
|
+
*/
|
|
228
|
+
const convertEventAndSend = (e, type) => {
|
|
229
|
+
const data = (new Map()).set('originalEvent', e);
|
|
230
|
+
this.onEvent_(new shaka.util.FakeEvent(type, data));
|
|
231
|
+
};
|
|
232
|
+
|
|
227
233
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
228
234
|
google.ima.AdErrorEvent.Type.AD_ERROR, (error) => {
|
|
229
235
|
this.onAdError_(/** @type {!google.ima.AdErrorEvent} */ (error));
|
|
@@ -241,30 +247,22 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
241
247
|
|
|
242
248
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
243
249
|
google.ima.AdEvent.Type.FIRST_QUARTILE, (e) => {
|
|
244
|
-
|
|
245
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_FIRST_QUARTILE,
|
|
246
|
-
{'originalEvent': e}));
|
|
250
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_FIRST_QUARTILE);
|
|
247
251
|
});
|
|
248
252
|
|
|
249
253
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
250
254
|
google.ima.AdEvent.Type.MIDPOINT, (e) => {
|
|
251
|
-
|
|
252
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_MIDPOINT,
|
|
253
|
-
{'originalEvent': e}));
|
|
255
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_MIDPOINT);
|
|
254
256
|
});
|
|
255
257
|
|
|
256
258
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
257
259
|
google.ima.AdEvent.Type.THIRD_QUARTILE, (e) => {
|
|
258
|
-
|
|
259
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_THIRD_QUARTILE,
|
|
260
|
-
{'originalEvent': e}));
|
|
260
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_THIRD_QUARTILE);
|
|
261
261
|
});
|
|
262
262
|
|
|
263
263
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
264
264
|
google.ima.AdEvent.Type.COMPLETE, (e) => {
|
|
265
|
-
|
|
266
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_COMPLETE,
|
|
267
|
-
{'originalEvent': e}));
|
|
265
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_COMPLETE);
|
|
268
266
|
});
|
|
269
267
|
|
|
270
268
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
@@ -279,140 +277,102 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
279
277
|
|
|
280
278
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
281
279
|
google.ima.AdEvent.Type.SKIPPED, (e) => {
|
|
282
|
-
|
|
283
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_SKIPPED,
|
|
284
|
-
{'originalEvent': e}));
|
|
280
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_SKIPPED);
|
|
285
281
|
});
|
|
286
282
|
|
|
287
283
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
288
284
|
google.ima.AdEvent.Type.VOLUME_CHANGED, (e) => {
|
|
289
|
-
|
|
290
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_VOLUME_CHANGED,
|
|
291
|
-
{'originalEvent': e}));
|
|
285
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_VOLUME_CHANGED);
|
|
292
286
|
});
|
|
293
287
|
|
|
294
288
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
295
289
|
google.ima.AdEvent.Type.VOLUME_MUTED, (e) => {
|
|
296
|
-
|
|
297
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_MUTED,
|
|
298
|
-
{'originalEvent': e}));
|
|
290
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_MUTED);
|
|
299
291
|
});
|
|
300
292
|
|
|
301
293
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
302
294
|
google.ima.AdEvent.Type.PAUSED, (e) => {
|
|
303
295
|
goog.asserts.assert(this.ad_ != null, 'Ad should not be null!');
|
|
304
296
|
this.ad_.setPaused(true);
|
|
305
|
-
|
|
306
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_PAUSED,
|
|
307
|
-
{'originalEvent': e}));
|
|
297
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_PAUSED);
|
|
308
298
|
});
|
|
309
299
|
|
|
310
300
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
311
301
|
google.ima.AdEvent.Type.RESUMED, (e) => {
|
|
312
302
|
goog.asserts.assert(this.ad_ != null, 'Ad should not be null!');
|
|
313
303
|
this.ad_.setPaused(false);
|
|
314
|
-
|
|
315
|
-
new shaka.util.FakeEvent(shaka.ads.AdManager.AD_RESUMED,
|
|
316
|
-
{'originalEvent': e}));
|
|
304
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_RESUMED);
|
|
317
305
|
});
|
|
318
306
|
|
|
319
307
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
320
308
|
google.ima.AdEvent.Type.SKIPPABLE_STATE_CHANGED, (e) => {
|
|
321
309
|
goog.asserts.assert(this.ad_ != null, 'Ad should not be null!');
|
|
322
|
-
|
|
323
|
-
shaka.ads.AdManager.AD_SKIP_STATE_CHANGED,
|
|
324
|
-
{'originalEvent': e}));
|
|
310
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_SKIP_STATE_CHANGED);
|
|
325
311
|
});
|
|
326
312
|
|
|
327
313
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
328
314
|
google.ima.AdEvent.Type.CLICK, (e) => {
|
|
329
|
-
|
|
330
|
-
shaka.ads.AdManager.AD_CLICKED,
|
|
331
|
-
{'originalEvent': e}));
|
|
315
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_CLICKED);
|
|
332
316
|
});
|
|
333
317
|
|
|
334
318
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
335
319
|
google.ima.AdEvent.Type.AD_PROGRESS, (e) => {
|
|
336
|
-
|
|
337
|
-
shaka.ads.AdManager.AD_PROGRESS,
|
|
338
|
-
{'originalEvent': e}));
|
|
320
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_PROGRESS);
|
|
339
321
|
});
|
|
340
322
|
|
|
341
323
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
342
324
|
google.ima.AdEvent.Type.AD_BUFFERING, (e) => {
|
|
343
|
-
|
|
344
|
-
shaka.ads.AdManager.AD_BUFFERING,
|
|
345
|
-
{'originalEvent': e}));
|
|
325
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_BUFFERING);
|
|
346
326
|
});
|
|
347
327
|
|
|
348
328
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
349
329
|
google.ima.AdEvent.Type.IMPRESSION, (e) => {
|
|
350
|
-
|
|
351
|
-
shaka.ads.AdManager.AD_IMPRESSION,
|
|
352
|
-
{'originalEvent': e}));
|
|
330
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_IMPRESSION);
|
|
353
331
|
});
|
|
354
332
|
|
|
355
333
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
356
334
|
google.ima.AdEvent.Type.DURATION_CHANGE, (e) => {
|
|
357
|
-
|
|
358
|
-
shaka.ads.AdManager.AD_DURATION_CHANGED,
|
|
359
|
-
{'originalEvent': e}));
|
|
335
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_DURATION_CHANGED);
|
|
360
336
|
});
|
|
361
337
|
|
|
362
338
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
363
339
|
google.ima.AdEvent.Type.USER_CLOSE, (e) => {
|
|
364
|
-
|
|
365
|
-
shaka.ads.AdManager.AD_CLOSED,
|
|
366
|
-
{'originalEvent': e}));
|
|
340
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_CLOSED);
|
|
367
341
|
});
|
|
368
342
|
|
|
369
343
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
370
344
|
google.ima.AdEvent.Type.LOADED, (e) => {
|
|
371
|
-
|
|
372
|
-
shaka.ads.AdManager.AD_LOADED,
|
|
373
|
-
{'originalEvent': e}));
|
|
345
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_LOADED);
|
|
374
346
|
});
|
|
375
347
|
|
|
376
348
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
377
349
|
google.ima.AdEvent.Type.ALL_ADS_COMPLETED, (e) => {
|
|
378
|
-
|
|
379
|
-
shaka.ads.AdManager.ALL_ADS_COMPLETED,
|
|
380
|
-
{'originalEvent': e}));
|
|
350
|
+
convertEventAndSend(e, shaka.ads.AdManager.ALL_ADS_COMPLETED);
|
|
381
351
|
});
|
|
382
352
|
|
|
383
353
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
384
354
|
google.ima.AdEvent.Type.LINEAR_CHANGED, (e) => {
|
|
385
|
-
|
|
386
|
-
shaka.ads.AdManager.AD_LINEAR_CHANGED,
|
|
387
|
-
{'originalEvent': e}));
|
|
355
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_LINEAR_CHANGED);
|
|
388
356
|
});
|
|
389
357
|
|
|
390
358
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
391
359
|
google.ima.AdEvent.Type.AD_METADATA, (e) => {
|
|
392
|
-
|
|
393
|
-
shaka.ads.AdManager.AD_METADATA,
|
|
394
|
-
{'originalEvent': e}));
|
|
360
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_METADATA);
|
|
395
361
|
});
|
|
396
362
|
|
|
397
363
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
398
364
|
google.ima.AdEvent.Type.LOG, (e) => {
|
|
399
|
-
|
|
400
|
-
shaka.ads.AdManager.AD_RECOVERABLE_ERROR,
|
|
401
|
-
{'originalEvent': e}));
|
|
365
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_RECOVERABLE_ERROR);
|
|
402
366
|
});
|
|
403
367
|
|
|
404
368
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
405
369
|
google.ima.AdEvent.Type.AD_BREAK_READY, (e) => {
|
|
406
|
-
|
|
407
|
-
shaka.ads.AdManager.AD_BREAK_READY,
|
|
408
|
-
{'originalEvent': e}));
|
|
370
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_BREAK_READY);
|
|
409
371
|
});
|
|
410
372
|
|
|
411
373
|
this.eventManager_.listen(this.imaAdsManager_,
|
|
412
374
|
google.ima.AdEvent.Type.INTERACTION, (e) => {
|
|
413
|
-
|
|
414
|
-
shaka.ads.AdManager.AD_INTERACTION,
|
|
415
|
-
{'originalEvent': e}));
|
|
375
|
+
convertEventAndSend(e, shaka.ads.AdManager.AD_INTERACTION);
|
|
416
376
|
});
|
|
417
377
|
}
|
|
418
378
|
|
|
@@ -426,12 +386,12 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
426
386
|
|
|
427
387
|
const imaAd = e.getAd();
|
|
428
388
|
this.ad_ = new shaka.ads.ClientSideAd(imaAd, this.imaAdsManager_);
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
389
|
+
const data = new Map()
|
|
390
|
+
.set('ad', this.ad_)
|
|
391
|
+
.set('sdkAdObject', imaAd)
|
|
392
|
+
.set('originalEvent', e);
|
|
393
|
+
this.onEvent_(new shaka.util.FakeEvent(
|
|
394
|
+
shaka.ads.AdManager.AD_STARTED, data));
|
|
435
395
|
this.adContainer_.setAttribute('ad-active', 'true');
|
|
436
396
|
this.video_.pause();
|
|
437
397
|
}
|
|
@@ -442,7 +402,7 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
442
402
|
*/
|
|
443
403
|
onAdComplete_(e) {
|
|
444
404
|
this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STOPPED,
|
|
445
|
-
|
|
405
|
+
(new Map()).set('originalEvent', e)));
|
|
446
406
|
this.adContainer_.removeAttribute('ad-active');
|
|
447
407
|
this.video_.play();
|
|
448
408
|
}
|
|
@@ -77,9 +77,7 @@ shaka.ads.ServerSideAdManager = class {
|
|
|
77
77
|
|
|
78
78
|
this.onEvent_(new shaka.util.FakeEvent(
|
|
79
79
|
shaka.ads.AdManager.IMA_STREAM_MANAGER_LOADED,
|
|
80
|
-
|
|
81
|
-
'imaStreamManager': this.streamManager_,
|
|
82
|
-
}));
|
|
80
|
+
(new Map()).set('imaStreamManager', this.streamManager_)));
|
|
83
81
|
|
|
84
82
|
// Events
|
|
85
83
|
this.eventManager_.listen(this.streamManager_,
|
|
@@ -298,7 +296,7 @@ shaka.ads.ServerSideAdManager = class {
|
|
|
298
296
|
}
|
|
299
297
|
|
|
300
298
|
this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STARTED,
|
|
301
|
-
|
|
299
|
+
(new Map()).set('ad', this.ad_)));
|
|
302
300
|
this.adContainer_.setAttribute('ad-active', 'true');
|
|
303
301
|
}
|
|
304
302
|
|
|
@@ -324,9 +322,8 @@ shaka.ads.ServerSideAdManager = class {
|
|
|
324
322
|
onLoaded_(e) {
|
|
325
323
|
const now = Date.now() / 1000;
|
|
326
324
|
const loadTime = now - this.streamRequestStartTime_;
|
|
327
|
-
this.onEvent_(
|
|
328
|
-
new
|
|
329
|
-
{'loadTime': loadTime}));
|
|
325
|
+
this.onEvent_(new shaka.util.FakeEvent(shaka.ads.AdManager.ADS_LOADED,
|
|
326
|
+
(new Map()).set('loadTime', loadTime)));
|
|
330
327
|
|
|
331
328
|
const streamData = e.getStreamData();
|
|
332
329
|
const url = streamData.url;
|
|
@@ -386,8 +383,8 @@ shaka.ads.ServerSideAdManager = class {
|
|
|
386
383
|
cuePoints.push(shakaCuePoint);
|
|
387
384
|
}
|
|
388
385
|
|
|
389
|
-
this.onEvent_(
|
|
390
|
-
|
|
391
|
-
|
|
386
|
+
this.onEvent_(new shaka.util.FakeEvent(
|
|
387
|
+
shaka.ads.AdManager.CUEPOINTS_CHANGED,
|
|
388
|
+
(new Map()).set('cuepoints', cuePoints)));
|
|
392
389
|
}
|
|
393
390
|
};
|
package/lib/cast/cast_proxy.js
CHANGED
|
@@ -525,7 +525,8 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
|
|
|
525
525
|
goog.asserts.assert(error instanceof shaka.util.Error,
|
|
526
526
|
'Wrong error type!');
|
|
527
527
|
const eventType = shaka.Player.EventName.Error;
|
|
528
|
-
const
|
|
528
|
+
const data = (new Map()).set('detail', error);
|
|
529
|
+
const event = new shaka.util.FakeEvent(eventType, data);
|
|
529
530
|
this.localPlayer_.dispatchEvent(event);
|
|
530
531
|
});
|
|
531
532
|
}
|
|
@@ -598,7 +599,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
|
|
|
598
599
|
|
|
599
600
|
// Convert this real Event into a FakeEvent for dispatch from our
|
|
600
601
|
// FakeEventListener.
|
|
601
|
-
const fakeEvent =
|
|
602
|
+
const fakeEvent = shaka.util.FakeEvent.fromRealEvent(event);
|
|
602
603
|
this.videoEventTarget_.dispatchEvent(fakeEvent);
|
|
603
604
|
}
|
|
604
605
|
|
|
@@ -407,7 +407,8 @@ shaka.cast.CastReceiver = class extends shaka.util.FakeEventTarget {
|
|
|
407
407
|
goog.asserts.assert(error instanceof shaka.util.Error,
|
|
408
408
|
'Wrong error type!');
|
|
409
409
|
const eventType = shaka.Player.EventName.Error;
|
|
410
|
-
const
|
|
410
|
+
const data = (new Map()).set('detail', error);
|
|
411
|
+
const event = new shaka.util.FakeEvent(eventType, data);
|
|
411
412
|
// Only dispatch the event if the player still exists.
|
|
412
413
|
if (this.player_) {
|
|
413
414
|
this.player_.dispatchEvent(event);
|
package/lib/cast/cast_sender.js
CHANGED
|
@@ -647,7 +647,7 @@ shaka.cast.CastSender = class {
|
|
|
647
647
|
case 'event': {
|
|
648
648
|
const targetName = message['targetName'];
|
|
649
649
|
const event = message['event'];
|
|
650
|
-
const fakeEvent =
|
|
650
|
+
const fakeEvent = shaka.util.FakeEvent.fromRealEvent(event);
|
|
651
651
|
this.onRemoteEvent_(targetName, fakeEvent);
|
|
652
652
|
break;
|
|
653
653
|
}
|
|
@@ -725,7 +725,7 @@ shaka.cast.CastSender = class {
|
|
|
725
725
|
|
|
726
726
|
// Dispatch it through the Player proxy
|
|
727
727
|
const fakeEvent = new shaka.util.FakeEvent(
|
|
728
|
-
'error',
|
|
728
|
+
'error', (new Map()).set('detail', shakaError));
|
|
729
729
|
this.onRemoteEvent_('player', fakeEvent);
|
|
730
730
|
|
|
731
731
|
// Force this session to disconnect and transfer playback to the local
|
package/lib/dash/dash_parser.js
CHANGED
|
@@ -95,6 +95,18 @@ shaka.dash.DashParser = class {
|
|
|
95
95
|
/** @private {!shaka.util.OperationManager} */
|
|
96
96
|
this.operationManager_ = new shaka.util.OperationManager();
|
|
97
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Largest period start time seen.
|
|
100
|
+
* @private {?number}
|
|
101
|
+
*/
|
|
102
|
+
this.largestPeriodStartTime_ = null;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Period IDs seen in previous manifest.
|
|
106
|
+
* @private {!Array.<number>}
|
|
107
|
+
*/
|
|
108
|
+
this.lastManifestUpdatePeriodIds_ = [];
|
|
109
|
+
|
|
98
110
|
/**
|
|
99
111
|
* The minimum of the availabilityTimeOffset values among the adaptation
|
|
100
112
|
* sets.
|
|
@@ -533,6 +545,7 @@ shaka.dash.DashParser = class {
|
|
|
533
545
|
for (const {i, item: elem, next} of enumerate(periodNodes)) {
|
|
534
546
|
const start = /** @type {number} */ (
|
|
535
547
|
XmlUtils.parseAttr(elem, 'start', XmlUtils.parseDuration, prevEnd));
|
|
548
|
+
const periodId = elem.id;
|
|
536
549
|
const givenDuration =
|
|
537
550
|
XmlUtils.parseAttr(elem, 'duration', XmlUtils.parseDuration);
|
|
538
551
|
|
|
@@ -566,6 +579,42 @@ shaka.dash.DashParser = class {
|
|
|
566
579
|
periodDuration = givenDuration;
|
|
567
580
|
}
|
|
568
581
|
|
|
582
|
+
/**
|
|
583
|
+
* This is to improve robustness when the player observes manifest with
|
|
584
|
+
* past periods that are inconsistent to previous ones.
|
|
585
|
+
*
|
|
586
|
+
* This may happen when a CDN or proxy server switches its upstream from
|
|
587
|
+
* one encoder to another redundant encoder.
|
|
588
|
+
*
|
|
589
|
+
* Skip periods that match all of the following criteria:
|
|
590
|
+
* - Start time is earlier than latest period start time ever seen
|
|
591
|
+
* - Period ID is never seen in the previous manifest
|
|
592
|
+
* - Not the last period in the manifest
|
|
593
|
+
*
|
|
594
|
+
* Periods that meet the aforementioned criteria are considered invalid
|
|
595
|
+
* and should be safe to discard.
|
|
596
|
+
*/
|
|
597
|
+
|
|
598
|
+
if (this.largestPeriodStartTime_ !== null &&
|
|
599
|
+
periodId !== null && start !== null &&
|
|
600
|
+
start < this.largestPeriodStartTime_ &&
|
|
601
|
+
!this.lastManifestUpdatePeriodIds_.includes(periodId) &&
|
|
602
|
+
i + 1 != periodNodes.length) {
|
|
603
|
+
shaka.log.debug(
|
|
604
|
+
`Skipping Period with ID ${periodId} as its start time is smaller` +
|
|
605
|
+
' than the largest period start time that has been seen, and ID ' +
|
|
606
|
+
'is unseen before');
|
|
607
|
+
continue;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
|
|
611
|
+
// Save maximum period start time if it is the last period
|
|
612
|
+
if (start !== null &&
|
|
613
|
+
(this.largestPeriodStartTime_ === null ||
|
|
614
|
+
start > this.largestPeriodStartTime_)) {
|
|
615
|
+
this.largestPeriodStartTime_ = start;
|
|
616
|
+
}
|
|
617
|
+
|
|
569
618
|
// Parse child nodes.
|
|
570
619
|
const info = {
|
|
571
620
|
start: start,
|
|
@@ -597,6 +646,9 @@ shaka.dash.DashParser = class {
|
|
|
597
646
|
prevEnd = start + periodDuration;
|
|
598
647
|
} // end of period parsing loop
|
|
599
648
|
|
|
649
|
+
// Replace previous seen periods with the current one.
|
|
650
|
+
this.lastManifestUpdatePeriodIds_ = periods.map((el) => el.id);
|
|
651
|
+
|
|
600
652
|
if (presentationDuration != null) {
|
|
601
653
|
if (prevEnd != presentationDuration) {
|
|
602
654
|
shaka.log.warning(
|
|
@@ -808,6 +860,25 @@ shaka.dash.DashParser = class {
|
|
|
808
860
|
}
|
|
809
861
|
}
|
|
810
862
|
|
|
863
|
+
// Parallel for HLS VIDEO-RANGE as defined in DASH-IF IOP v4.3 6.2.5.1.
|
|
864
|
+
let videoRange;
|
|
865
|
+
const videoRangeScheme = 'urn:mpeg:mpegB:cicp:TransferCharacteristics';
|
|
866
|
+
const getVideoRangeFromTransferCharacteristicCICP = (cicp) => {
|
|
867
|
+
switch (cicp) {
|
|
868
|
+
case 1:
|
|
869
|
+
case 6:
|
|
870
|
+
case 13:
|
|
871
|
+
case 14:
|
|
872
|
+
case 15:
|
|
873
|
+
return 'SDR';
|
|
874
|
+
case 16:
|
|
875
|
+
return 'PQ';
|
|
876
|
+
case 18:
|
|
877
|
+
return 'HLG';
|
|
878
|
+
}
|
|
879
|
+
return undefined;
|
|
880
|
+
};
|
|
881
|
+
|
|
811
882
|
const essentialProperties =
|
|
812
883
|
XmlUtils.findChildren(elem, 'EssentialProperty');
|
|
813
884
|
// ID of real AdaptationSet if this is a trick mode set:
|
|
@@ -817,11 +888,26 @@ shaka.dash.DashParser = class {
|
|
|
817
888
|
const schemeId = prop.getAttribute('schemeIdUri');
|
|
818
889
|
if (schemeId == 'http://dashif.org/guidelines/trickmode') {
|
|
819
890
|
trickModeFor = prop.getAttribute('value');
|
|
891
|
+
} else if (schemeId == videoRangeScheme) {
|
|
892
|
+
videoRange = getVideoRangeFromTransferCharacteristicCICP(
|
|
893
|
+
parseInt(prop.getAttribute('value'), 10),
|
|
894
|
+
);
|
|
820
895
|
} else {
|
|
821
896
|
unrecognizedEssentialProperty = true;
|
|
822
897
|
}
|
|
823
898
|
}
|
|
824
899
|
|
|
900
|
+
const supplementalProperties =
|
|
901
|
+
XmlUtils.findChildren(elem, 'SupplementalProperty');
|
|
902
|
+
for (const prop of supplementalProperties) {
|
|
903
|
+
const schemeId = prop.getAttribute('schemeIdUri');
|
|
904
|
+
if (schemeId == videoRangeScheme) {
|
|
905
|
+
videoRange = getVideoRangeFromTransferCharacteristicCICP(
|
|
906
|
+
parseInt(prop.getAttribute('value'), 10),
|
|
907
|
+
);
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
|
|
825
911
|
const accessibilities = XmlUtils.findChildren(elem, 'Accessibility');
|
|
826
912
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
827
913
|
const closedCaptions = new Map();
|
|
@@ -947,8 +1033,13 @@ shaka.dash.DashParser = class {
|
|
|
947
1033
|
// Parse Representations into Streams.
|
|
948
1034
|
const representations = XmlUtils.findChildren(elem, 'Representation');
|
|
949
1035
|
const streams = representations.map((representation) => {
|
|
950
|
-
|
|
951
|
-
language, label, main, roleValues,
|
|
1036
|
+
const parsedRepresentation = this.parseRepresentation_(context,
|
|
1037
|
+
contentProtection, kind, language, label, main, roleValues,
|
|
1038
|
+
closedCaptions, representation);
|
|
1039
|
+
if (parsedRepresentation) {
|
|
1040
|
+
parsedRepresentation.hdr = parsedRepresentation.hdr || videoRange;
|
|
1041
|
+
}
|
|
1042
|
+
return parsedRepresentation;
|
|
952
1043
|
}).filter((s) => !!s);
|
|
953
1044
|
|
|
954
1045
|
if (streams.length == 0) {
|
package/lib/dash/segment_list.js
CHANGED
|
@@ -63,12 +63,12 @@ shaka.dash.SegmentList = class {
|
|
|
63
63
|
const start = context.presentationTimeline.getSegmentAvailabilityStart();
|
|
64
64
|
segmentIndex.mergeAndEvict(references, start);
|
|
65
65
|
} else {
|
|
66
|
-
context.presentationTimeline.notifySegments(references);
|
|
67
66
|
segmentIndex = new shaka.media.SegmentIndex(references);
|
|
68
67
|
if (id && context.dynamic) {
|
|
69
68
|
segmentIndexMap[id] = segmentIndex;
|
|
70
69
|
}
|
|
71
70
|
}
|
|
71
|
+
context.presentationTimeline.notifySegments(references);
|
|
72
72
|
|
|
73
73
|
if (!context.dynamic || !context.periodInfo.isLastPeriod) {
|
|
74
74
|
const periodStart = context.periodInfo.start;
|
|
@@ -116,12 +116,12 @@ shaka.dash.SegmentTemplate = class {
|
|
|
116
116
|
segmentIndex.mergeAndEvict(references,
|
|
117
117
|
context.presentationTimeline.getSegmentAvailabilityStart());
|
|
118
118
|
} else {
|
|
119
|
-
context.presentationTimeline.notifySegments(references);
|
|
120
119
|
segmentIndex = new shaka.media.SegmentIndex(references);
|
|
121
120
|
if (id && context.dynamic) {
|
|
122
121
|
segmentIndexMap[id] = segmentIndex;
|
|
123
122
|
}
|
|
124
123
|
}
|
|
124
|
+
context.presentationTimeline.notifySegments(references);
|
|
125
125
|
|
|
126
126
|
if (shouldFit) {
|
|
127
127
|
segmentIndex.fit(periodStart, periodEnd);
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -414,18 +414,16 @@ shaka.hls.HlsParser = class {
|
|
|
414
414
|
const uri = tag.getAttributeValue('URI');
|
|
415
415
|
const language = tag.getAttributeValue('LANGUAGE');
|
|
416
416
|
const value = tag.getAttributeValue('VALUE');
|
|
417
|
-
const data =
|
|
418
|
-
'id': id,
|
|
419
|
-
};
|
|
417
|
+
const data = (new Map()).set('id', id);
|
|
420
418
|
if (uri) {
|
|
421
|
-
data.uri
|
|
422
|
-
shaka.hls.Utils.constructAbsoluteUri(this.masterPlaylistUri_, uri);
|
|
419
|
+
data.set('uri',
|
|
420
|
+
shaka.hls.Utils.constructAbsoluteUri(this.masterPlaylistUri_, uri));
|
|
423
421
|
}
|
|
424
422
|
if (language) {
|
|
425
|
-
data.language
|
|
423
|
+
data.set('language', language);
|
|
426
424
|
}
|
|
427
425
|
if (value) {
|
|
428
|
-
data.value
|
|
426
|
+
data.set('value', value);
|
|
429
427
|
}
|
|
430
428
|
const event = new shaka.util.FakeEvent('sessiondata', data);
|
|
431
429
|
if (this.playerInterface_) {
|
|
@@ -529,6 +527,30 @@ shaka.hls.HlsParser = class {
|
|
|
529
527
|
}
|
|
530
528
|
}
|
|
531
529
|
|
|
530
|
+
// Now that the content has been fit, notify segments.
|
|
531
|
+
this.segmentsToNotifyByStream_ = [];
|
|
532
|
+
const streamsToNotify = [];
|
|
533
|
+
for (const variant of variants) {
|
|
534
|
+
for (const stream of [variant.video, variant.audio]) {
|
|
535
|
+
if (stream) {
|
|
536
|
+
streamsToNotify.push(stream);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
await Promise.all(streamsToNotify.map(async (stream) => {
|
|
541
|
+
await stream.createSegmentIndex();
|
|
542
|
+
}));
|
|
543
|
+
for (const stream of streamsToNotify) {
|
|
544
|
+
this.segmentsToNotifyByStream_.push(stream.segmentIndex.references);
|
|
545
|
+
}
|
|
546
|
+
this.notifySegments_();
|
|
547
|
+
|
|
548
|
+
// This asserts that the live edge is being calculated from segment times.
|
|
549
|
+
// For VOD and event streams, this check should still pass.
|
|
550
|
+
goog.asserts.assert(
|
|
551
|
+
!this.presentationTimeline_.usingPresentationStartTime(),
|
|
552
|
+
'We should not be using the presentation start time in HLS!');
|
|
553
|
+
|
|
532
554
|
this.manifest_ = {
|
|
533
555
|
presentationTimeline: this.presentationTimeline_,
|
|
534
556
|
variants,
|
|
@@ -1151,7 +1173,7 @@ shaka.hls.HlsParser = class {
|
|
|
1151
1173
|
// "AUTOSELECT=YES". A value of "AUTOSELECT=NO" would imply that it may
|
|
1152
1174
|
// only be selected explicitly by the user, and we don't have a way to
|
|
1153
1175
|
// represent that in our model.
|
|
1154
|
-
const defaultAttrValue = tag.
|
|
1176
|
+
const defaultAttrValue = tag.getAttributeValue('DEFAULT');
|
|
1155
1177
|
const primary = defaultAttrValue == 'YES';
|
|
1156
1178
|
|
|
1157
1179
|
const channelsCount = type == 'audio' ? this.getChannelsCount_(tag) : null;
|
|
@@ -1538,12 +1560,6 @@ shaka.hls.HlsParser = class {
|
|
|
1538
1560
|
}
|
|
1539
1561
|
|
|
1540
1562
|
this.notifySegments_();
|
|
1541
|
-
|
|
1542
|
-
// This asserts that the live edge is being calculated from segment times.
|
|
1543
|
-
// For VOD and event streams, this check should still pass.
|
|
1544
|
-
goog.asserts.assert(
|
|
1545
|
-
!this.presentationTimeline_.usingPresentationStartTime(),
|
|
1546
|
-
'We should not be using the presentation start time in HLS!');
|
|
1547
1563
|
}
|
|
1548
1564
|
|
|
1549
1565
|
/**
|
|
@@ -1915,9 +1931,6 @@ shaka.hls.HlsParser = class {
|
|
|
1915
1931
|
}
|
|
1916
1932
|
}
|
|
1917
1933
|
|
|
1918
|
-
this.segmentsToNotifyByStream_.push(references);
|
|
1919
|
-
this.notifySegments_();
|
|
1920
|
-
|
|
1921
1934
|
return references;
|
|
1922
1935
|
}
|
|
1923
1936
|
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -1889,9 +1889,16 @@ shaka.media.DrmEngine = class {
|
|
|
1889
1889
|
// audio adaptations, so we shouldn't have to worry about checking
|
|
1890
1890
|
// robustness.
|
|
1891
1891
|
if (drm1.keySystem == drm2.keySystem) {
|
|
1892
|
+
/** @type {Array<shaka.extern.InitDataOverride>} */
|
|
1892
1893
|
let initData = [];
|
|
1893
1894
|
initData = initData.concat(drm1.initData || []);
|
|
1894
1895
|
initData = initData.concat(drm2.initData || []);
|
|
1896
|
+
initData = initData.filter((d, i) => {
|
|
1897
|
+
return d.keyId === undefined || i === initData.findIndex((d2) => {
|
|
1898
|
+
return d2.keyId === d.keyId;
|
|
1899
|
+
});
|
|
1900
|
+
});
|
|
1901
|
+
|
|
1895
1902
|
const keyIds = drm1.keyIds && drm2.keyIds ?
|
|
1896
1903
|
new Set([...drm1.keyIds, ...drm2.keyIds]) :
|
|
1897
1904
|
drm1.keyIds || drm2.keyIds;
|