shaka-player 3.0.14 → 3.0.15
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 +2 -0
- package/CHANGELOG.md +39 -0
- package/CONTRIBUTORS +2 -0
- package/build/generateExterns.js +1 -1
- package/demo/common/assets.js +1 -1
- package/dist/controls.css +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 +34 -34
- 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 +181 -178
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +1 -1
- package/dist/shaka-player.compiled.js +688 -686
- package/dist/shaka-player.compiled.map +3 -3
- 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 +169 -166
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +3 -3
- package/dist/shaka-player.ui.js +815 -813
- 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 +6 -2
- package/lib/cast/cast_sender.js +2 -2
- package/lib/dash/dash_parser.js +52 -0
- package/lib/dash/segment_list.js +1 -1
- package/lib/dash/segment_template.js +1 -1
- package/lib/hls/hls_parser.js +25 -10
- package/lib/media/drm_engine.js +7 -0
- package/lib/media/gap_jumping_controller.js +4 -2
- package/lib/media/streaming_engine.js +2 -1
- package/lib/net/networking_engine.js +2 -1
- package/lib/player.js +18 -17
- 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/ttml_text_parser.js +5 -0
- package/lib/text/ui_text_displayer.js +6 -1
- package/lib/util/fake_event.js +53 -7
- package/lib/util/periods.js +4 -1
- 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 +73 -0
- package/test/hls/hls_parser_unit.js +5 -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 +18 -0
- package/test/ui/localization_unit.js +15 -14
- package/ui/cast_button.js +2 -3
- package/ui/controls.js +4 -6
- 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
|
@@ -136,6 +136,7 @@ module.exports = (config) => {
|
|
|
136
136
|
included: false,
|
|
137
137
|
},
|
|
138
138
|
{pattern: 'test/test/assets/*', included: false},
|
|
139
|
+
{pattern: 'test/test/assets/3675/*', included: false},
|
|
139
140
|
{pattern: 'dist/shaka-player.ui.js', included: false},
|
|
140
141
|
{pattern: 'dist/locales.js', included: false},
|
|
141
142
|
{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
|
@@ -526,7 +526,8 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
|
|
|
526
526
|
goog.asserts.assert(error instanceof shaka.util.Error,
|
|
527
527
|
'Wrong error type!');
|
|
528
528
|
const eventType = shaka.Player.EventName.Error;
|
|
529
|
-
const
|
|
529
|
+
const data = (new Map()).set('detail', error);
|
|
530
|
+
const event = new shaka.util.FakeEvent(eventType, data);
|
|
530
531
|
this.localPlayer_.dispatchEvent(event);
|
|
531
532
|
});
|
|
532
533
|
}
|
|
@@ -599,7 +600,7 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
|
|
|
599
600
|
|
|
600
601
|
// Convert this real Event into a FakeEvent for dispatch from our
|
|
601
602
|
// FakeEventListener.
|
|
602
|
-
const fakeEvent =
|
|
603
|
+
const fakeEvent = shaka.util.FakeEvent.fromRealEvent(event);
|
|
603
604
|
this.videoEventTarget_.dispatchEvent(fakeEvent);
|
|
604
605
|
}
|
|
605
606
|
|
|
@@ -407,8 +407,12 @@ 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
|
|
411
|
-
|
|
410
|
+
const data = (new Map()).set('detail', error);
|
|
411
|
+
const event = new shaka.util.FakeEvent(eventType, data);
|
|
412
|
+
// Only dispatch the event if the player still exists.
|
|
413
|
+
if (this.player_) {
|
|
414
|
+
this.player_.dispatchEvent(event);
|
|
415
|
+
}
|
|
412
416
|
return;
|
|
413
417
|
}
|
|
414
418
|
} else {
|
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
|
@@ -94,6 +94,18 @@ shaka.dash.DashParser = class {
|
|
|
94
94
|
|
|
95
95
|
/** @private {!shaka.util.OperationManager} */
|
|
96
96
|
this.operationManager_ = new shaka.util.OperationManager();
|
|
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_ = [];
|
|
97
109
|
}
|
|
98
110
|
|
|
99
111
|
/**
|
|
@@ -474,6 +486,7 @@ shaka.dash.DashParser = class {
|
|
|
474
486
|
for (const {i, item: elem, next} of enumerate(periodNodes)) {
|
|
475
487
|
const start = /** @type {number} */ (
|
|
476
488
|
XmlUtils.parseAttr(elem, 'start', XmlUtils.parseDuration, prevEnd));
|
|
489
|
+
const periodId = elem.id;
|
|
477
490
|
const givenDuration =
|
|
478
491
|
XmlUtils.parseAttr(elem, 'duration', XmlUtils.parseDuration);
|
|
479
492
|
|
|
@@ -507,6 +520,42 @@ shaka.dash.DashParser = class {
|
|
|
507
520
|
periodDuration = givenDuration;
|
|
508
521
|
}
|
|
509
522
|
|
|
523
|
+
/**
|
|
524
|
+
* This is to improve robustness when the player observes manifest with
|
|
525
|
+
* past periods that are inconsistent to previous ones.
|
|
526
|
+
*
|
|
527
|
+
* This may happen when a CDN or proxy server switches its upstream from
|
|
528
|
+
* one encoder to another redundant encoder.
|
|
529
|
+
*
|
|
530
|
+
* Skip periods that match all of the following criteria:
|
|
531
|
+
* - Start time is earlier than latest period start time ever seen
|
|
532
|
+
* - Period ID is never seen in the previous manifest
|
|
533
|
+
* - Not the last period in the manifest
|
|
534
|
+
*
|
|
535
|
+
* Periods that meet the aforementioned criteria are considered invalid
|
|
536
|
+
* and should be safe to discard.
|
|
537
|
+
*/
|
|
538
|
+
|
|
539
|
+
if (this.largestPeriodStartTime_ !== null &&
|
|
540
|
+
periodId !== null && start !== null &&
|
|
541
|
+
start < this.largestPeriodStartTime_ &&
|
|
542
|
+
!this.lastManifestUpdatePeriodIds_.includes(periodId) &&
|
|
543
|
+
i + 1 != periodNodes.length) {
|
|
544
|
+
shaka.log.debug(
|
|
545
|
+
`Skipping Period with ID ${periodId} as its start time is smaller` +
|
|
546
|
+
' than the largest period start time that has been seen, and ID ' +
|
|
547
|
+
'is unseen before');
|
|
548
|
+
continue;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
// Save maximum period start time if it is the last period
|
|
553
|
+
if (start !== null &&
|
|
554
|
+
(this.largestPeriodStartTime_ === null ||
|
|
555
|
+
start > this.largestPeriodStartTime_)) {
|
|
556
|
+
this.largestPeriodStartTime_ = start;
|
|
557
|
+
}
|
|
558
|
+
|
|
510
559
|
// Parse child nodes.
|
|
511
560
|
const info = {
|
|
512
561
|
start: start,
|
|
@@ -538,6 +587,9 @@ shaka.dash.DashParser = class {
|
|
|
538
587
|
prevEnd = start + periodDuration;
|
|
539
588
|
} // end of period parsing loop
|
|
540
589
|
|
|
590
|
+
// Replace previous seen periods with the current one.
|
|
591
|
+
this.lastManifestUpdatePeriodIds_ = periods.map((el) => el.id);
|
|
592
|
+
|
|
541
593
|
if (presentationDuration != null) {
|
|
542
594
|
if (prevEnd != presentationDuration) {
|
|
543
595
|
shaka.log.warning(
|
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
|
@@ -475,6 +475,30 @@ shaka.hls.HlsParser = class {
|
|
|
475
475
|
}
|
|
476
476
|
}
|
|
477
477
|
|
|
478
|
+
// Now that the content has been fit, notify segments.
|
|
479
|
+
this.segmentsToNotifyByStream_ = [];
|
|
480
|
+
const streamsToNotify = [];
|
|
481
|
+
for (const variant of variants) {
|
|
482
|
+
for (const stream of [variant.video, variant.audio]) {
|
|
483
|
+
if (stream) {
|
|
484
|
+
streamsToNotify.push(stream);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
await Promise.all(streamsToNotify.map(async (stream) => {
|
|
489
|
+
await stream.createSegmentIndex();
|
|
490
|
+
}));
|
|
491
|
+
for (const stream of streamsToNotify) {
|
|
492
|
+
this.segmentsToNotifyByStream_.push(stream.segmentIndex.references);
|
|
493
|
+
}
|
|
494
|
+
this.notifySegments_();
|
|
495
|
+
|
|
496
|
+
// This asserts that the live edge is being calculated from segment times.
|
|
497
|
+
// For VOD and event streams, this check should still pass.
|
|
498
|
+
goog.asserts.assert(
|
|
499
|
+
!this.presentationTimeline_.usingPresentationStartTime(),
|
|
500
|
+
'We should not be using the presentation start time in HLS!');
|
|
501
|
+
|
|
478
502
|
this.manifest_ = {
|
|
479
503
|
presentationTimeline: this.presentationTimeline_,
|
|
480
504
|
variants,
|
|
@@ -1064,7 +1088,7 @@ shaka.hls.HlsParser = class {
|
|
|
1064
1088
|
// "AUTOSELECT=YES". A value of "AUTOSELECT=NO" would imply that it may
|
|
1065
1089
|
// only be selected explicitly by the user, and we don't have a way to
|
|
1066
1090
|
// represent that in our model.
|
|
1067
|
-
const defaultAttrValue = tag.
|
|
1091
|
+
const defaultAttrValue = tag.getAttributeValue('DEFAULT');
|
|
1068
1092
|
const primary = defaultAttrValue == 'YES';
|
|
1069
1093
|
|
|
1070
1094
|
const channelsCount = type == 'audio' ? this.getChannelsCount_(tag) : null;
|
|
@@ -1397,12 +1421,6 @@ shaka.hls.HlsParser = class {
|
|
|
1397
1421
|
}
|
|
1398
1422
|
|
|
1399
1423
|
this.notifySegments_();
|
|
1400
|
-
|
|
1401
|
-
// This asserts that the live edge is being calculated from segment times.
|
|
1402
|
-
// For VOD and event streams, this check should still pass.
|
|
1403
|
-
goog.asserts.assert(
|
|
1404
|
-
!this.presentationTimeline_.usingPresentationStartTime(),
|
|
1405
|
-
'We should not be using the presentation start time in HLS!');
|
|
1406
1424
|
}
|
|
1407
1425
|
|
|
1408
1426
|
/**
|
|
@@ -1638,9 +1656,6 @@ shaka.hls.HlsParser = class {
|
|
|
1638
1656
|
references.push(reference);
|
|
1639
1657
|
}
|
|
1640
1658
|
|
|
1641
|
-
this.segmentsToNotifyByStream_.push(references);
|
|
1642
|
-
this.notifySegments_();
|
|
1643
|
-
|
|
1644
1659
|
return references;
|
|
1645
1660
|
}
|
|
1646
1661
|
|
package/lib/media/drm_engine.js
CHANGED
|
@@ -1751,9 +1751,16 @@ shaka.media.DrmEngine = class {
|
|
|
1751
1751
|
// audio adaptations, so we shouldn't have to worry about checking
|
|
1752
1752
|
// robustness.
|
|
1753
1753
|
if (drm1.keySystem == drm2.keySystem) {
|
|
1754
|
+
/** @type {Array<shaka.extern.InitDataOverride>} */
|
|
1754
1755
|
let initData = [];
|
|
1755
1756
|
initData = initData.concat(drm1.initData || []);
|
|
1756
1757
|
initData = initData.concat(drm2.initData || []);
|
|
1758
|
+
initData = initData.filter((d, i) => {
|
|
1759
|
+
return d.keyId === undefined || i === initData.findIndex((d2) => {
|
|
1760
|
+
return d2.keyId === d.keyId;
|
|
1761
|
+
});
|
|
1762
|
+
});
|
|
1763
|
+
|
|
1757
1764
|
const keyIds = drm1.keyIds && drm2.keyIds ?
|
|
1758
1765
|
new Set([...drm1.keyIds, ...drm2.keyIds]) :
|
|
1759
1766
|
drm1.keyIds || drm2.keyIds;
|
|
@@ -216,8 +216,10 @@ shaka.media.GapJumpingController = class {
|
|
|
216
216
|
this.didFireLargeGap_ = true;
|
|
217
217
|
|
|
218
218
|
// Event firing is synchronous.
|
|
219
|
-
const
|
|
220
|
-
'
|
|
219
|
+
const data = new Map()
|
|
220
|
+
.set('currentTime', currentTime)
|
|
221
|
+
.set('gapSize', jumpSize);
|
|
222
|
+
const event = new shaka.util.FakeEvent('largegap', data);
|
|
221
223
|
event.cancelable = true;
|
|
222
224
|
this.onEvent_(event);
|
|
223
225
|
|
|
@@ -1615,7 +1615,8 @@ shaka.media.StreamingEngine = class {
|
|
|
1615
1615
|
|
|
1616
1616
|
// Dispatch an event to notify the application about the emsg box.
|
|
1617
1617
|
const eventName = shaka.Player.EventName.Emsg;
|
|
1618
|
-
const
|
|
1618
|
+
const data = (new Map()).set('detail', emsg);
|
|
1619
|
+
const event = new shaka.util.FakeEvent(eventName, data);
|
|
1619
1620
|
this.playerInterface_.onEvent(event);
|
|
1620
1621
|
}
|
|
1621
1622
|
}
|
|
@@ -463,7 +463,8 @@ shaka.net.NetworkingEngine = class extends shaka.util.FakeEventTarget {
|
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
if (error.severity == shaka.util.Error.Severity.RECOVERABLE) {
|
|
466
|
-
const
|
|
466
|
+
const data = (new Map()).set('error', error);
|
|
467
|
+
const event = new shaka.util.FakeEvent('retry', data);
|
|
467
468
|
this.dispatchEvent(event);
|
|
468
469
|
|
|
469
470
|
// Move to the next URI.
|