shaka-player 4.8.8 → 4.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +5 -0
  2. package/dist/controls.css +1 -1
  3. package/dist/controls.css.map +1 -1
  4. package/dist/deps.js +5 -5
  5. package/dist/locales.js +33 -33
  6. package/dist/shaka-player.compiled.d.ts +39 -17
  7. package/dist/shaka-player.compiled.debug.d.ts +39 -17
  8. package/dist/shaka-player.compiled.debug.externs.js +32 -11
  9. package/dist/shaka-player.compiled.debug.js +574 -516
  10. package/dist/shaka-player.compiled.debug.map +4 -4
  11. package/dist/shaka-player.compiled.externs.js +32 -11
  12. package/dist/shaka-player.compiled.js +1270 -1236
  13. package/dist/shaka-player.compiled.map +4 -4
  14. package/dist/shaka-player.ui.d.ts +39 -17
  15. package/dist/shaka-player.ui.debug.d.ts +39 -17
  16. package/dist/shaka-player.ui.debug.externs.js +43 -22
  17. package/dist/shaka-player.ui.debug.js +601 -543
  18. package/dist/shaka-player.ui.debug.map +4 -4
  19. package/dist/shaka-player.ui.externs.js +43 -22
  20. package/dist/shaka-player.ui.js +1483 -1448
  21. package/dist/shaka-player.ui.map +4 -4
  22. package/externs/shaka/manifest.js +11 -1
  23. package/externs/shaka/offline.js +3 -0
  24. package/externs/shaka/player.js +105 -12
  25. package/externs/tizen.js +1 -1
  26. package/lib/abr/simple_abr_manager.js +5 -0
  27. package/lib/ads/media_tailor_ad.js +11 -0
  28. package/lib/ads/media_tailor_ad_manager.js +37 -3
  29. package/lib/cea/cea608_data_channel.js +9 -0
  30. package/lib/cea/cea_decoder.js +6 -2
  31. package/lib/dash/dash_parser.js +655 -46
  32. package/lib/dash/mpd_utils.js +7 -8
  33. package/lib/dash/segment_template.js +65 -10
  34. package/lib/hls/hls_parser.js +92 -34
  35. package/lib/media/drm_engine.js +274 -40
  36. package/lib/media/manifest_filterer.js +10 -14
  37. package/lib/media/preload_manager.js +3 -10
  38. package/lib/media/segment_utils.js +14 -3
  39. package/lib/mss/mss_parser.js +2 -0
  40. package/lib/net/http_plugin_utils.js +2 -1
  41. package/lib/net/networking_engine.js +27 -0
  42. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  43. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  44. package/lib/offline/manifest_converter.js +2 -0
  45. package/lib/offline/storage.js +1 -0
  46. package/lib/player.js +221 -14
  47. package/lib/polyfill/media_capabilities.js +10 -35
  48. package/lib/util/config_utils.js +74 -6
  49. package/lib/util/error.js +7 -0
  50. package/lib/util/mp4_box_parsers.js +23 -2
  51. package/lib/util/periods.js +51 -28
  52. package/lib/util/platform.js +3 -1
  53. package/lib/util/player_configuration.js +20 -8
  54. package/lib/util/stream_utils.js +62 -30
  55. package/lib/util/tXml.js +74 -6
  56. package/package.json +2 -2
  57. package/support.html +1 -0
  58. package/ui/controls.js +4 -0
  59. package/ui/less/ad_controls.less +2 -1
  60. package/ui/resolution_selection.js +12 -3
@@ -21,7 +21,8 @@
21
21
  * sequenceMode: boolean,
22
22
  * ignoreManifestTimestampsInSegmentsMode: boolean,
23
23
  * type: string,
24
- * serviceDescription: ?shaka.extern.ServiceDescription
24
+ * serviceDescription: ?shaka.extern.ServiceDescription,
25
+ * nextUrl: ?string
25
26
  * }}
26
27
  *
27
28
  * @description
