shaka-player 4.2.5 → 4.3.1

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 (143) hide show
  1. package/.github/workflows/build-and-test.yaml +7 -0
  2. package/.github/workflows/sync-labels.yaml +1 -1
  3. package/.github/workflows/update-issues.yaml +1 -1
  4. package/AUTHORS +4 -0
  5. package/CHANGELOG.md +114 -74
  6. package/CONTRIBUTORS +4 -0
  7. package/README.md +14 -0
  8. package/conditional/dummy_cast_proxy.js +120 -0
  9. package/demo/common/assets.js +58 -0
  10. package/demo/common/message_ids.js +22 -1
  11. package/demo/config.js +89 -5
  12. package/demo/demo.less +7 -1
  13. package/demo/index.html +8 -1
  14. package/demo/locales/en.json +21 -1
  15. package/demo/locales/source.json +82 -2
  16. package/demo/main.js +57 -1
  17. package/demo/search.js +2 -0
  18. package/demo/visualizer.js +337 -0
  19. package/demo/visualizer_button.js +103 -0
  20. package/dist/controls.css +1 -1
  21. package/dist/controls.css.map +1 -1
  22. package/dist/demo.compiled.debug.js +107 -88
  23. package/dist/demo.compiled.debug.map +4 -4
  24. package/dist/demo.compiled.js +107 -88
  25. package/dist/demo.compiled.map +4 -4
  26. package/dist/demo.css +1 -1
  27. package/dist/demo.css.map +1 -1
  28. package/dist/deps.js +21 -13
  29. package/dist/locales.js +31 -31
  30. package/dist/receiver.compiled.debug.js +75 -77
  31. package/dist/receiver.compiled.debug.map +3 -3
  32. package/dist/receiver.compiled.js +75 -77
  33. package/dist/receiver.compiled.map +3 -3
  34. package/dist/shaka-player.compiled.d.ts +181 -27
  35. package/dist/shaka-player.compiled.debug.d.ts +181 -27
  36. package/dist/shaka-player.compiled.debug.externs.js +169 -31
  37. package/dist/shaka-player.compiled.debug.js +510 -450
  38. package/dist/shaka-player.compiled.debug.map +4 -4
  39. package/dist/shaka-player.compiled.externs.js +169 -31
  40. package/dist/shaka-player.compiled.js +912 -874
  41. package/dist/shaka-player.compiled.map +4 -4
  42. package/dist/shaka-player.ui.d.ts +181 -27
  43. package/dist/shaka-player.ui.debug.d.ts +181 -27
  44. package/dist/shaka-player.ui.debug.externs.js +169 -31
  45. package/dist/shaka-player.ui.debug.js +533 -471
  46. package/dist/shaka-player.ui.debug.map +4 -4
  47. package/dist/shaka-player.ui.externs.js +169 -31
  48. package/dist/shaka-player.ui.js +1073 -1036
  49. package/dist/shaka-player.ui.map +4 -4
  50. package/docs/design/lcevc-architecture.png +0 -0
  51. package/docs/design/lcevc-demo.png +0 -0
  52. package/docs/design/lcevc-integration.md +72 -0
  53. package/docs/tutorials/fairplay.md +7 -0
  54. package/docs/tutorials/faq.md +1 -1
  55. package/docs/tutorials/ui.md +7 -7
  56. package/docs/tutorials/upgrade.md +6 -0
  57. package/externs/ima.js +13 -1
  58. package/externs/lcevc.js +81 -0
  59. package/externs/mux.js +1 -42
  60. package/externs/shaka/ads.js +11 -1
  61. package/externs/shaka/manifest_parser.js +5 -1
  62. package/externs/shaka/mp4_parser.js +3 -0
  63. package/externs/shaka/player.js +178 -15
  64. package/lib/abr/simple_abr_manager.js +7 -0
  65. package/lib/ads/ad_manager.js +0 -8
  66. package/lib/ads/client_side_ad.js +15 -0
  67. package/lib/ads/client_side_ad_manager.js +21 -8
  68. package/lib/ads/server_side_ad.js +15 -0
  69. package/lib/ads/server_side_ad_manager.js +3 -3
  70. package/lib/cast/cast_utils.js +2 -0
  71. package/lib/cea/dummy_cea_parser.js +28 -0
  72. package/lib/cea/i_cea_parser.js +14 -2
  73. package/lib/cea/mp4_cea_parser.js +108 -5
  74. package/lib/config/auto_show_text.js +33 -0
  75. package/lib/dash/dash_parser.js +1 -1
  76. package/lib/hls/hls_parser.js +808 -384
  77. package/lib/lcevc/lcevc_dil.js +152 -0
  78. package/lib/media/closed_caption_parser.js +9 -6
  79. package/lib/media/drm_engine.js +14 -6
  80. package/lib/media/media_source_capabilities.js +36 -0
  81. package/lib/media/media_source_engine.js +113 -28
  82. package/lib/media/presentation_timeline.js +26 -11
  83. package/lib/media/segment_reference.js +49 -1
  84. package/lib/media/streaming_engine.js +142 -12
  85. package/lib/media/transmuxer.js +78 -21
  86. package/lib/offline/storage.js +1 -0
  87. package/lib/player.js +456 -77
  88. package/lib/polyfill/media_capabilities.js +9 -5
  89. package/lib/polyfill/patchedmediakeys_apple.js +63 -4
  90. package/lib/text/vtt_text_parser.js +35 -1
  91. package/lib/util/dom_utils.js +0 -1
  92. package/lib/util/error.js +17 -0
  93. package/lib/util/fake_event.js +2 -0
  94. package/lib/util/id3_utils.js +300 -0
  95. package/lib/util/mime_utils.js +3 -6
  96. package/lib/util/mp4_box_parsers.js +39 -5
  97. package/lib/util/mp4_parser.js +35 -0
  98. package/lib/util/player_configuration.js +23 -1
  99. package/lib/util/stream_utils.js +5 -3
  100. package/lib/util/ts_parser.js +499 -0
  101. package/maintained-branches.md +2 -2
  102. package/package.json +7 -4
  103. package/roadmap.md +5 -3
  104. package/test/ads/ad_manager_unit.js +182 -29
  105. package/test/cast/cast_utils_unit.js +3 -1
  106. package/test/dash/dash_parser_content_protection_unit.js +1 -0
  107. package/test/dash/dash_parser_live_unit.js +1 -0
  108. package/test/dash/dash_parser_manifest_unit.js +93 -1
  109. package/test/dash/dash_parser_segment_base_unit.js +1 -0
  110. package/test/dash/dash_parser_segment_list_unit.js +1 -0
  111. package/test/dash/dash_parser_segment_template_unit.js +1 -0
  112. package/test/demo/demo_unit.js +2 -1
  113. package/test/hls/hls_live_unit.js +253 -19
  114. package/test/hls/hls_parser_unit.js +631 -12
  115. package/test/media/closed_caption_parser_unit.js +2 -1
  116. package/test/media/drm_engine_integration.js +3 -1
  117. package/test/media/media_source_engine_integration.js +71 -6
  118. package/test/media/media_source_engine_unit.js +10 -5
  119. package/test/media/streaming_engine_integration.js +4 -1
  120. package/test/media/streaming_engine_unit.js +144 -1
  121. package/test/media/transmuxer_integration.js +21 -10
  122. package/test/player_integration.js +224 -82
  123. package/test/player_unit.js +5 -2
  124. package/test/polyfill/media_capabilities_unit.js +21 -23
  125. package/test/polyfill/patchedmediakeys_apple_unit.js +130 -0
  126. package/test/test/assets/id3-metadata.aac +0 -0
  127. package/test/test/assets/id3-metadata.ts +0 -0
  128. package/test/test/assets/thumbnails-sprites.vtt +10 -0
  129. package/test/test/assets/thumbnails.vtt +10 -0
  130. package/test/test/util/dash_parser_util.js +2 -0
  131. package/test/test/util/fake_ad.js +21 -0
  132. package/test/test/util/fake_media_source_engine.js +7 -0
  133. package/test/test/util/id3_generator.js +100 -0
  134. package/test/test/util/manifest_generator.js +3 -6
  135. package/test/test/util/simple_fakes.js +4 -0
  136. package/test/test/util/stream_generator.js +38 -0
  137. package/test/test/util/test_scheme.js +43 -14
  138. package/test/text/vtt_text_parser_unit.js +11 -0
  139. package/test/util/id3_utils_unit.js +116 -0
  140. package/test/util/ts_parser_unit.js +77 -0
  141. package/third_party/closure-uri/uri.js +1 -1
  142. package/ui/less/containers.less +7 -0
  143. package/ui/ui.js +43 -4
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "shaka-player",
3
3
  "description": "DASH/EME video player library",
