shaka-player 3.2.0 → 3.2.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.
Files changed (162) hide show
  1. package/.github/workflows/build_and_test.yaml +73 -0
  2. package/.github/workflows/release.yaml +53 -0
  3. package/AUTHORS +3 -0
  4. package/CHANGELOG.md +182 -1
  5. package/CONTRIBUTORS +3 -0
  6. package/README.md +4 -4
  7. package/build/checkversion.py +1 -1
  8. package/build/generateExterns.js +1 -1
  9. package/build/misspellings.txt +1 -0
  10. package/build/shakaBuildHelpers.py +6 -5
  11. package/build/subprocessWindowsPatch.py +103 -0
  12. package/build/test.py +6 -0
  13. package/demo/common/assets.js +1 -1
  14. package/demo/index.html +1 -1
  15. package/dist/controls.css +2 -2
  16. package/dist/controls.css.map +1 -1
  17. package/dist/demo.compiled.debug.js +1 -1
  18. package/dist/demo.compiled.js +1 -1
  19. package/dist/deps.js +8 -8
  20. package/dist/locales.js +37 -37
  21. package/dist/receiver.compiled.debug.js +1 -1
  22. package/dist/receiver.compiled.js +1 -1
  23. package/dist/shaka-player.compiled.d.ts +195 -5
  24. package/dist/shaka-player.compiled.debug.d.ts +195 -5
  25. package/dist/shaka-player.compiled.debug.externs.js +226 -14
  26. package/dist/shaka-player.compiled.debug.js +424 -399
  27. package/dist/shaka-player.compiled.debug.map +4 -4
  28. package/dist/shaka-player.compiled.externs.js +226 -14
  29. package/dist/shaka-player.compiled.js +826 -812
  30. package/dist/shaka-player.compiled.map +4 -4
  31. package/dist/shaka-player.ui.d.ts +197 -16
  32. package/dist/shaka-player.ui.debug.d.ts +197 -16
  33. package/dist/shaka-player.ui.debug.externs.js +230 -27
  34. package/dist/shaka-player.ui.debug.js +466 -442
  35. package/dist/shaka-player.ui.debug.map +4 -4
  36. package/dist/shaka-player.ui.externs.js +230 -27
  37. package/dist/shaka-player.ui.js +946 -932
  38. package/dist/shaka-player.ui.map +4 -4
  39. package/docs/tutorials/fairplay.md +1 -1
  40. package/docs/tutorials/faq.md +14 -0
  41. package/docs/tutorials/ui.md +5 -5
  42. package/externs/ima.js +4 -0
  43. package/externs/shaka/ads.js +25 -0
  44. package/externs/shaka/player.js +8 -0
  45. package/externs/shaka/text.js +10 -0
  46. package/karma.conf.js +20 -15
  47. package/lib/ads/ad_manager.js +46 -26
  48. package/lib/ads/client_side_ad_manager.js +82 -88
  49. package/lib/ads/server_side_ad_manager.js +45 -13
  50. package/lib/cast/cast_proxy.js +6 -2
  51. package/lib/cast/cast_receiver.js +5 -1
  52. package/lib/cast/cast_sender.js +2 -2
  53. package/lib/cea/sei_processor.js +24 -17
  54. package/lib/dash/dash_parser.js +131 -24
  55. package/lib/dash/segment_list.js +1 -1
  56. package/lib/dash/segment_template.js +1 -1
  57. package/lib/hls/hls_parser.js +74 -17
  58. package/lib/hls/manifest_text_parser.js +1 -0
  59. package/lib/media/closed_caption_parser.js +3 -1
  60. package/lib/media/content_workarounds.js +12 -0
  61. package/lib/media/drm_engine.js +20 -1
  62. package/lib/media/gap_jumping_controller.js +8 -4
  63. package/lib/media/media_source_engine.js +1 -2
  64. package/lib/media/playhead.js +1 -1
  65. package/lib/media/region_observer.js +39 -33
  66. package/lib/media/region_timeline.js +17 -19
  67. package/lib/media/segment_index.js +2 -1
  68. package/lib/media/segment_reference.js +19 -1
  69. package/lib/media/streaming_engine.js +8 -4
  70. package/lib/net/networking_engine.js +6 -1
  71. package/lib/offline/download_manager.js +1 -2
  72. package/lib/offline/storage.js +8 -9
  73. package/lib/player.js +129 -59
  74. package/lib/polyfill/aria.js +12 -2
  75. package/lib/polyfill/encryption_scheme.js +2 -0
  76. package/lib/polyfill/fullscreen.js +2 -0
  77. package/lib/polyfill/mathround.js +2 -0
  78. package/lib/polyfill/media_capabilities.js +73 -21
  79. package/lib/polyfill/mediasource.js +8 -0
  80. package/lib/polyfill/orientation.js +3 -1
  81. package/lib/polyfill/patchedmediakeys_apple.js +6 -4
  82. package/lib/polyfill/patchedmediakeys_ms.js +6 -4
  83. package/lib/polyfill/patchedmediakeys_nop.js +2 -0
  84. package/lib/polyfill/patchedmediakeys_webkit.js +6 -4
  85. package/lib/polyfill/pip_webkit.js +2 -0
  86. package/lib/polyfill/storage_estimate.js +2 -0
  87. package/lib/polyfill/video_play_promise.js +2 -0
  88. package/lib/polyfill/videoplaybackquality.js +2 -0
  89. package/lib/polyfill/vttcue.js +2 -0
  90. package/lib/text/cue.js +6 -0
  91. package/lib/text/mp4_ttml_parser.js +3 -0
  92. package/lib/text/text_engine.js +14 -2
  93. package/lib/text/ttml_text_parser.js +135 -87
  94. package/lib/text/ui_text_displayer.js +213 -80
  95. package/lib/text/vtt_text_parser.js +4 -2
  96. package/lib/text/web_vtt_generator.js +21 -12
  97. package/lib/util/fake_event.js +53 -7
  98. package/lib/util/fake_event_target.js +21 -1
  99. package/lib/util/mp4_box_parsers.js +1 -1
  100. package/lib/util/periods.js +4 -1
  101. package/lib/util/platform.js +13 -1
  102. package/lib/util/stream_utils.js +105 -13
  103. package/lib/util/xml_utils.js +50 -12
  104. package/package.json +3 -6
  105. package/roadmap.md +24 -22
  106. package/test/cast/cast_proxy_unit.js +12 -6
  107. package/test/cast/cast_receiver_integration.js +1 -1
  108. package/test/cast/cast_utils_unit.js +1 -1
  109. package/test/cea/mp4_cea_parser_unit.js +26 -0
  110. package/test/dash/dash_parser_live_unit.js +43 -0
  111. package/test/dash/dash_parser_manifest_unit.js +222 -3
  112. package/test/hls/hls_parser_unit.js +79 -1
  113. package/test/media/closed_caption_parser_unit.js +20 -0
  114. package/test/media/drm_engine_integration.js +86 -2
  115. package/test/media/drm_engine_unit.js +57 -0
  116. package/test/media/playhead_unit.js +27 -1
  117. package/test/media/region_observer_unit.js +40 -5
  118. package/test/media/region_timeline_unit.js +40 -22
  119. package/test/media/streaming_engine_integration.js +2 -1
  120. package/test/media/streaming_engine_unit.js +145 -0
  121. package/test/player_integration.js +79 -8
  122. package/test/player_src_equals_integration.js +41 -8
  123. package/test/player_unit.js +14 -4
  124. package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
  125. package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
  126. package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
  127. package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
  128. package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
  129. package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
  130. package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
  131. package/test/test/assets/3675/dash_0.mpd +30 -0
  132. package/test/test/assets/3675/dash_1.mpd +30 -0
  133. package/test/test/assets/3675/dash_2.mpd +30 -0
  134. package/test/test/assets/3675/dash_3.mpd +30 -0
  135. package/test/test/assets/3675/dash_4.mpd +30 -0
  136. package/test/test/assets/3675/dash_5.mpd +26 -0
  137. package/test/test/assets/3675/init-stream0.m4s +0 -0
  138. package/test/test/assets/chapters.vtt +2 -2
  139. package/test/test/assets/chapters2.vtt +10 -0
  140. package/test/test/assets/empty_caption_video_init.mp4 +0 -0
  141. package/test/test/assets/empty_caption_video_segment.mp4 +0 -0
  142. package/test/test/util/fake_ad_manager.js +11 -1
  143. package/test/test/util/ttml_utils.js +81 -0
  144. package/test/test/util/util.js +10 -7
  145. package/test/text/mp4_ttml_parser_unit.js +11 -18
  146. package/test/text/ttml_text_parser_unit.js +542 -220
  147. package/test/text/ui_text_displayer_unit.js +93 -20
  148. package/test/text/vtt_text_parser_unit.js +17 -1
  149. package/test/text/web_vtt_generator_unit.js +58 -3
  150. package/test/ui/localization_unit.js +15 -14
  151. package/test/ui/text_displayer_layout_unit.js +21 -8
  152. package/test/util/mp4_box_parsers_unit.js +28 -0
  153. package/test/util/stream_utils_unit.js +60 -3
  154. package/ui/cast_button.js +2 -3
  155. package/ui/controls.js +11 -6
  156. package/ui/less/buttons.less +0 -4
  157. package/ui/less/containers.less +6 -7
  158. package/ui/locales/ru.json +6 -6
  159. package/ui/localization.js +40 -87
  160. package/ui/pip_button.js +2 -3
  161. package/ui/seek_bar.js +1 -2
  162. package/ui/text_selection.js +1 -0
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xmlns="urn:mpeg:dash:schema:mpd:2011"
4
+ xmlns:xlink="http://www.w3.org/1999/xlink"
5
+ xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
6
+ profiles="urn:mpeg:dash:profile:isoff-live:2011"
7
+ type="dynamic"
8
+ minimumUpdatePeriod="PT2S"
9
+ suggestedPresentationDelay="PT2S"
10
+ availabilityStartTime="2021-10-28T07:36:27.755Z"
11
+ publishTime="2021-10-28T07:36:31.750Z"
12
+ timeShiftBufferDepth="PT10.0S"
13
+ maxSegmentDuration="PT2.0S"
14
+ minBufferTime="PT4.0S">
15
+ <ProgramInformation>
16
+ </ProgramInformation>
17
+ <ServiceDescription id="0">
18
+ </ServiceDescription>
19
+ <Period id="0" start="PT0.0S">
20
+ <AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
21
+ <Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
22
+ <SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
23
+ <SegmentTimeline>
24
+ <S t="0" d="30720" r="1" />
25
+ </SegmentTimeline>
26
+ </SegmentTemplate>
27
+ </Representation>
28
+ </AdaptationSet>
29
+ </Period>
30
+ </MPD>
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xmlns="urn:mpeg:dash:schema:mpd:2011"
4
+ xmlns:xlink="http://www.w3.org/1999/xlink"
5
+ xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
6
+ profiles="urn:mpeg:dash:profile:isoff-live:2011"
7
+ type="dynamic"
8
+ minimumUpdatePeriod="PT2S"
9
+ suggestedPresentationDelay="PT2S"
10
+ availabilityStartTime="2021-10-28T07:36:27.755Z"
11
+ publishTime="2021-10-28T07:36:35.752Z"
12
+ timeShiftBufferDepth="PT10.0S"
13
+ maxSegmentDuration="PT2.0S"
14
+ minBufferTime="PT4.0S">
15
+ <ProgramInformation>
16
+ </ProgramInformation>
17
+ <ServiceDescription id="0">
18
+ </ServiceDescription>
19
+ <Period id="0" start="PT0.0S">
20
+ <AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
21
+ <Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
22
+ <SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
23
+ <SegmentTimeline>
24
+ <S t="0" d="30720" r="3" />
25
+ </SegmentTimeline>
26
+ </SegmentTemplate>
27
+ </Representation>
28
+ </AdaptationSet>
29
+ </Period>
30
+ </MPD>
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xmlns="urn:mpeg:dash:schema:mpd:2011"
4
+ xmlns:xlink="http://www.w3.org/1999/xlink"
5
+ xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
6
+ profiles="urn:mpeg:dash:profile:isoff-live:2011"
7
+ type="dynamic"
8
+ minimumUpdatePeriod="PT2S"
9
+ suggestedPresentationDelay="PT2S"
10
+ availabilityStartTime="2021-10-28T07:36:27.755Z"
11
+ publishTime="2021-10-28T07:36:37.752Z"
12
+ timeShiftBufferDepth="PT10.0S"
13
+ maxSegmentDuration="PT2.0S"
14
+ minBufferTime="PT4.0S">
15
+ <ProgramInformation>
16
+ </ProgramInformation>
17
+ <ServiceDescription id="0">
18
+ </ServiceDescription>
19
+ <Period id="0" start="PT0.0S">
20
+ <AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
21
+ <Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
22
+ <SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="1">
23
+ <SegmentTimeline>
24
+ <S t="0" d="30720" r="4" />
25
+ </SegmentTimeline>
26
+ </SegmentTemplate>
27
+ </Representation>
28
+ </AdaptationSet>
29
+ </Period>
30
+ </MPD>
@@ -0,0 +1,30 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xmlns="urn:mpeg:dash:schema:mpd:2011"
4
+ xmlns:xlink="http://www.w3.org/1999/xlink"
5
+ xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
6
+ profiles="urn:mpeg:dash:profile:isoff-live:2011"
7
+ type="dynamic"
8
+ minimumUpdatePeriod="PT2S"
9
+ suggestedPresentationDelay="PT2S"
10
+ availabilityStartTime="2021-10-28T07:36:27.755Z"
11
+ publishTime="2021-10-28T07:36:41.751Z"
12
+ timeShiftBufferDepth="PT10.0S"
13
+ maxSegmentDuration="PT2.0S"
14
+ minBufferTime="PT4.0S">
15
+ <ProgramInformation>
16
+ </ProgramInformation>
17
+ <ServiceDescription id="0">
18
+ </ServiceDescription>
19
+ <Period id="0" start="PT0.0S">
20
+ <AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
21
+ <Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
22
+ <SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="3">
23
+ <SegmentTimeline>
24
+ <S t="61440" d="30720" r="4" />
25
+ </SegmentTimeline>
26
+ </SegmentTemplate>
27
+ </Representation>
28
+ </AdaptationSet>
29
+ </Period>
30
+ </MPD>
@@ -0,0 +1,26 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <MPD xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xmlns="urn:mpeg:dash:schema:mpd:2011"
4
+ xmlns:xlink="http://www.w3.org/1999/xlink"
5
+ xsi:schemaLocation="urn:mpeg:DASH:schema:MPD:2011 http://standards.iso.org/ittf/PubliclyAvailableStandards/MPEG-DASH_schema_files/DASH-MPD.xsd"
6
+ profiles="urn:mpeg:dash:profile:isoff-live:2011"
7
+ type="static"
8
+ mediaPresentationDuration="PT14.0S"
9
+ maxSegmentDuration="PT2.0S"
10
+ minBufferTime="PT4.0S">
11
+ <ProgramInformation>
12
+ </ProgramInformation>
13
+ <ServiceDescription id="0">
14
+ </ServiceDescription>
15
+ <Period id="0" start="PT0.0S">
16
+ <AdaptationSet id="0" contentType="video" startWithSAP="1" segmentAlignment="true" bitstreamSwitching="true" frameRate="30/1" maxWidth="1280" maxHeight="720" par="16:9">
17
+ <Representation id="0" mimeType="video/mp4" codecs="avc1.64001f" bandwidth="122012" width="1280" height="720" sar="1:1">
18
+ <SegmentTemplate timescale="15360" initialization="init-stream$RepresentationID$.m4s" media="chunk-stream$RepresentationID$-$Number%05d$.m4s" startNumber="3">
19
+ <SegmentTimeline>
20
+ <S t="61440" d="30720" r="4" />
21
+ </SegmentTimeline>
22
+ </SegmentTemplate>
23
+ </Representation>
24
+ </AdaptationSet>
25
+ </Period>
26
+ </MPD>
@@ -3,8 +3,8 @@ WEBVTT
3
3
  00:00.000 --> 00:05.000