@@ -93,6 +94,8 @@
93
94
  * @property {?shaka.extern.ServiceDescription} serviceDescription
94
95
  * The service description for the manifest. Used to adapt playbackRate to
95
96
  * decrease latency.
97
+ * @property {?string} nextUrl
98
+ * The next url to play.
96
99
  *
97
100
  * @exportDoc
98
101
  */
@@ -151,6 +154,7 @@ shaka.extern.InitDataOverride;
151
154
 
152
155
  /**
153
156
  * @typedef {{
157
+ * targetLatency:?number,
154
158
  * maxLatency: ?number,
155
159
  * maxPlaybackRate: ?number,
156
160
  * minLatency: ?number,
@@ -164,6 +168,8 @@ shaka.extern.InitDataOverride;
164
168
  * minPlaybackRate to increase latency.
165
169
  * More information {@link https://dashif.org/docs/CR-Low-Latency-Live-r8.pdf here}.
166
170
  *
171
+ * @property {?number} targetLatency
172
+ * The target latency to aim for.
167
173
  * @property {?number} maxLatency
168
174
  * Maximum latency in seconds.
169
175
  * @property {?number} maxPlaybackRate
@@ -424,6 +430,7 @@ shaka.extern.SegmentIndex = class {
424
430
  * frameRate: (number|undefined),
425
431
  * pixelAspectRatio: (string|undefined),
426
432
  * hdr: (string|undefined),
433
+ * colorGamut: (string|undefined),
427
434
  * videoLayout: (string|undefined),
428
435
  * bandwidth: (number|undefined),
429
436
  * width: (number|undefined),
@@ -501,6 +508,9 @@ shaka.extern.SegmentIndex = class {
501
508
  * @property {(string|undefined)} hdr
502
509
  * <i>Video streams only.</i> <br>
503
510
  * The Stream's HDR info
511
+ * @property {(string|undefined)} colorGamut
512
+ * <i>Video streams only.</i> <br>
513
+ * The Stream's color gamut info
504
514
  * @property {(string|undefined)} videoLayout
505
515
  * <i>Video streams only.</i> <br>
506
516
  * The Stream's video layout info.
@@ -122,6 +122,7 @@ shaka.extern.ManifestDB;
122
122
  * frameRate: (number|undefined),
123
123
  * pixelAspectRatio: (string|undefined),
124
124
  * hdr: (string|undefined),
125
+ * colorGamut: (string|undefined),
125
126
  * videoLayout: (string|undefined),
126
127
  * kind: (string|undefined),
127
128
  * language: string,
@@ -166,6 +167,8 @@ shaka.extern.ManifestDB;
166
167
  * The Stream's pixel aspect ratio
167
168
  * @property {(string|undefined)} hdr
168
169
  * The Stream's HDR info
170
+ * @property {(string|undefined)} colorGamut
171
+ * The Stream's color gamut info
169
172
  * @property {(string|undefined)} videoLayout
170
173
  * The Stream's video layout info.
171
174
  * @property {(string|undefined)} kind
@@ -234,6 +234,7 @@ shaka.extern.BufferedInfo;
234
234
  * frameRate: ?number,
235
235
  * pixelAspectRatio: ?string,
236
236
  * hdr: ?string,
237
+ * colorGamut: ?string,
237
238
  * videoLayout: ?string,
238
239
  * mimeType: ?string,
239
240
  * audioMimeType: ?string,
@@ -299,6 +300,8 @@ shaka.extern.BufferedInfo;
299
300
  * The video pixel aspect ratio provided in the manifest, if present.
300
301
  * @property {?string} hdr
301
302
  * The video HDR provided in the manifest, if present.
303
+ * @property {?string} colorGamut
304
+ * The video color gamut provided in the manifest, if present.
302
305
  * @property {?string} videoLayout
303
306
  * The video layout provided in the manifest, if present.
304
307
  * @property {?string} mimeType
@@ -392,7 +395,10 @@ shaka.extern.TrackList;
392
395
  * maxFrameRate: number,
393
396
  *
394
397
  * minBandwidth: number,
395
- * maxBandwidth: number
398
+ * maxBandwidth: number,
399
+ *
400
+ * minChannelsCount: number,
401
+ * maxChannelsCount: number
396
402
  * }}
397
403
  *
398
404
  * @description
@@ -429,6 +435,11 @@ shaka.extern.TrackList;
429
435
  * The minimum bandwidth of a variant track, in bit/sec.
430
436
  * @property {number} maxBandwidth
431
437
  * The maximum bandwidth of a variant track, in bit/sec.
438
+ *
439
+ * @property {number} minChannelsCount
440
+ * The minimum channels count of a variant track.
441
+ * @property {number} maxChannelsCount
442
+ * The maximum channels count of a variant track.
432
443
  * @exportDoc
433
444
  */