4
- "version": "4.2.5",
4
+ "version": "4.3.1",
5
5
  "homepage": "https://github.com/shaka-project/shaka-player",
6
6
  "author": "Google",
7
7
  "maintainers": [
@@ -28,9 +28,9 @@
28
28
  "eslint-plugin-shaka-rules": "file:./build/eslint-plugin-shaka-rules",
29
29
  "esprima": "^4.0.1",
30
30
  "fontfaceonload": "^1.0.2",
31
- "google-closure-compiler-java": "^20220301.0.0",
32
- "google-closure-deps": "https://gitpkg.now.sh/google/closure-library/closure-deps?d7736da6",
33
- "google-closure-library": "^20220301.0.0",
31
+ "google-closure-compiler-java": "^20221102.0.0",
32
+ "google-closure-deps": "^20221102.0.0",
33
+ "google-closure-library": "^20221102.0.0",
34
34
  "htmlhint": "^1.1.3",
35
35
  "jasmine-ajax": "^4.0.0",
36
36
  "jimp": "^0.16.1",
@@ -46,6 +46,7 @@
46
46
  "karma-sourcemap-loader": "^0.3.8",
47
47
  "karma-spec-reporter": "^0.0.34",
48
48
  "karma-webdriver-launcher": "^1.0.8",
49
+ "lcevc_dil.js": "^1.1.20",
49
50
  "less": "https://gitpkg.now.sh/joeyparrish/less.js/packages/less?28c63a43",
50
51
  "less-plugin-clean-css": "github:austingardner/less-plugin-clean-css#4e9e77bf",
51
52
  "material-design-lite": "^1.3.0",
@@ -71,6 +72,8 @@
71
72
  "eme-encryption-scheme-polyfill/index.js",
72
73
  "es6-promise-polyfill/promise.min.js",
73
74
  "google-closure-library/closure/goog/base.js",
75
+ "lcevc_dil.js/dist/lcevc_dil.min.js",
76
+ "lcevc_dil.js/dist/liblcevc_dpi.wasm",
74
77
  "less/dist/less.js",
75
78
  "material-design-lite/dist/material.indigo-blue.min.css",
76
79
  "material-design-lite/dist/material.min.js",
package/roadmap.md CHANGED
@@ -23,13 +23,15 @@ Candidate features for future release cycles:
23
23
  https://github.com/shaka-project/shaka-player/issues/879
24
24
  - Smaller, more modular binary
25
25
 
26
- v4.3 - 2022 Q4 / 2023 Q1
26
+ =====
27
+
28
+ v4.3 - 2022 Q4
27
29
  - Support ID3 tags in mp4
28
30
  https://github.com/shaka-project/shaka-player/issues/3351
29
31
  - Lazy-load HLS playlists on adaptation
30
32
  https://github.com/shaka-project/shaka-player/issues/1936
31
-
32
- =====
33
+ - HLS key rotation
34
+ https://github.com/shaka-project/shaka-player/issues/741
33
35
 
34
36
  v4.2 - 2022 Q3
35
37
  - Automatic ABR quality restrictions based on size
@@ -25,45 +25,158 @@ describe('Ad manager', () => {
25
25
  /** @type {!HTMLElement} */ (document.createElement('div'));
26
26
  });
27
27
 
28
- it('doesn\'t init CS if CS IMA is missing', () => {
29
- const error = createError(
30
- shaka.util.Error.Severity.CRITICAL,
31
- shaka.util.Error.Code.CS_IMA_SDK_MISSING);
28
+ describe('client side', () => {
29
+ it('doesn\'t init if CS IMA is missing', () => {
30
+ const error = createError(
31
+ shaka.util.Error.Severity.CRITICAL,
32
+ shaka.util.Error.Code.CS_IMA_SDK_MISSING);
32
33
 
33
- expect(() => adManager.initClientSide(
34
- adContainer, mockVideo)).toThrow(error);
35
- });
34
+ expect(() => adManager.initClientSide(
35
+ adContainer, mockVideo)).toThrow(error);
36
+ });
36
37
 
37
- it('doesn\'t init SS if SS IMA is missing', () => {
38
- const error = createError(
39
- shaka.util.Error.Severity.CRITICAL,
40
- shaka.util.Error.Code.SS_IMA_SDK_MISSING);
38
+ it('doesn\'t request ads until CS is initialized', () => {
39
+ setupFakeIMA();
40
+ const error = createError(
41
+ shaka.util.Error.Severity.RECOVERABLE,
42
+ shaka.util.Error.Code.CS_AD_MANAGER_NOT_INITIALIZED);
41
43
 
42
- expect(() => adManager.initServerSide(
43
- adContainer, mockVideo)).toThrow(error);
44
- });
44
+ const request = new google.ima.AdsRequest();
45
+ request.adTagUrl = 'fakeTag';
46
+
47
+ expect(() => adManager.requestClientSideAds(request)).toThrow(error);
48
+ });
49
+
50
+ it('doesn\'t request ads if CS events return no ad', () => {
51
+ setupFakeIMA();
52
+
53
+ const request = new google.ima.AdsRequest();
54
+ request.adTagUrl = 'fakeTag';
55
+
56
+ /** @type {google.ima.AdsLoader} */
57
+ let mockAdsLoaderInstance;
58
+ let numAdsRequested = 0;
59
+ /** @type {google.ima.AdsManager} */
60
+ let mockAdsManagerInstance;
61
+ /** @type {Event} */
62
+ let loadEvent;
63
+ /** @type {Event} */
64
+ let startedEventA;
65
+ /** @type {Event} */
66
+ let startedEventB;
67
+
68
+ /** @suppress {invalidCasts} */
69
+ function makeMocks() {
70
+ const mockAdsLoader = class extends shaka.util.FakeEventTarget {
71
+ constructor(container) {
72
+ super();
73
+ mockAdsLoaderInstance = /** @type {!google.ima.AdsLoader} */ (this);
74
+ }
75
+
76
+ getSettings() {
77
+ return {
78
+ setPlayerType: (type) => {},
79
+ setPlayerVersion: (version) => {},
80
+ };
81
+ }
45
82
 
46
- it('doesn\'t request CS ads until CS is initialized', () => {
47
- setupFakeIMA();
48
- const error = createError(
49
- shaka.util.Error.Severity.RECOVERABLE,
50
- shaka.util.Error.Code.CS_AD_MANAGER_NOT_INITIALIZED);
83
+ requestAds(imaRequest) {
84
+ numAdsRequested += 1;
85
+ }
86
+ };
87
+ window['google'].ima.AdsLoader = mockAdsLoader;
51
88
 
52
- const request = new google.ima.AdsRequest();
53
- request.adTagUrl = 'fakeTag';
89
+ loadEvent = /** @type {!google.ima.AdsManagerLoadedEvent} */ (
90
+ new shaka.util.FakeEvent(
91
+ google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED));
92
+ loadEvent.getAdsManager = () => {
93
+ const MockAdManager = class extends shaka.util.FakeEventTarget {
94
+ constructor() {
95
+ super();
96
+ mockAdsManagerInstance =
97
+ /** @type {!google.ima.AdsManager} */ (this);
98
+ }
54
99
 
55
- expect(() => adManager.requestClientSideAds(request)).toThrow(error);
100
+ getCuePoints() {
101
+ return [];
102
+ }
103
+
104
+ getVolume() {
105
+ return 0;
106
+ }
107
+ };
108
+ return new MockAdManager();
109
+ };
110
+ startedEventA = /** @type {!google.ima.AdEvent} */ (
111
+ new shaka.util.FakeEvent(google.ima.AdEvent.Type.STARTED));
112
+ startedEventA.getAd = () => {
113
+ return null;
114
+ };
115
+ startedEventB = /** @type {!google.ima.AdEvent} */ (
116
+ new shaka.util.FakeEvent(google.ima.AdEvent.Type.STARTED));
117
+ startedEventB.getAd = () => {
118
+ return {
119
+ isLinear: () => true,
120
+ };
121
+ };
122
+ }
123
+ makeMocks();
124
+
125
+ // Set up event listeners.
126
+ const eventManager = new shaka.util.EventManager();
127
+ let loaded = false;
128
+ let numAdStarted = 0;
129
+ const AdManager = shaka.ads.AdManager;
130
+ eventManager.listen(adManager, AdManager.IMA_AD_MANAGER_LOADED, () => {
131
+ loaded = true;
132
+ });
133
+ eventManager.listen(adManager, AdManager.AD_STARTED, () => {
134
+ numAdStarted += 1;
135
+ });
136
+
137
+ // Set up the ad manager.
138
+ adManager.initClientSide(adContainer, mockVideo);
139
+ goog.asserts.assert(loadEvent != null, 'loadEvent exists');
140
+ mockAdsLoaderInstance.dispatchEvent(/** @type {!Event} */ (loadEvent));
141
+ expect(loaded).toBe(true);
142
+
143
+ // Request an ad, but create an event with no ad.
144
+ adManager.requestClientSideAds(request);
145
+ expect(numAdsRequested).toBe(1);
146
+ mockAdsManagerInstance.dispatchEvent(/** @type {!Event} */ (
147
+ startedEventA));
148
+ expect(numAdStarted).toBe(0);
149
+
150
+ // Request another ad. This time, the IMA event has an ad, so the ad
151
+ // manager should fire a started event.
152
+ adManager.requestClientSideAds(request);
153
+ expect(numAdsRequested).toBe(2);
154
+ mockAdsManagerInstance.dispatchEvent(/** @type {!Event} */ (
155
+ startedEventB));
156
+ expect(numAdStarted).toBe(1);
157
+ });
56
158
  });
57
159
 
58
- it('doesn\'t request SS streams until SS is initialized', () => {
59
- setupFakeIMA();
60
- const error = createError(
61
- shaka.util.Error.Severity.RECOVERABLE,
62
- shaka.util.Error.Code.SS_AD_MANAGER_NOT_INITIALIZED);
160
+ describe('server side', () => {
161
+ it('doesn\'t init if SS IMA is missing', () => {
162
+ const error = createError(
163
+ shaka.util.Error.Severity.CRITICAL,
164
+ shaka.util.Error.Code.SS_IMA_SDK_MISSING);
165
+
166
+ expect(() => adManager.initServerSide(
167
+ adContainer, mockVideo)).toThrow(error);
168
+ });
169
+
170
+ it('doesn\'t request streams until SS is initialized', () => {
171
+ setupFakeIMA();
172
+ const error = createError(
173
+ shaka.util.Error.Severity.RECOVERABLE,
174
+ shaka.util.Error.Code.SS_AD_MANAGER_NOT_INITIALIZED);
63
175
 
64
- const request = new google.ima.dai.api.StreamRequest();
176
+ const request = new google.ima.dai.api.StreamRequest();
65
177
 
66
- expect(() => adManager.requestServerSideStream(request)).toThrow(error);
178
+ expect(() => adManager.requestServerSideStream(request)).toThrow(error);
179
+ });
67
180
  });
68
181
 
69
182
  /**
@@ -86,5 +199,45 @@ describe('Ad manager', () => {
86
199
  window['google'].ima.AdsRequest = class {};
87
200
  window['google'].ima.dai.api = {};
88
201
  window['google'].ima.dai.api.StreamRequest = class {};
202
+ window['google'].ima.settings = {};
203
+ window['google'].ima.settings.setLocale = (locale) => {};
204
+ window['google'].ima.AdsManagerLoadedEvent = {};
205
+ window['google'].ima.AdsManagerLoadedEvent.Type = {
206
+ ADS_MANAGER_LOADED: 'ADS_MANAGER_LOADED',
207
+ };
208
+ window['google'].ima.AdErrorEvent = {};
209
+ window['google'].ima.AdErrorEvent.Type = {
210
+ AD_ERROR: 'AD_ERROR',
211
+ };
212
+ window['google'].ima.AdEvent = {};
213
+ window['google'].ima.AdEvent.Type = {
214
+ CONTENT_PAUSE_REQUESTED: 'CONTENT_PAUSE_REQUESTED',
215
+ STARTED: 'STARTED',
216
+ FIRST_QUARTILE: 'FIRST_QUARTILE',
217
+ MIDPOINT: 'MIDPOINT',
218
+ THIRD_QUARTILE: 'THIRD_QUARTILE',
219
+ COMPLETE: 'COMPLETE',
220
+ CONTENT_RESUME_REQUESTED: 'CONTENT_RESUME_REQUESTED',
221
+ ALL_ADS_COMPLETED: 'ALL_ADS_COMPLETED',
222
+ SKIPPED: 'SKIPPED',
223
+ VOLUME_CHANGED: 'VOLUME_CHANGED',
224
+ VOLUME_MUTED: 'VOLUME_MUTED',
225
+ PAUSED: 'PAUSED',
226
+ RESUMED: 'RESUMED',
227
+ SKIPPABLE_STATE_CHANGED: 'SKIPPABLE_STATE_CHANGED',
228
+ CLICK: 'CLICK',
229
+ AD_PROGRESS: 'AD_PROGRESS',
230
+ AD_BUFFERING: 'AD_BUFFERING',
231
+ IMPRESSION: 'IMPRESSION',
232
+ DURATION_CHANGE: 'DURATION_CHANGE',
233
+ USER_CLOSE: 'USER_CLOSE',
234
+ LOADED: 'LOADED',
235
+ LINEAR_CHANGED: 'LINEAR_CHANGED',
236
+ AD_METADATA: 'AD_METADATA',
237
+ LOG: 'LOG',
238
+ AD_BREAK_READY: 'AD_BREAK_READY',
239
+ INTERACTION: 'INTERACTION',
240
+ };
241
+ window['google'].ima.AdDisplayContainer = class { initialize() {} };
89
242
  }
90
243
  });
@@ -206,8 +206,10 @@ describe('CastUtils', () => {
206
206
 
207
207
  mediaSourceEngine = new shaka.media.MediaSourceEngine(
208
208
  video,
209
- new shaka.test.FakeClosedCaptionParser(),
210
209
  new shaka.test.FakeTextDisplayer());
210
+ const config =
211
+ shaka.util.PlayerConfiguration.createDefault().mediaSource;
212
+ mediaSourceEngine.configure(config);
211
213
 
212
214
  const ContentType = shaka.util.ManifestParserUtils.ContentType;
213
215
  const initObject = new Map();
@@ -44,6 +44,7 @@ describe('DashParser ContentProtection', () => {
44
44
  isAutoLowLatencyMode: () => false,
45
45
  enableLowLatencyMode: () => {},
46
46
  updateDuration: () => {},
47
+ newDrmInfo: (stream) => {},
47
48
  };
48
49
 
49
50
  const actual = await dashParser.start(
@@ -37,6 +37,7 @@ describe('DashParser Live', () => {
37
37
  isAutoLowLatencyMode: () => false,
38
38
  enableLowLatencyMode: () => {},
39
39
  updateDuration: () => {},
40
+ newDrmInfo: (stream) => {},
40
41
  };
41
42
  });
42
43
 
@@ -53,6 +53,7 @@ describe('DashParser Manifest', () => {
53
53
  isAutoLowLatencyMode: () => false,
54
54
  enableLowLatencyMode: () => {},
55
55
  updateDuration: () => {},
56
+ newDrmInfo: (stream) => {},
56
57
  };
57
58
  });
58
59
 
@@ -119,7 +120,97 @@ describe('DashParser Manifest', () => {
119
120
  });
120
121
  }
121
122
 
122
- describe('parses and inherits attributes', () => {
123
+ describe('parses and inherits attributes with sequenceMode', () => {
124
+ beforeEach(() => {
125
+ const config = shaka.util.PlayerConfiguration.createDefault().manifest;
126
+ config.dash.sequenceMode = true;
127
+ parser.configure(config);
128
+ });
129
+
130
+ makeTestsForEach(
131
+ [
132
+ '<MPD minBufferTime="PT75S">',
133
+ ' <Period id="1" duration="PT30S">',
134
+ ' <BaseURL>http://example.com</BaseURL>',
135
+ ],
136
+ [
137
+ ' <AdaptationSet contentType="video" mimeType="video/mp4"',
138
+ ' codecs="avc1.4d401f" frameRate="1000000/42000">',
139
+ ' <Representation bandwidth="100" width="768" height="576" />',
140
+ ' <Representation bandwidth="50" width="576" height="432" />',
141
+ ' </AdaptationSet>',
142
+ ' <AdaptationSet mimeType="text/vtt"',
143
+ ' lang="es" label="spanish">',
144
+ ' <Role value="caption" />',
145
+ ' <Role value="main" />',
146
+ ' <Representation bandwidth="100" />',
147
+ ' </AdaptationSet>',
148
+ ' <AdaptationSet mimeType="audio/mp4" lang="en" ',
149
+ ' codecs="mp4a.40.29">',
150
+ ' <Role value="main" />',
151
+ ' <Representation bandwidth="100" />',
152
+ ' </AdaptationSet>',
153
+ ' </Period>',
154
+ '</MPD>',
155
+ ],
156
+ shaka.test.ManifestGenerator.generate((manifest) => {
157
+ manifest.sequenceMode = true;
158
+ manifest.anyTimeline();
159
+ manifest.minBufferTime = 75;
160
+ manifest.addPartialVariant((variant) => {
161
+ variant.language = 'en';
162
+ variant.bandwidth = 200;
163
+ variant.primary = true;
164
+ variant.addPartialStream(ContentType.VIDEO, (stream) => {
165
+ stream.bandwidth = 100;
166
+ stream.frameRate = 1000000 / 42000;
167
+ stream.size(768, 576);
168
+ stream.mime('video/mp4', 'avc1.4d401f');
169
+ });
170
+ variant.addPartialStream(ContentType.AUDIO, (stream) => {
171
+ stream.bandwidth = 100;
172
+ stream.primary = true;
173
+ stream.roles = ['main'];
174
+ stream.mime('audio/mp4', 'mp4a.40.29');
175
+ });
176
+ });
177
+ manifest.addPartialVariant((variant) => {
178
+ variant.language = 'en';
179
+ variant.bandwidth = 150;
180
+ variant.primary = true;
181
+ variant.addPartialStream(ContentType.VIDEO, (stream) => {
182
+ stream.bandwidth = 50;
183
+ stream.frameRate = 1000000 / 42000;
184
+ stream.size(576, 432);
185
+ stream.mime('video/mp4', 'avc1.4d401f');
186
+ });
187
+ variant.addPartialStream(ContentType.AUDIO, (stream) => {
188
+ stream.bandwidth = 100;
189
+ stream.primary = true;
190
+ stream.roles = ['main'];
191
+ stream.mime('audio/mp4', 'mp4a.40.29');
192
+ });
193
+ });
194
+ manifest.addPartialTextStream((stream) => {
195
+ stream.language = 'es';
196
+ stream.label = 'spanish';
197
+ stream.primary = true;
198
+ stream.mimeType = 'text/vtt';
199
+ stream.bandwidth = 100;
200
+ stream.kind = 'caption';
201
+ stream.roles = ['caption', 'main'];
202
+ });
203
+ }));
204
+ });
205
+
206
+ describe('parses and inherits attributes without sequenceMode', () => {
207
+ beforeEach(() => {
208
+ const config = shaka.util.PlayerConfiguration.createDefault().manifest;
209
+ config.dash.sequenceMode = false;
210
+ parser.configure(config);
211
+ });
212
+
213
+
123
214
  makeTestsForEach(
124
215
  [
125
216
  '<MPD minBufferTime="PT75S">',
@@ -147,6 +238,7 @@ describe('DashParser Manifest', () => {
147
238
  '</MPD>',
148
239
  ],
149
240
  shaka.test.ManifestGenerator.generate((manifest) => {
241
+ manifest.sequenceMode = false;
150
242
  manifest.anyTimeline();
151
243
  manifest.minBufferTime = 75;
152
244
  manifest.addPartialVariant((variant) => {
@@ -39,6 +39,7 @@ describe('DashParser SegmentBase', () => {
39
39
  isAutoLowLatencyMode: () => false,
40
40
  enableLowLatencyMode: () => {},
41
41
  updateDuration: () => {},
42
+ newDrmInfo: (stream) => {},
42
43
  };
43
44
  });
44
45
 
@@ -349,6 +349,7 @@ describe('DashParser SegmentList', () => {
349
349
  isAutoLowLatencyMode: () => false,
350
350
  enableLowLatencyMode: () => {},
351
351
  updateDuration: () => {},
352
+ newDrmInfo: (stream) => {},
352
353
  };
353
354
  const manifest = await dashParser.start('dummy://foo', playerInterface);
354
355
  const stream = manifest.variants[0].video;
@@ -48,6 +48,7 @@ describe('DashParser SegmentTemplate', () => {
48
48
  isAutoLowLatencyMode: () => false,
49
49
  enableLowLatencyMode: () => {},
50
50
  updateDuration: () => {},
51
+ newDrmInfo: (stream) => {},
51
52
  };
52
53
  });
53
54
 
@@ -95,7 +95,8 @@ describe('Demo', () => {
95
95
  .add('playRangeEnd')
96
96
  .add('manifest.dash.keySystemsByURI')
97
97
  .add('manifest.hls.mediaPlaylistFullMimeType')
98
- .add('drm.keySystemsMapping');
98
+ .add('drm.keySystemsMapping')
99
+ .add('streaming.parsePrftBox');
99
100
 
100
101
  /**
101
102
  * @param {!Object} section