shaka-player 3.1.3 → 3.2.2

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 (182) hide show
  1. package/AUTHORS +3 -0
  2. package/CHANGELOG.md +175 -3
  3. package/CONTRIBUTORS +3 -0
  4. package/README.md +4 -4
  5. package/build/generateExterns.js +1 -1
  6. package/build/types/polyfill +1 -0
  7. package/demo/common/asset.js +9 -7
  8. package/demo/common/assets.js +11 -2
  9. package/demo/common/message_ids.js +2 -1
  10. package/demo/config.js +5 -2
  11. package/demo/index.html +1 -1
  12. package/demo/locales/en.json +2 -1
  13. package/demo/locales/source.json +8 -4
  14. package/demo/main.js +2 -1
  15. package/dist/controls.css +2 -2
  16. package/dist/controls.css.map +1 -1
  17. package/dist/demo.compiled.debug.js +15 -15
  18. package/dist/demo.compiled.debug.map +2 -2
  19. package/dist/demo.compiled.js +15 -15
  20. package/dist/demo.compiled.map +2 -2
  21. package/dist/deps.js +22 -21
  22. package/dist/locales.js +36 -36
  23. package/dist/receiver.compiled.debug.js +9 -9
  24. package/dist/receiver.compiled.debug.map +2 -2
  25. package/dist/receiver.compiled.js +9 -9
  26. package/dist/receiver.compiled.map +2 -2
  27. package/dist/shaka-player.compiled.d.ts +58 -10
  28. package/dist/shaka-player.compiled.debug.d.ts +58 -10
  29. package/dist/shaka-player.compiled.debug.externs.js +777 -717
  30. package/dist/shaka-player.compiled.debug.js +639 -607
  31. package/dist/shaka-player.compiled.debug.map +4 -4
  32. package/dist/shaka-player.compiled.externs.js +777 -717
  33. package/dist/shaka-player.compiled.js +826 -819
  34. package/dist/shaka-player.compiled.map +4 -4
  35. package/dist/shaka-player.ui.d.ts +58 -10
  36. package/dist/shaka-player.ui.debug.d.ts +58 -10
  37. package/dist/shaka-player.ui.debug.externs.js +529 -469
  38. package/dist/shaka-player.ui.debug.js +676 -645
  39. package/dist/shaka-player.ui.debug.map +4 -4
  40. package/dist/shaka-player.ui.externs.js +529 -469
  41. package/dist/shaka-player.ui.js +963 -955
  42. package/dist/shaka-player.ui.map +4 -4
  43. package/docs/tutorials/fairplay.md +1 -1
  44. package/docs/tutorials/ui.md +5 -5
  45. package/externs/aria.js +6 -0
  46. package/externs/shaka/ads.js +24 -1
  47. package/externs/shaka/manifest.js +6 -1
  48. package/externs/shaka/offline.js +5 -0
  49. package/externs/shaka/player.js +53 -9
  50. package/externs/shaka/text.js +10 -10
  51. package/externs/texttrack.js +3 -0
  52. package/karma.conf.js +1 -0
  53. package/lib/ads/ad_manager.js +16 -15
  54. package/lib/ads/client_side_ad_manager.js +52 -88
  55. package/lib/ads/server_side_ad_manager.js +26 -12
  56. package/lib/cast/cast_proxy.js +11 -2
  57. package/lib/cast/cast_receiver.js +2 -1
  58. package/lib/cast/cast_sender.js +2 -2
  59. package/lib/cast/cast_utils.js +6 -1
  60. package/lib/cea/cea608_data_channel.js +56 -56
  61. package/lib/cea/cea608_memory.js +33 -33
  62. package/lib/cea/cea708_service.js +43 -43
  63. package/lib/cea/cea708_window.js +38 -38
  64. package/lib/cea/cea_decoder.js +13 -14
  65. package/lib/cea/cea_utils.js +23 -23
  66. package/lib/cea/dtvcc_packet_builder.js +7 -7
  67. package/lib/cea/i_caption_decoder.js +2 -3
  68. package/lib/cea/i_cea_parser.js +2 -2
  69. package/lib/cea/mp4_cea_parser.js +6 -6
  70. package/lib/dash/dash_parser.js +98 -2
  71. package/lib/dash/segment_list.js +1 -1
  72. package/lib/dash/segment_template.js +1 -1
  73. package/lib/hls/hls_parser.js +159 -29
  74. package/lib/media/closed_caption_parser.js +1 -2
  75. package/lib/media/drm_engine.js +169 -192
  76. package/lib/media/gap_jumping_controller.js +4 -2
  77. package/lib/media/media_source_engine.js +1 -2
  78. package/lib/media/segment_index.js +3 -1
  79. package/lib/media/segment_reference.js +19 -2
  80. package/lib/media/streaming_engine.js +8 -7
  81. package/lib/net/networking_engine.js +3 -1
  82. package/lib/offline/download_manager.js +1 -2
  83. package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
  84. package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
  85. package/lib/offline/manifest_converter.js +3 -1
  86. package/lib/offline/storage.js +12 -14
  87. package/lib/player.js +437 -167
  88. package/lib/polyfill/aria.js +82 -0
  89. package/lib/polyfill/media_capabilities.js +7 -1
  90. package/lib/polyfill/mediasource.js +6 -0
  91. package/lib/polyfill/orientation.js +1 -1
  92. package/lib/polyfill/patchedmediakeys_apple.js +4 -4
  93. package/lib/polyfill/patchedmediakeys_ms.js +4 -4
  94. package/lib/polyfill/patchedmediakeys_webkit.js +4 -4
  95. package/lib/routing/walker.js +2 -3
  96. package/lib/text/mp4_ttml_parser.js +3 -0
  97. package/lib/text/srt_text_parser.js +4 -4
  98. package/lib/text/text_engine.js +16 -4
  99. package/lib/text/ttml_text_parser.js +5 -0
  100. package/lib/text/ui_text_displayer.js +85 -37
  101. package/lib/text/vtt_text_parser.js +2 -2
  102. package/lib/text/web_vtt_generator.js +55 -12
  103. package/lib/util/error.js +6 -0
  104. package/lib/util/fake_event.js +53 -7
  105. package/lib/util/manifest_parser_utils.js +1 -0
  106. package/lib/util/mp4_box_parsers.js +20 -20
  107. package/lib/util/multi_map.js +8 -0
  108. package/lib/util/periods.js +4 -1
  109. package/lib/util/platform.js +13 -1
  110. package/lib/util/player_configuration.js +13 -1
  111. package/lib/util/stream_utils.js +153 -85
  112. package/lib/util/xml_utils.js +31 -12
  113. package/package.json +1 -1
  114. package/roadmap.md +24 -22
  115. package/shaka-player.uncompiled.js +1 -0
  116. package/test/cast/cast_proxy_unit.js +12 -6
  117. package/test/cast/cast_utils_unit.js +2 -1
  118. package/test/cea/cea608_memory_unit.js +1 -1
  119. package/test/cea/cea708_service_unit.js +8 -8
  120. package/test/cea/cea708_window_unit.js +6 -6
  121. package/test/cea/cea_decoder_unit.js +1 -1
  122. package/test/cea/dtvcc_packet_builder_unit.js +2 -2
  123. package/test/dash/dash_parser_manifest_unit.js +230 -2
  124. package/test/hls/hls_parser_unit.js +255 -1
  125. package/test/media/closed_caption_parser_unit.js +6 -1
  126. package/test/media/drm_engine_integration.js +86 -12
  127. package/test/media/drm_engine_unit.js +353 -450
  128. package/test/offline/manifest_convert_unit.js +2 -0
  129. package/test/offline/storage_integration.js +9 -19
  130. package/test/player_integration.js +90 -0
  131. package/test/player_src_equals_integration.js +52 -0
  132. package/test/player_unit.js +11 -33
  133. package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
  134. package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
  135. package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
  136. package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
  137. package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
  138. package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
  139. package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
  140. package/test/test/assets/3675/dash_0.mpd +30 -0
  141. package/test/test/assets/3675/dash_1.mpd +30 -0
  142. package/test/test/assets/3675/dash_2.mpd +30 -0
  143. package/test/test/assets/3675/dash_3.mpd +30 -0
  144. package/test/test/assets/3675/dash_4.mpd +30 -0
  145. package/test/test/assets/3675/dash_5.mpd +26 -0
  146. package/test/test/assets/3675/init-stream0.m4s +0 -0
  147. package/test/test/assets/chapters.srt +11 -0
  148. package/test/test/assets/chapters.vtt +10 -0
  149. package/test/test/util/cea_utils.js +12 -12
  150. package/test/test/util/fake_ad_manager.js +8 -1
  151. package/test/test/util/manifest_generator.js +2 -0
  152. package/test/test/util/manifest_parser_util.js +3 -1
  153. package/test/text/ttml_text_parser_unit.js +9 -0
  154. package/test/text/ui_text_displayer_unit.js +29 -17
  155. package/test/text/web_vtt_generator_unit.js +81 -7
  156. package/test/ui/localization_unit.js +15 -14
  157. package/test/ui/text_displayer_layout_unit.js +13 -1
  158. package/test/util/stream_utils_unit.js +153 -10
  159. package/ui/airplay_button.js +1 -1
  160. package/ui/audio_language_selection.js +2 -5
  161. package/ui/cast_button.js +6 -9
  162. package/ui/constants.js +0 -3
  163. package/ui/controls.js +4 -6
  164. package/ui/fast_forward_button.js +2 -3
  165. package/ui/fullscreen_button.js +1 -3
  166. package/ui/language_utils.js +1 -1
  167. package/ui/less/containers.less +3 -7
  168. package/ui/locales/ru.json +6 -6
  169. package/ui/localization.js +28 -51
  170. package/ui/loop_button.js +1 -3
  171. package/ui/mute_button.js +1 -3
  172. package/ui/overflow_menu.js +2 -3
  173. package/ui/pip_button.js +7 -10
  174. package/ui/playback_rate_selection.js +3 -6
  175. package/ui/presentation_time.js +1 -3
  176. package/ui/resolution_selection.js +4 -7
  177. package/ui/rewind_button.js +2 -3
  178. package/ui/seek_bar.js +2 -4
  179. package/ui/spacer.js +1 -1
  180. package/ui/text_selection.js +8 -11
  181. package/ui/ui_utils.js +1 -1
  182. package/ui/volume_bar.js +1 -3