434
445
  shaka.extern.Restrictions;
@@ -436,11 +447,26 @@ shaka.extern.Restrictions;
436
447
 
437
448
  /**
438
449
  * @typedef {{
439
- * persistentState: boolean
450
+ * persistentState: boolean,
451
+ * encryptionSchemes: !Array<string|null>,
452
+ * videoRobustnessLevels: !Array<string>,
453
+ * audioRobustnessLevels: !Array<string>
440
454
  * }}
441
455
  *
442
456
  * @property {boolean} persistentState
443
457
  * Whether this key system supports persistent state.
458
+ * @property {!Array<string|null>} encryptionSchemes
459
+ * An array of encryption schemes that are reported to work, through either
460
+ * EME or MCap APIs. An empty array indicates that encryptionScheme queries
461
+ * are not supported. This should not happen if our polyfills are installed.
462
+ * @property {!Array<string>} videoRobustnessLevels
463
+ * An array of video robustness levels that are reported to work. An empty
464
+ * array indicates that none were tested. Not all key systems have a list of
465
+ * known robustness levels built into probeSupport().
466
+ * @property {!Array<string>} audioRobustnessLevels
467
+ * An array of audio robustness levels that are reported to work. An empty
468
+ * array indicates that none were tested. Not all key systems have a list of
469
+ * known robustness levels built into probeSupport().
444
470
  * @exportDoc
445
471
  */
446
472
  shaka.extern.DrmSupportType;
@@ -450,7 +476,8 @@ shaka.extern.DrmSupportType;
450
476
  * @typedef {{
451
477
  * manifest: !Object.<string, boolean>,
452
478
  * media: !Object.<string, boolean>,
453
- * drm: !Object.<string, ?shaka.extern.DrmSupportType>
479
+ * drm: !Object.<string, ?shaka.extern.DrmSupportType>,
480
+ * hardwareResolution: shaka.extern.Resolution
454
481
  * }}
455
482
  *
456
483
  * @description
@@ -466,6 +493,10 @@ shaka.extern.DrmSupportType;
466
493
  * A map of supported key systems.
467
494
  * The keys are the key system names. The value is <code>null</code> if it is
468
495
  * not supported. Key systems not probed will not be in this dictionary.
496
+ * @property {shaka.extern.Resolution} hardwareResolution
497
+ * The maximum detected hardware resolution, which may have
498
+ * height==width==Infinity for devices without a maximum resolution or
499
+ * without a way to detect the maximum.
469
500
  *
470
501
  * @exportDoc
471
502
  */
@@ -677,7 +708,8 @@ shaka.extern.ProducerReferenceTime;
677
708
  * serverCertificate: Uint8Array,
678
709
  * serverCertificateUri: string,
679
710
  * individualizationServer: string,
680
- * sessionType: string
711
+ * sessionType: string,
712
+ * headers: !Object.<string, string>
681
713
  * }}
682
714
  *
683
715
  * @property {boolean} distinctiveIdentifierRequired