4
4
  Chapter 1
5
5
 
6
- 00:05.000 --> 00:30.000
6
+ 00:05.000 --> 00:10.000
7
7
  Chapter 2
8
8
 
9
- 00:30.000 --> 01:01.349
9
+ 00:10.000 --> 00:20.000
10
10
  Chapter 3
@@ -0,0 +1,10 @@
1
+ WEBVTT
2
+
3
+ 00:20.000 --> 00:30.000
4
+ Chapter 4
5
+
6
+ 00:30.000 --> 00:40.000
7
+ Chapter 5
8
+
9
+ 00:40.000 --> 01:01.349
10
+ Chapter 6
@@ -25,6 +25,9 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
25
25
  this.stats_ = new shaka.ads.AdsStats();
26
26
  }
27
27
 
28
+ /** @override */
29
+ release() {}
30
+
28
31
  /** @override */
29
32
  setLocale(locale) {}
30
33
 
@@ -50,6 +53,13 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
50
53
  /** @override */
51
54
  replaceServerSideAdTagParameters(adTagParameters) {}
52
55
 
56
+ /**
57
+ * @override
58
+ */
59
+ getServerSideCuePoints() {
60
+ return [];
61
+ }
62
+
53
63
  /** @override */
54
64
  getStats() {
55
65
  return this.stats_;
@@ -75,7 +85,7 @@ shaka.test.FakeAdManager = class extends shaka.util.FakeEventTarget {
75
85
  */
76
86
  startAd(ad) {
77
87
  const event = new shaka.util.FakeEvent(shaka.ads.AdManager.AD_STARTED,
78
- {'ad': ad});
88
+ (new Map()).set('ad', ad));
79
89
 
80
90
  this.dispatchEvent(event);
81
91
  }
@@ -0,0 +1,81 @@
1
+ /*! @license
2
+ * Shaka Player
3
+ * Copyright 2016 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ goog.provide('shaka.test.TtmlUtils');
8
+
9
+ shaka.test.TtmlUtils = class {
10
+ /**
11
+ * @param {!Array} expectedCues
12
+ * @param {!Array} actualCues
13
+ * @param {!Object} bodyProperties
14
+ * @param {Object=} divProperties
15
+ */
16
+ static verifyHelper(expectedCues, actualCues, bodyProperties, divProperties) {
17
+ const mapExpected = (cue) => {
18
+ if (cue.region) {
19
+ cue.region = jasmine.objectContaining(cue.region);
20
+ }
21
+
22
+ if (cue.nestedCues && (cue.nestedCues instanceof Array)) {
23
+ cue.nestedCues = cue.nestedCues.map(mapExpected);
24
+ }
25
+
26
+ if (cue.isContainer == undefined) {
27
+ // If not specified to be true, check for isContainer to be false.
28
+ cue.isContainer = false;
29
+ }
30
+
31
+ return jasmine.objectContaining(cue);
32
+ };
33
+
34
+ /**
35
+ * @param {!Object} properties
36
+ * @return {!shaka.extern.Cue}
37
+ */
38
+ const makeContainer = (properties) => {
39
+ const region = {
40
+ id: '',
41
+ viewportAnchorX: 0,
42
+ viewportAnchorY: 0,
43
+ regionAnchorX: 0,
44
+ regionAnchorY: 0,
45
+ width: 100,
46
+ height: 100,
47
+ widthUnits: shaka.text.CueRegion.units.PERCENTAGE,
48
+ heightUnits: shaka.text.CueRegion.units.PERCENTAGE,
49
+ viewportAnchorUnits: shaka.text.CueRegion.units.PERCENTAGE,
50
+ scroll: '',
51
+ };
52
+ const containerCue = /** @type {!shaka.extern.Cue} */ ({
53
+ region,
54
+ nestedCues: jasmine.any(Object),
55
+ payload: '',
56
+ startTime: 0,
57
+ endTime: Infinity,
58
+ isContainer: true,
59
+ });
60
+ Object.assign(containerCue, properties);
61
+ return mapExpected(containerCue);
62
+ };
63
+
64
+ if (expectedCues.length == 0 && !divProperties) {
65
+ expect(actualCues.length).toBe(0);
66
+ } else {
67
+ // Body.
68
+ expect(actualCues.length).toBe(1);
69
+ const body = actualCues[0];
70
+ expect(body).toEqual(makeContainer(bodyProperties));
71
+
72
+ // Div.
73
+ expect(body.nestedCues.length).toBe(1);
74
+ const div = body.nestedCues[0];
75
+ expect(div).toEqual(makeContainer(divProperties || bodyProperties));
76
+
77
+ // Cues.
78
+ expect(div.nestedCues).toEqual(expectedCues.map(mapExpected));
79
+ }
80
+ }
81
+ };
@@ -401,10 +401,10 @@ shaka.test.Util = class {
401
401
  * within the bounds of the viewport.
402
402
  * @param {string} name An identifier for the screenshot. Use alphanumeric
403
403
  * plus dash and underscore only.
404
- * @param {number} threshold A change threshold in pixels.
404
+ * @param {number} minSimilarity A minimum similarity score between 0 and 1.
405
405
  * @return {!Promise}
406
406
  */
407
- static async checkScreenshot(element, name, threshold=0) {
407
+ static async checkScreenshot(element, name, minSimilarity=1) {
408
408
  // Make sure the DOM is up-to-date and layout has settled before continuing.
409
409
  // Without this delay, or with a shorter delay, we sometimes get missing
410
410
  // elements in our UITextDisplayer tests on some platforms.
@@ -448,13 +448,16 @@ shaka.test.Util = class {
448
448
  const buffer = await shaka.test.Util.fetch(
449
449
  '/screenshot/diff' + parentUrlParams + paramsString);
450
450
  const json = shaka.util.StringUtils.fromUTF8(buffer);
451
- const pixelsChanged = /** @type {number} */(JSON.parse(json));
451
+ const similarity = /** @type {number} */(JSON.parse(json));
452
452
 
453
- // If the change threshold is exceeded, you can review the new screenshot
453
+ // If the minimum similarity is not met, you can review the new screenshot
454
454
  // and the diff image in the screenshots folder. Look for images that end
455
- // with "-new" and "-diff". If cropping doesn't work right, you can view
456
- // the full-page screenshot in the image that ends with "-full".
457
- expect(pixelsChanged).withContext(name).not.toBeGreaterThan(threshold);
455
+ // with "-new" and "-diff". (NOTE: The diff is a pixel-wise diff for human
456
+ // review, and is not produced with the same structural similarity
457
+ // algorithm used to detect changes in the test.) If cropping doesn't work
458
+ // right, you can view the full-page screenshot in the image that ends with
459
+ // "-full".
460
+ expect(similarity).withContext(name).not.toBeLessThan(minSimilarity);
458
461
  }
459
462
  };
460
463
 
@@ -4,6 +4,7 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
+ goog.require('shaka.test.TtmlUtils');
7
8
  goog.require('shaka.test.Util');
8
9
  goog.require('shaka.text.Mp4TtmlParser');
9
10
  goog.require('shaka.util.BufferUtils');
@@ -48,7 +49,14 @@ describe('Mp4TtmlParser', () => {
48
49
  parser.parseInit(ttmlInitSegment);
49
50
  const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0};
50
51
  const ret = parser.parseMedia(ttmlSegmentMultipleMDAT, time);
51
- expect(ret.length).toBe(20);
52
+ // Bodies.
53
+ expect(ret.length).toBe(2);
54
+ // Divs.
55
+ expect(ret[0].nestedCues.length).toBe(1);
56
+ expect(ret[1].nestedCues.length).toBe(1);
57
+ // Cues.
58
+ expect(ret[0].nestedCues[0].nestedCues.length).toBe(10);
59
+ expect(ret[1].nestedCues[0].nestedCues.length).toBe(10);
52
60
  });
53
61
 
54
62
  it('accounts for offset', () => {
@@ -159,22 +167,7 @@ describe('Mp4TtmlParser', () => {
159
167
  parser.parseInit(ttmlInitSegment);
160
168
  const time = {periodStart: 0, segmentStart: 0, segmentEnd: 0};
161
169
  const result = parser.parseMedia(ttmlSegment, time);
162
- verifyHelper(cues, result);
170
+ shaka.test.TtmlUtils.verifyHelper(
171
+ cues, result, {startTime: 23, endTime: 53.5});
163
172
  });
164
-
165
- function verifyHelper(/** !Array */ expected, /** !Array */ actual) {
166
- const mapExpected = (cue) => {
167
- if (cue.region) {
168
- cue.region = jasmine.objectContaining(cue.region);
169
- }
170
-
171
- if (cue.nestedCues) {
172
- cue.nestedCues = cue.nestedCues.map(mapExpected);
173
- }
174
-
175
- return jasmine.objectContaining(cue);
176
- };
177
-
178
- expect(actual).toEqual(expected.map(mapExpected));
179
- }
180
173
  });