@@ -15,10 +15,10 @@ shaka.cea.CeaUtils = class {
15
15
  /**
16
16
  * Emits a closed caption based on the state of the buffer.
17
17
  * @param {!shaka.text.Cue} topLevelCue
18
- * @param {!string} stream
18
+ * @param {string} stream
19
19
  * @param {!Array<!Array<?shaka.cea.CeaUtils.StyledChar>>} memory
20
- * @param {!number} startTime Start time of the cue.
21
- * @param {!number} endTime End time of the cue.
20
+ * @param {number} startTime Start time of the cue.
21
+ * @param {number} endTime End time of the cue.
22
22
  * @return {?shaka.cea.ICaptionDecoder.ClosedCaption}
23
23
  */
24
24
  static getParsedCaption(topLevelCue, stream, memory, startTime, endTime) {
@@ -153,12 +153,12 @@ shaka.cea.CeaUtils = class {
153
153
  }
154
154
 
155
155
  /**
156
- * @param {!number} startTime
157
- * @param {!number} endTime
158
- * @param {!boolean} underline
159
- * @param {!boolean} italics
160
- * @param {!string} txtColor
161
- * @param {!string} bgColor
156
+ * @param {number} startTime
157
+ * @param {number} endTime
158
+ * @param {boolean} underline
159
+ * @param {boolean} italics
160
+ * @param {string} txtColor
161
+ * @param {string} bgColor
162
162
  * @return {!shaka.text.Cue}
163
163
  */
164
164
  static createStyledCue(startTime, endTime, underline,
@@ -176,8 +176,8 @@ shaka.cea.CeaUtils = class {
176
176
  }
177
177
 
178
178
  /**
179
- * @param {!number} startTime
180
- * @param {!number} endTime
179
+ * @param {number} startTime
180
+ * @param {number} endTime
181
181
  * @return {!shaka.text.Cue}
182
182
  */
183
183
  static createLineBreakCue(startTime, endTime) {
@@ -198,61 +198,61 @@ shaka.cea.CeaUtils.StyledChar = class {
198
198
  */
199
199
  constructor(character, underline, italics, backgroundColor, textColor) {
200
200
  /**
201
- * @private {!string}
201
+ * @private {string}
202
202
  */
203
203
  this.character_ = character;
204
204
 
205
205
  /**
206
- * @private {!boolean}
206
+ * @private {boolean}
207
207
  */
208
208
  this.underline_ = underline;
209
209
 
210
210
  /**
211
- * @private {!boolean}
211
+ * @private {boolean}
212
212
  */
213
213
  this.italics_ = italics;
214
214
 
215
215
  /**
216
- * @private {!string}
216
+ * @private {string}
217
217
  */
218
218
  this.backgroundColor_ = backgroundColor;
219
219
 
220
220
  /**
221
- * @private {!string}
221
+ * @private {string}
222
222
  */
223
223
  this.textColor_ = textColor;
224
224
  }
225
225
 
226
226
  /**
227
- * @return {!string}
227
+ * @return {string}
228
228
  */
229
229
  getChar() {
230
230
  return this.character_;
231
231
  }
232
232
 
233
233
  /**
234
- * @return {!boolean}
234
+ * @return {boolean}
235
235
  */
236
236
  isUnderlined() {
237
237
  return this.underline_;
238
238
  }
239
239
 
240
240
  /**
241
- * @return {!boolean}
241
+ * @return {boolean}
242
242
  */
243
243
  isItalicized() {
244
244
  return this.italics_;
245
245
  }
246
246
 
247
247
  /**
248
- * @return {!string}
248
+ * @return {string}
249
249
  */
250
250
  getBackgroundColor() {
251
251
  return this.backgroundColor_;
252
252
  }
253
253
 
254
254
  /**
255
- * @return {!string}
255
+ * @return {string}
256
256
  */
257
257
  getTextColor() {
258
258
  return this.textColor_;
@@ -261,12 +261,12 @@ shaka.cea.CeaUtils.StyledChar = class {
261
261
 
262
262
  /**
263
263
  * Default background color for text.
264
- * @const {!string}
264
+ * @const {string}
265
265
  */
266
266
  shaka.cea.CeaUtils.DEFAULT_BG_COLOR = 'black';
267
267
 
268
268
  /**
269
269
  * Default text color.
270
- * @const {!string}
270
+ * @const {string}
271
271
  */
272
272
  shaka.cea.CeaUtils.DEFAULT_TXT_COLOR = 'white';
@@ -35,7 +35,7 @@ shaka.cea.DtvccPacketBuilder = class {
35
35
 
36
36
  /**
37
37
  * Keeps track of the number of bytes left to add in the current packet.
38
- * @private {!number}
38
+ * @private {number}
39
39
  */
40
40
  this.bytesLeftToAddInCurrentPacket_ = 0;
41
41
  }
@@ -107,7 +107,7 @@ shaka.cea.DtvccPacket = class {
107
107
  constructor(packetData) {
108
108
  /**
109
109
  * Keeps track of the position to read the next byte from in the packet.
110
- * @private {!number}
110
+ * @private {number}
111
111
  */
112
112
  this.pos_ = 0;
113
113
 
@@ -119,14 +119,14 @@ shaka.cea.DtvccPacket = class {
119
119
  }
120
120
 
121
121
  /**
122
- * @return {!boolean}
122
+ * @return {boolean}
123
123
  */
124
124
  hasMoreData() {
125
125
  return this.pos_ < this.packetData_.length;
126
126
  }
127
127
 
128
128
  /**
129
- * @return {!number}
129
+ * @return {number}
130
130
  */
131
131
  getPosition() {
132
132
  return this.pos_;
@@ -149,7 +149,7 @@ shaka.cea.DtvccPacket = class {
149
149
 
150
150
  /**
151
151
  * Skips the provided number of blocks in the buffer.
152
- * @param {!number} numBlocks
152
+ * @param {number} numBlocks
153
153
  * @throws {!shaka.util.Error}
154
154
  */
155
155
  skip(numBlocks) {
@@ -164,11 +164,11 @@ shaka.cea.DtvccPacket = class {
164
164
  };
165
165
 
166
166
  /**
167
- * @const {!number}
167
+ * @const {number}
168
168
  */
169
169
  shaka.cea.DtvccPacketBuilder.DTVCC_PACKET_DATA = 2;
170
170
 
171
171
  /**
172
- * @const {!number}
172
+ * @const {number}
173
173
  */
174
174
  shaka.cea.DtvccPacketBuilder.DTVCC_PACKET_START = 3;
@@ -5,7 +5,6 @@
5
5
  */
6
6
 
7
7
  goog.provide('shaka.cea.ICaptionDecoder');
8
- goog.provide('shaka.cea.ICaptionDecoder.ClosedCaption');
9
8
 
10
9
  goog.require('shaka.text.Cue');
11
10
 
@@ -23,7 +22,7 @@ shaka.cea.ICaptionDecoder = class {
23
22
  * @param {!Uint8Array} userDataSeiMessage
24
23
  * This is a User Data registered by Rec.ITU-T T.35 SEI message.
25
24
  * It is described in sections D.1.6 and D.2.6 of Rec. ITU-T H.264 (06/2019).
26
- * @param {!number} pts PTS when this packet was received, in seconds.
25
+ * @param {number} pts PTS when this packet was received, in seconds.
27
26
  */
28
27
  extract(userDataSeiMessage, pts) {}
29
28
 
@@ -46,7 +45,7 @@ shaka.cea.ICaptionDecoder = class {
46
45
  * Parsed Cue.
47
46
  * @typedef {{
48
47
  * cue: !shaka.text.Cue,
49
- * stream: !string
48
+ * stream: string
50
49
  * }}
51
50
  */
52
51
  shaka.cea.ICaptionDecoder.ClosedCaption;
@@ -39,7 +39,7 @@ shaka.cea.ICeaParser.DEFAULT_TIMESCALE_VALUE = 90000;
39
39
  /**
40
40
  * @typedef {{
41
41
  * packet: !Uint8Array,
42
- * pts: !number
42
+ * pts: number
43
43
  * }}
44
44
  *
45
45
  * @description Parsed Caption Packet.
@@ -47,7 +47,7 @@ shaka.cea.ICeaParser.DEFAULT_TIMESCALE_VALUE = 90000;
47
47
  * Caption packet. More specifically, it contains a "User data
48
48
  * registered by Recommendation ITU-T T.35 SEI message", from section D.1.6
49
49
  * and section D.2.6 of Rec. ITU-T H.264 (06/2019).
50
- * @property {!number} pts
50
+ * @property {number} pts
51
51
  * The presentation timestamp (pts) at which the ITU-T T.35 data shows up.
52
52
  * in seconds.
53
53
  * @exportDoc
@@ -36,13 +36,13 @@ shaka.cea.Mp4CeaParser = class {
36
36
 
37
37
  /**
38
38
  * Default sample duration, as specified by the TREX box.
39
- * @private {!number}
39
+ * @private {number}
40
40
  */
41
41
  this.defaultSampleDuration_ = 0;
42
42
 
43
43
  /**
44
44
  * Default sample size, as specified by the TREX box.
45
- * @private {!number}
45
+ * @private {number}
46
46
  */
47
47
  this.defaultSampleSize_ = 0;
48
48
  }
@@ -195,10 +195,10 @@ shaka.cea.Mp4CeaParser = class {
195
195
  /**
196
196
  * Parse MDAT box.
197
197
  * @param {!shaka.util.DataViewReader} reader
198
- * @param {!number} time
199
- * @param {!number} timescale
200
- * @param {!number} defaultSampleDuration
201
- * @param {!number} defaultSampleSize
198
+ * @param {number} time
199
+ * @param {number} timescale
200
+ * @param {number} defaultSampleDuration
201
+ * @param {number} defaultSampleSize
202
202
  * @param {!Array<shaka.util.ParsedTRUNSample>} sampleData
203
203
  * @param {!Array<!shaka.cea.ICeaParser.CaptionPacket>} captionPackets
204
204
  * @private
@@ -95,6 +95,18 @@ shaka.dash.DashParser = class {
95
95
  /** @private {!shaka.util.OperationManager} */
96
96
  this.operationManager_ = new shaka.util.OperationManager();
97
97
 
98
+ /**
99
+ * Largest period start time seen.
100
+ * @private {?number}
101
+ */
102
+ this.largestPeriodStartTime_ = null;
103
+
104
+ /**
105
+ * Period IDs seen in previous manifest.
106
+ * @private {!Array.<number>}
107
+ */
108
+ this.lastManifestUpdatePeriodIds_ = [];
109
+
98
110
  /**
99
111
  * The minimum of the availabilityTimeOffset values among the adaptation
100
112
  * sets.
@@ -289,6 +301,11 @@ shaka.dash.DashParser = class {
289
301
  const Functional = shaka.util.Functional;
290
302
  const XmlUtils = shaka.util.XmlUtils;
291
303
 
304
+ const manifestPreprocessor = this.config_.dash.manifestPreprocessor;
305
+ if (manifestPreprocessor) {
306
+ manifestPreprocessor(mpd);
307
+ }
308
+
292
309
  // Get any Location elements. This will update the manifest location and
293
310
  // the base URI.
294
311
  /** @type {!Array.<string>} */
@@ -533,6 +550,7 @@ shaka.dash.DashParser = class {
533
550
  for (const {i, item: elem, next} of enumerate(periodNodes)) {
534
551
  const start = /** @type {number} */ (
535
552
  XmlUtils.parseAttr(elem, 'start', XmlUtils.parseDuration, prevEnd));
553
+ const periodId = elem.id;
536
554
  const givenDuration =
537
555
  XmlUtils.parseAttr(elem, 'duration', XmlUtils.parseDuration);
538
556
 
@@ -566,6 +584,42 @@ shaka.dash.DashParser = class {
566
584
  periodDuration = givenDuration;
567
585
  }
568
586
 
587
+ /**
588
+ * This is to improve robustness when the player observes manifest with
589
+ * past periods that are inconsistent to previous ones.
590
+ *
591
+ * This may happen when a CDN or proxy server switches its upstream from
592
+ * one encoder to another redundant encoder.
593
+ *
594
+ * Skip periods that match all of the following criteria:
595
+ * - Start time is earlier than latest period start time ever seen
596
+ * - Period ID is never seen in the previous manifest
597
+ * - Not the last period in the manifest
598
+ *
599
+ * Periods that meet the aforementioned criteria are considered invalid
600
+ * and should be safe to discard.
601
+ */
602
+
603
+ if (this.largestPeriodStartTime_ !== null &&
604
+ periodId !== null && start !== null &&
605
+ start < this.largestPeriodStartTime_ &&
606
+ !this.lastManifestUpdatePeriodIds_.includes(periodId) &&
607
+ i + 1 != periodNodes.length) {
608
+ shaka.log.debug(
609
+ `Skipping Period with ID ${periodId} as its start time is smaller` +
610
+ ' than the largest period start time that has been seen, and ID ' +
611
+ 'is unseen before');
612
+ continue;
613
+ }
614
+
615
+
616
+ // Save maximum period start time if it is the last period
617
+ if (start !== null &&
618
+ (this.largestPeriodStartTime_ === null ||
619
+ start > this.largestPeriodStartTime_)) {
620
+ this.largestPeriodStartTime_ = start;
621
+ }
622
+
569
623
  // Parse child nodes.
570
624
  const info = {
571
625
  start: start,
@@ -597,6 +651,9 @@ shaka.dash.DashParser = class {
597
651
  prevEnd = start + periodDuration;
598
652
  } // end of period parsing loop
599
653
 
654
+ // Replace previous seen periods with the current one.
655
+ this.lastManifestUpdatePeriodIds_ = periods.map((el) => el.id);
656
+
600
657
  if (presentationDuration != null) {
601
658
  if (prevEnd != presentationDuration) {
602
659
  shaka.log.warning(
@@ -808,6 +865,25 @@ shaka.dash.DashParser = class {
808
865
  }
809
866
  }
810
867
 
868
+ // Parallel for HLS VIDEO-RANGE as defined in DASH-IF IOP v4.3 6.2.5.1.
869
+ let videoRange;
870
+ const videoRangeScheme = 'urn:mpeg:mpegB:cicp:TransferCharacteristics';
871
+ const getVideoRangeFromTransferCharacteristicCICP = (cicp) => {
872
+ switch (cicp) {
873
+ case 1:
874
+ case 6:
875
+ case 13:
876
+ case 14:
877
+ case 15:
878
+ return 'SDR';
879
+ case 16:
880
+ return 'PQ';
881
+ case 18:
882
+ return 'HLG';
883
+ }
884
+ return undefined;
885
+ };
886
+
811
887
  const essentialProperties =
812
888
  XmlUtils.findChildren(elem, 'EssentialProperty');
813
889
  // ID of real AdaptationSet if this is a trick mode set:
@@ -817,11 +893,26 @@ shaka.dash.DashParser = class {
817
893
  const schemeId = prop.getAttribute('schemeIdUri');
818
894
  if (schemeId == 'http://dashif.org/guidelines/trickmode') {
819
895
  trickModeFor = prop.getAttribute('value');
896
+ } else if (schemeId == videoRangeScheme) {
897
+ videoRange = getVideoRangeFromTransferCharacteristicCICP(
898
+ parseInt(prop.getAttribute('value'), 10),
899
+ );
820
900
  } else {
821
901
  unrecognizedEssentialProperty = true;
822
902
  }
823
903
  }
824
904
 
905
+ const supplementalProperties =
906
+ XmlUtils.findChildren(elem, 'SupplementalProperty');
907
+ for (const prop of supplementalProperties) {
908
+ const schemeId = prop.getAttribute('schemeIdUri');
909
+ if (schemeId == videoRangeScheme) {
910
+ videoRange = getVideoRangeFromTransferCharacteristicCICP(
911
+ parseInt(prop.getAttribute('value'), 10),
912
+ );
913
+ }
914
+ }
915
+
825
916
  const accessibilities = XmlUtils.findChildren(elem, 'Accessibility');
826
917
  const LanguageUtils = shaka.util.LanguageUtils;
827
918
  const closedCaptions = new Map();
@@ -947,8 +1038,13 @@ shaka.dash.DashParser = class {
947
1038
  // Parse Representations into Streams.
948
1039
  const representations = XmlUtils.findChildren(elem, 'Representation');
949
1040
  const streams = representations.map((representation) => {
950
- return this.parseRepresentation_(context, contentProtection, kind,
951
- language, label, main, roleValues, closedCaptions, representation);
1041
+ const parsedRepresentation = this.parseRepresentation_(context,
1042
+ contentProtection, kind, language, label, main, roleValues,
1043
+ closedCaptions, representation);
1044
+ if (parsedRepresentation) {
1045
+ parsedRepresentation.hdr = parsedRepresentation.hdr || videoRange;
1046
+ }
1047
+ return parsedRepresentation;
952
1048
  }).filter((s) => !!s);
953
1049
 
954
1050
  if (streams.length == 0) {
@@ -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);