@@ -716,6 +748,8 @@ shaka.extern.ProducerReferenceTime;
716
748
  * <i>Defaults to <code>'temporary'</code> for streaming.</i> <br>
717
749
  * The MediaKey session type to create streaming licenses with. This doesn't
718
750
  * affect offline storage.
751
+ * @property {!Object.<string, string>} headers
752
+ * The headers to use in the license request.
719
753
  *
720
754
  * @exportDoc
721
755
  */
@@ -906,7 +940,8 @@ shaka.extern.xml.Node;
906
940
  * enableAudioGroups: boolean,
907
941
  * multiTypeVariantsAllowed: boolean,
908
942
  * useStreamOnceInPeriodFlattening: boolean,
909
- * updatePeriod: number
943
+ * updatePeriod: number,
944
+ * enableFastSwitching: boolean
910
945
  * }}
911
946
  *
912
947
  * @property {string} clockSyncUri
@@ -995,6 +1030,9 @@ shaka.extern.xml.Node;
995
1030
  * manifest less frequently. if you update the value during for a dynamic
996
1031
  * manifest, it will directly trigger a new download of the manifest
997
1032
  * Defaults to <code>-1</code>.
1033
+ * @property {boolean} enableFastSwitching
1034
+ * If false, disables fast switching track recognition.
1035
+ * Defaults to <code>true</code>.
998
1036
  * @exportDoc
999
1037
  */
1000
1038
  shaka.extern.DashManifestConfiguration;
@@ -1014,6 +1052,7 @@ shaka.extern.DashManifestConfiguration;
1014
1052
  * sequenceMode: boolean,
1015
1053
  * ignoreManifestTimestampsInSegmentsMode: boolean,
1016
1054
  * disableCodecGuessing: boolean,
1055
+ * disableClosedCaptionsDetection: boolean,
1017
1056
  * allowLowLatencyByteRangeOptimization: boolean
1018
1057
  * }}
1019
1058
  *
@@ -1082,6 +1121,11 @@ shaka.extern.DashManifestConfiguration;
1082
1121
  * As a consequence, lazy-loading media playlists won't be possible for this
1083
1122
  * use case, which may result in longer video startup times.
1084
1123
  * <i>Defaults to <code>false</code>.</i>
1124
+ * @property {boolean} disableClosedCaptionsDetection
1125
+ * If true, disables the automatic detection of closed captions.
1126
+ * Otherwise, in the absence of a EXT-X-MEDIA tag with TYPE="CLOSED-CAPTIONS",
1127
+ * Shaka Player will attempt to detect captions based on the media data.
1128
+ * <i>Defaults to <code>false</code>.</i>
1085
1129
  * @property {boolean} allowLowLatencyByteRangeOptimization
1086
1130
  * If set to true, the HLS parser will optimize operation with LL and partial
1087
1131
  * byte range segments. More info in
@@ -1206,6 +1250,7 @@ shaka.extern.ManifestConfiguration;
1206
1250
  * inaccurateManifestTolerance: number,
1207
1251
  * lowLatencyMode: boolean,
1208
1252
  * autoLowLatencyMode: boolean,
1253
+ * forceHTTP: boolean,
1209
1254
  * forceHTTPS: boolean,
1210
1255
  * preferNativeHls: boolean,
1211
1256
  * updateIntervalSeconds: number,
@@ -1219,6 +1264,7 @@ shaka.extern.ManifestConfiguration;
1219
1264
  * disableTextPrefetch: boolean,
1220
1265
  * disableVideoPrefetch: boolean,
1221
1266
  * liveSync: boolean,
1267
+ * liveSyncTargetLatencyTolerance: number,
1222
1268
  * liveSyncMaxLatency: number,
1223
1269
  * liveSyncPlaybackRate: number,
1224
1270
  * liveSyncMinLatency: number,
@@ -1231,7 +1277,9 @@ shaka.extern.ManifestConfiguration;
1231
1277
  * vodDynamicPlaybackRateLowBufferRate: number,
1232
1278
  * vodDynamicPlaybackRateBufferRatio: number,
1233
1279
  * infiniteLiveStreamDuration: boolean,
1234
- * loadTimeout: number
1280
+ * preloadNextUrlWindow: number,
1281
+ * loadTimeout: number,
1282
+ * clearDecodingCache: boolean
1235
1283
  * }}
1236
1284
  *
1237
1285
  * @description
@@ -1323,16 +1371,19 @@ shaka.extern.ManifestConfiguration;
1323
1371
  * extra segment requests necessary to compensate for drift.
1324
1372
  * @property {boolean} lowLatencyMode
1325
1373
  * If <code>true</code>, low latency streaming mode is enabled. If
1326
- * lowLatencyMode is set to true, inaccurateManifestTolerance is set to 0
1327
- * unless specified, and rebufferingGoal to 0.01 unless specified at the same
1328
- * time.
1374
+ * lowLatencyMode is set to true, it changes the default config values for
1375
+ * other things, see: docs/tutorials/config.md
1329
1376
  * @property {boolean} autoLowLatencyMode
1330
1377
  * If the stream is low latency and the user has not configured the
1331
1378
  * lowLatencyMode, but if it has been configured to activate the
1332
1379
  * lowLatencyMode if a stream of this type is detected, we automatically
1333
1380
  * activate the lowLatencyMode. Defaults to false.
1381
+ * @property {boolean} forceHTTP
1382
+ * If true, if the protocol is HTTPs change it to HTTP.
1383
+ * If both forceHTTP and forceHTTPS are set, forceHTTPS wins.
1334
1384
  * @property {boolean} forceHTTPS
1335
1385
  * If true, if the protocol is HTTP change it to HTTPs.
1386
+ * If both forceHTTP and forceHTTPS are set, forceHTTPS wins.
1336
1387
  * @property {boolean} preferNativeHls
1337
1388
  * If true, prefer native HLS playback when possible, regardless of platform.
1338
1389
  * @property {number} updateIntervalSeconds
@@ -1378,6 +1429,9 @@ shaka.extern.ManifestConfiguration;
1378
1429
  * rate. Defaults to <code>false</code>.
1379
1430
  * Note: on some SmartTVs, if this is activated, it may not work or the sound
1380
1431
  * may be lost when activated.
1432
+ * @property {number} liveSyncTargetLatencyTolerance
1433
+ * Latency tolerance for target latency, in seconds. Effective only if
1434
+ * liveSync is true. Defaults to <code>0.5</code>.
1381
1435
  * @property {number} liveSyncMaxLatency
1382
1436
  * Maximum acceptable latency, in seconds. Effective only if liveSync is
1383
1437
  * true. Defaults to <code>1</code>.
@@ -1422,10 +1476,22 @@ shaka.extern.ManifestConfiguration;
1422
1476
  * If <code>true</code>, the media source live duration
1423
1477
  * set as a<code>Infinity</code>
1424
1478
  * Defaults to <code> false </code>.
1479
+ * @property {number} preloadNextUrlWindow
1480
+ * The window of time at the end of the presentation to begin preloading the
1481
+ * next URL, such as one specified by a urn:mpeg:dash:chaining:2016 element
1482
+ * in DASH. Measured in seconds. If the value is 0, the next URL will not
1483
+ * be preloaded at all.
1484
+ * Defaults to <code> 30 </code>.
1425
1485
  * @property {number} loadTimeout
1426
1486
  * The maximum timeout to reject the load when using src= in case the content
1427
1487
  * does not work correctly. Measured in seconds.
1428
1488
  * Defaults to <code> 30 </code>.
1489
+ * @property {boolean} clearDecodingCache
1490
+ * Clears decodingInfo and MediaKeySystemAccess cache during player unload
1491
+ * as these objects may become corrupt and cause issues during subsequent
1492
+ * playbacks on some platforms.
1493
+ * Defaults to <code>true</code> on PlayStation devices and to
1494
+ * <code>false</code> on other devices.
1429
1495
  * @exportDoc
1430
1496
  */
1431
1497
  shaka.extern.StreamingConfiguration;
@@ -1481,7 +1547,8 @@ shaka.extern.MediaSourceConfiguration;
1481
1547
  /**
1482
1548
  * @typedef {{
1483
1549
  * customPlayheadTracker: boolean,
1484
- * skipPlayDetection: boolean
1550
+ * skipPlayDetection: boolean,
1551
+ * supportsMultipleMediaElements: boolean
1485
1552
  * }}
1486
1553
  *
1487
1554
  * @description
@@ -1491,13 +1558,20 @@ shaka.extern.MediaSourceConfiguration;
1491
1558
  * If this is <code>true</code>, we create a custom playhead tracker for
1492
1559
  * Client Side. This is useful because it allows you to implement the use of
1493
1560
  * IMA on platforms that do not support multiple video elements.
1494
- * This value defaults to <code>false</code>.
1561
+ * Defaults to <code>false</code> except on Tizen, WebOS, Chromecast,
1562
+ * Hisense, PlayStation 4, PlayStation5, Xbox whose default value is
1563
+ * <code>true</code>.
1495
1564
  * @property {boolean} skipPlayDetection
1496
1565
  * If this is true, we will load Client Side ads without waiting for a play
1497
1566
  * event.
1498
1567
  * Defaults to <code>false</code> except on Tizen, WebOS, Chromecast,
1499
1568
  * Hisense, PlayStation 4, PlayStation5, Xbox whose default value is
1500
1569
  * <code>true</code>.
1570
+ * @property {boolean} supportsMultipleMediaElements
1571
+ * If this is true, the browser supports multiple media elements.
1572
+ * Defaults to <code>true</code> except on Tizen, WebOS, Chromecast,
1573
+ * Hisense, PlayStation 4, PlayStation5, Xbox whose default value is
1574
+ * <code>false</code>.
1501
1575
  *
1502
1576
  * @exportDoc
1503
1577
  */
@@ -1518,7 +1592,8 @@ shaka.extern.AdsConfiguration;
1518
1592
  * restrictToScreenSize: boolean,
1519
1593
  * ignoreDevicePixelRatio: boolean,
1520
1594
  * clearBufferSwitch: boolean,
1521
- * safeMarginSwitch: number
1595
+ * safeMarginSwitch: number,
1596
+ * cacheLoadThreshold: number
1522
1597
  * }}
1523
1598
  *
1524
1599
  * @property {boolean} enabled
@@ -1576,6 +1651,10 @@ shaka.extern.AdsConfiguration;
1576
1651
  * Can cause hiccups on some browsers if chosen too small, e.g.
1577
1652
  * The amount of two segments is a fair minimum to consider as safeMargin
1578
1653
  * value.
1654
+ * @property {number} cacheLoadThreshold
1655
+ * Indicates the value in milliseconds from which a request is not
1656
+ * considered cached.
1657
+ * Defaults to <code>20</code>.
1579
1658
  * @exportDoc
1580
1659
  */
1581
1660
  shaka.extern.AbrConfiguration;
@@ -1989,3 +2068,17 @@ shaka.extern.Thumbnail;
1989
2068
  * @exportDoc
1990
2069
  */
1991
2070
  shaka.extern.Chapter;
2071
+
2072
+ /**
2073
+ * @typedef {{
2074
+ * width: number,
2075
+ * height: number
2076
+ * }}
2077
+ *
2078
+ * @property {number} width
2079
+ * Width in pixels.
2080
+ * @property {number} height
2081
+ * Height in pixels.
2082
+ * @exportDoc
2083
+ */
2084
+ shaka.extern.Resolution;
package/externs/tizen.js CHANGED
@@ -19,7 +19,7 @@ webapis.systeminfo = {};
19
19
 
20
20
 
21
21
  /**
22
- * @return {{width: number, height: number}}
22
+ * @return {shaka.extern.Resolution}
23
23
  */
24
24
  webapis.systeminfo.getMaxVideoResolution = function() {};
25
25
 
@@ -308,6 +308,11 @@ shaka.abr.SimpleAbrManager = class {
308
308
  * @export
309
309
  */
310
310
  segmentDownloaded(deltaTimeMs, numBytes, allowSwitch, request) {
311
+ if (deltaTimeMs < this.config_.cacheLoadThreshold) {
312
+ // The time indicates that it could be a cache response, so we should
313
+ // ignore this value.
314
+ return;
315
+ }
311
316
  shaka.log.v2('Segment downloaded:',
312
317
  'contentType=' + (request && request.contentType),
313
318
  'deltaTimeMs=' + deltaTimeMs,
@@ -33,6 +33,9 @@ shaka.ads.MediaTailorAd = class {
33
33
 
34
34
  /** @private {boolean} */
35
35
  this.isLinear_ = isLinear;
36
+
37
+ /** @private {boolean} */
38
+ this.isSkipped_ = false;
36
39
  }
37
40
 
38
41
 
@@ -105,6 +108,7 @@ shaka.ads.MediaTailorAd = class {
105
108
  * @export
106
109
  */
107
110
  skip() {
111
+ this.isSkipped_ = true;
108
112
  this.video_.currentTime += this.getRemainingTime();
109
113
  }
110
114
 
@@ -294,4 +298,11 @@ shaka.ads.MediaTailorAd = class {
294
298
  this.adPosition_ = null;
295
299
  this.totalAds_ = null;
296
300
  }
301
+
302
+ /**
303
+ * @return {boolean}
304
+ */
305
+ isSkipped() {
306
+ return this.isSkipped_;
307
+ }
297
308
  };
@@ -452,6 +452,10 @@ shaka.ads.MediaTailorAdManager = class {
452
452
  this.sendInProgressEvents_(currentTime, this.mediaTailorAd_);
453
453
  const remainingTime = this.ad_.getRemainingTime();
454
454
  const duration = this.ad_.getDuration();
455
+ if (this.ad_.canSkipNow() && remainingTime > 0 && duration > 0) {
456
+ this.sendTrackingEvent_(
457
+ shaka.ads.MediaTailorAdManager.SKIP_STATE_CHANGED_);
458
+ }
455
459
  if (duration > 0 && (remainingTime <= 0 || remainingTime > duration)) {
456
460
  this.onEnded_();
457
461
  }
@@ -610,7 +614,7 @@ shaka.ads.MediaTailorAdManager = class {
610
614
  if (!this.isLive_) {
611
615
  this.playedAds_.push(this.mediaTailorAd_.adId);
612
616
  }
613
- this.removeCurrentAdListeners_();
617
+ this.removeCurrentAdListeners_(this.ad_.isSkipped());
614
618
  const position = this.ad_.getPositionInSequence();
615
619
  const totalAdsInBreak = this.ad_.getSequenceLength();
616
620
  if (position === totalAdsInBreak) {
@@ -679,10 +683,15 @@ shaka.ads.MediaTailorAdManager = class {
679
683
  }
680
684
 
681
685
  /**
686
+ * @param {boolean=} skipped
682
687
  * @private
683
688
  */
684
- removeCurrentAdListeners_() {
685
- this.sendTrackingEvent_(shaka.ads.MediaTailorAdManager.COMPLETE_);
689
+ removeCurrentAdListeners_(skipped = false) {
690
+ if (skipped) {
691
+ this.sendTrackingEvent_(shaka.ads.MediaTailorAdManager.SKIPPED_);
692
+ } else {
693
+ this.sendTrackingEvent_(shaka.ads.MediaTailorAdManager.COMPLETE_);
694
+ }
686
695
  for (const listener of this.adListeners_) {
687
696
  this.eventManager_.unlisten(
688
697
  listener.target, listener.type, listener.listener);
@@ -759,12 +768,23 @@ shaka.ads.MediaTailorAdManager = class {
759
768
  this.onEvent_(
760
769
  new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STOPPED));
761
770
  break;
771
+ case shaka.ads.MediaTailorAdManager.SKIPPED_:
772
+ this.onEvent_(
773
+ new shaka.util.FakeEvent(shaka.ads.AdManager.AD_SKIPPED));
774
+ this.onEvent_(
775
+ new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STOPPED));
776
+ break;
762
777
  case shaka.ads.MediaTailorAdManager.BREAKSTART_:
763
778
  this.adContainer_.setAttribute('ad-active', 'true');
764
779
  break;
765
780
  case shaka.ads.MediaTailorAdManager.BREAKEND_:
766
781
  this.adContainer_.removeAttribute('ad-active');
767
782
  break;
783
+ case shaka.ads.MediaTailorAdManager.SKIP_STATE_CHANGED_:
784
+ this.onEvent_(
785
+ new shaka.util.FakeEvent(
786
+ shaka.ads.AdManager.AD_SKIP_STATE_CHANGED));
787
+ break;
768
788
  }
769
789
  }
770
790
  };
@@ -840,6 +860,13 @@ shaka.ads.MediaTailorAdManager.THIRDQUARTILE_ = 'thirdQuartile';
840
860
  shaka.ads.MediaTailorAdManager.COMPLETE_ = 'complete';
841
861
 
842
862
 
863
+ /**
864
+ * @const {string}
865
+ * @private
866
+ */
867
+ shaka.ads.MediaTailorAdManager.SKIPPED_ = 'skip';
868
+
869
+
843
870
  /**
844
871
  * @const {string}
845
872
  * @private
@@ -852,3 +879,10 @@ shaka.ads.MediaTailorAdManager.BREAKSTART_ = 'breakStart';
852
879
  * @private
853
880
  */
854
881
  shaka.ads.MediaTailorAdManager.BREAKEND_ = 'breakEnd';
882
+
883
+
884
+ /**
885
+ * @const {string}
886
+ * @private
887
+ */
888
+ shaka.ads.MediaTailorAdManager.SKIP_STATE_CHANGED_ = 'skipStateChanged';
@@ -642,6 +642,15 @@ shaka.cea.Cea608DataChannel = class {
642
642
  // b1 -> |P|0|0|1|X|X|X|X|
643
643
  return (b1 & 0x70) === 0x10;
644
644
  }
645
+
646
+ /**
647
+ * Checks if the data contains a XDS control code.
648
+ * @param {number} b1 Byte 1.
649
+ * @return {boolean}
650
+ */
651
+ static isXdsControlCode(b1) {
652
+ return b1 >= 0x01 && b1 <= 0x0F;
653
+ }
645
654
  };
646
655
 
647
656
  /**
@@ -307,16 +307,20 @@ shaka.cea.CeaDecoder = class {
307
307
  ccPacket.ccData1 &= 0x7f;
308
308
  ccPacket.ccData2 &= 0x7f;
309
309
 
310
+ // Ignore XDS
311
+ if (shaka.cea.Cea608DataChannel.isXdsControlCode(ccPacket.ccData1)) {
312
+ return null;
313
+ }
314
+
310
315
  // Check for empty captions and skip them.
311
316
  if (!ccPacket.ccData1 && !ccPacket.ccData2) {
312
317
  return null;
313
318
  }
314
319
 
315
- this.streams_.add(selectedMode);
316
-
317
320
  // Process the clean CC data pair.
318
321
  let parsedClosedCaption = null;
319
322
  if (shaka.cea.Cea608DataChannel.isControlCode(ccPacket.ccData1)) {
323
+ this.streams_.add(selectedMode);
320
324
  parsedClosedCaption = selectedStream.handleControlCode(ccPacket);
321
325
  } else {
322
326
  // Handle as a Basic North American Character.