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
@@ -92,7 +92,8 @@ shaka.hls.HlsParser = class {
92
92
  * timestamps, offsets, and to handle TS rollover.
93
93
  *
94
94
  * During parsing, used to avoid duplicates in the async methods
95
- * createStreamInfoFromMediaTag_ and createStreamInfoFromVariantTag_.
95
+ * createStreamInfoFromMediaTag_, createStreamInfoFromImageTag_ and
96
+ * createStreamInfoFromVariantTag_.
96
97
  *
97
98
  * During parsing of updates, used by getStartTime_ to determine the start
98
99
  * time of the first segment from existing segment references.
@@ -403,6 +404,9 @@ shaka.hls.HlsParser = class {
403
404
  /** @type {!Array.<!shaka.hls.Tag>} */
404
405
  const variantTags = Utils.filterTagsByName(
405
406
  playlist.tags, 'EXT-X-STREAM-INF');
407
+ /** @type {!Array.<!shaka.hls.Tag>} */
408
+ const imageTags = Utils.filterTagsByName(
409
+ playlist.tags, 'EXT-X-IMAGE-STREAM-INF');
406
410
 
407
411
  this.parseCodecs_(variantTags);
408
412
 
@@ -414,18 +418,16 @@ shaka.hls.HlsParser = class {
414
418
  const uri = tag.getAttributeValue('URI');
415
419
  const language = tag.getAttributeValue('LANGUAGE');
416
420
  const value = tag.getAttributeValue('VALUE');
417
- const data = {
418
- 'id': id,
419
- };
421
+ const data = (new Map()).set('id', id);
420
422
  if (uri) {
421
- data.uri =
422
- shaka.hls.Utils.constructAbsoluteUri(this.masterPlaylistUri_, uri);
423
+ data.set('uri',
424
+ shaka.hls.Utils.constructAbsoluteUri(this.masterPlaylistUri_, uri));
423
425
  }
424
426
  if (language) {
425
- data.language = language;
427
+ data.set('language', language);
426
428
  }
427
429
  if (value) {
428
- data.value = value;
430
+ data.set('value', value);
429
431
  }
430
432
  const event = new shaka.util.FakeEvent('sessiondata', data);
431
433
  if (this.playerInterface_) {
@@ -439,6 +441,7 @@ shaka.hls.HlsParser = class {
439
441
  this.parseClosedCaptions_(mediaTags);
440
442
  const variants = await this.createVariantsForTags_(variantTags);
441
443
  const textStreams = await this.parseTexts_(mediaTags);
444
+ const imageStreams = await this.parseImages_(imageTags);
442
445
 
443
446
  // Make sure that the parser has not been destroyed.
444
447
  if (!this.playerInterface_) {
@@ -529,11 +532,35 @@ shaka.hls.HlsParser = class {
529
532
  }
530
533
  }
531
534
 
535
+ // Now that the content has been fit, notify segments.
536
+ this.segmentsToNotifyByStream_ = [];
537
+ const streamsToNotify = [];
538
+ for (const variant of variants) {
539
+ for (const stream of [variant.video, variant.audio]) {
540
+ if (stream) {
541
+ streamsToNotify.push(stream);
542
+ }
543
+ }
544
+ }
545
+ await Promise.all(streamsToNotify.map(async (stream) => {
546
+ await stream.createSegmentIndex();
547
+ }));
548
+ for (const stream of streamsToNotify) {
549
+ this.segmentsToNotifyByStream_.push(stream.segmentIndex.references);
550
+ }
551
+ this.notifySegments_();
552
+
553
+ // This asserts that the live edge is being calculated from segment times.
554
+ // For VOD and event streams, this check should still pass.
555
+ goog.asserts.assert(
556
+ !this.presentationTimeline_.usingPresentationStartTime(),
557
+ 'We should not be using the presentation start time in HLS!');
558
+
532
559
  this.manifest_ = {
533
560
  presentationTimeline: this.presentationTimeline_,
534
561
  variants,
535
562
  textStreams,
536
- imageStreams: [],
563
+ imageStreams,
537
564
  offlineSessionIds: [],
538
565
  minBufferTime: 0,
539
566
  };
@@ -666,6 +693,34 @@ shaka.hls.HlsParser = class {
666
693
  return textStreams.filter((s) => s);
667
694
  }
668
695
 
696
+ /**
697
+ * @param {!Array.<!shaka.hls.Tag>} imageTags from the playlist.
698
+ * @return {!Promise.<!Array.<!shaka.extern.Stream>>}
699
+ * @private
700
+ */
701
+ async parseImages_(imageTags) {
702
+ // Create image stream for each image tag.
703
+ const imageStreamPromises = imageTags.map(async (tag) => {
704
+ const disableThumbnails = this.config_.disableThumbnails;
705
+ if (disableThumbnails) {
706
+ return null;
707
+ }
708
+ try {
709
+ const streamInfo = await this.createStreamInfoFromImageTag_(tag);
710
+ goog.asserts.assert(
711
+ streamInfo, 'Should always have a streamInfo for image');
712
+ return streamInfo.stream;
713
+ } catch (e) {
714
+ if (this.config_.hls.ignoreImageStreamFailures) {
715
+ return null;
716
+ }
717
+ throw e;
718
+ }
719
+ });
720
+ const imageStreams = await Promise.all(imageStreamPromises);
721
+ return imageStreams.filter((s) => s);
722
+ }
723
+
669
724
  /**
670
725
  * @param {!Array.<!shaka.hls.Tag>} mediaTags Media tags from the playlist.
671
726
  * @private
@@ -1151,7 +1206,7 @@ shaka.hls.HlsParser = class {
1151
1206
  // "AUTOSELECT=YES". A value of "AUTOSELECT=NO" would imply that it may
1152
1207
  // only be selected explicitly by the user, and we don't have a way to
1153
1208
  // represent that in our model.
1154
- const defaultAttrValue = tag.getAttribute('DEFAULT');
1209
+ const defaultAttrValue = tag.getAttributeValue('DEFAULT');
1155
1210
  const primary = defaultAttrValue == 'YES';
1156
1211
 
1157
1212
  const channelsCount = type == 'audio' ? this.getChannelsCount_(tag) : null;
@@ -1184,6 +1239,51 @@ shaka.hls.HlsParser = class {
1184
1239
  return streamInfo;
1185
1240
  }
1186
1241
 
1242
+ /**
1243
+ * Parse EXT-X-MEDIA media tag into a Stream object.
1244
+ *
1245
+ * @param {shaka.hls.Tag} tag
1246
+ * @return {!Promise.<?shaka.hls.HlsParser.StreamInfo>}
1247
+ * @private
1248
+ */
1249
+ async createStreamInfoFromImageTag_(tag) {
1250
+ goog.asserts.assert(tag.name == 'EXT-X-IMAGE-STREAM-INF',
1251
+ 'Should only be called on image tags!');
1252
+ /** @type {string} */
1253
+ const type = shaka.util.ManifestParserUtils.ContentType.IMAGE;
1254
+
1255
+ const verbatimImagePlaylistUri = this.variableSubstitution_(
1256
+ tag.getRequiredAttrValue('URI'), this.globalVariables_);
1257
+ const codecs = tag.getAttributeValue('CODECS', 'jpeg') || '';
1258
+
1259
+ // Check if the stream has already been created as part of another Variant
1260
+ // and return it if it has.
1261
+ if (this.uriToStreamInfosMap_.has(verbatimImagePlaylistUri)) {
1262
+ return this.uriToStreamInfosMap_.get(verbatimImagePlaylistUri);
1263
+ }
1264
+
1265
+ const language = this.getLanguage_(tag);
1266
+ const name = tag.getAttributeValue('NAME');
1267
+
1268
+ const characteristics = tag.getAttributeValue('CHARACTERISTICS');
1269
+
1270
+ const streamInfo = await this.createStreamInfo_(
1271
+ verbatimImagePlaylistUri, codecs, type, language, /* primary= */ false,
1272
+ name, /* channelsCount= */ null, /* closedCaptions= */ null,
1273
+ characteristics, /* forced= */ false, /* spatialAudio= */ false);
1274
+ if (streamInfo == null) {
1275
+ return null;
1276
+ }
1277
+
1278
+ // TODO: This check is necessary because of the possibility of multiple
1279
+ // calls to createStreamInfoFromImageTag_ before either has resolved.
1280
+ if (this.uriToStreamInfosMap_.has(verbatimImagePlaylistUri)) {
1281
+ return this.uriToStreamInfosMap_.get(verbatimImagePlaylistUri);
1282
+ }
1283
+ this.uriToStreamInfosMap_.set(verbatimImagePlaylistUri, streamInfo);
1284
+ return streamInfo;
1285
+ }
1286
+
1187
1287
  /**
1188
1288
  * Parse an EXT-X-STREAM-INF media tag into a Stream object.
1189
1289
  *
@@ -1256,7 +1356,8 @@ shaka.hls.HlsParser = class {
1256
1356
  response.data, absoluteMediaPlaylistUri);
1257
1357
 
1258
1358
  if (playlist.type != shaka.hls.PlaylistType.MEDIA) {
1259
- // EXT-X-MEDIA tags should point to media playlists.
1359
+ // EXT-X-MEDIA and EXT-X-IMAGE-STREAM-INF tags should point to media
1360
+ // playlists.
1260
1361
  throw new shaka.util.Error(
1261
1362
  shaka.util.Error.Severity.CRITICAL,
1262
1363
  shaka.util.Error.Category.MANIFEST,
@@ -1538,12 +1639,6 @@ shaka.hls.HlsParser = class {
1538
1639
  }
1539
1640
 
1540
1641
  this.notifySegments_();
1541
-
1542
- // This asserts that the live edge is being calculated from segment times.
1543
- // For VOD and event streams, this check should still pass.
1544
- goog.asserts.assert(
1545
- !this.presentationTimeline_.usingPresentationStartTime(),
1546
- 'We should not be using the presentation start time in HLS!');
1547
1642
  }
1548
1643
 
1549
1644
  /**
@@ -1619,11 +1714,12 @@ shaka.hls.HlsParser = class {
1619
1714
  * @param {!Map.<string, string>} variables
1620
1715
  * @param {string} absoluteMediaPlaylistUri
1621
1716
  * @return {!shaka.media.SegmentReference}
1717
+ * @param {string} type
1622
1718
  * @private
1623
1719
  */
1624
1720
  createSegmentReference_(
1625
1721
  initSegmentReference, previousReference, hlsSegment, startTime,
1626
- timestampOffset, variables, absoluteMediaPlaylistUri) {
1722
+ timestampOffset, variables, absoluteMediaPlaylistUri, type) {
1627
1723
  const tags = hlsSegment.tags;
1628
1724
  const absoluteSegmentUri = this.variableSubstitution_(
1629
1725
  hlsSegment.absoluteUri, variables);
@@ -1714,6 +1810,17 @@ shaka.hls.HlsParser = class {
1714
1810
  endByte = partialSegmentRefs[partialSegmentRefs.length - 1].endByte;
1715
1811
  }
1716
1812
 
1813
+ let tilesLayout = '';
1814
+ if (type == shaka.util.ManifestParserUtils.ContentType.IMAGE) {
1815
+ // By default in HLS the tilesLayout is 1x1
1816
+ tilesLayout = '1x1';
1817
+ const tilesTag =
1818
+ shaka.hls.Utils.getFirstTagWithName(tags, 'EXT-X-TILES');
1819
+ if (tilesTag) {
1820
+ tilesLayout = tilesTag.getRequiredAttrValue('LAYOUT');
1821
+ }
1822
+ }
1823
+
1717
1824
  return new shaka.media.SegmentReference(
1718
1825
  startTime,
1719
1826
  endTime,
@@ -1725,6 +1832,7 @@ shaka.hls.HlsParser = class {
1725
1832
  /* appendWindowStart= */ 0,
1726
1833
  /* appendWindowEnd= */ Infinity,
1727
1834
  partialSegmentRefs,
1835
+ tilesLayout,
1728
1836
  );
1729
1837
  }
1730
1838
 
@@ -1820,12 +1928,13 @@ shaka.hls.HlsParser = class {
1820
1928
  initSegmentRef = this.getInitSegmentReference_(
1821
1929
  playlist.absoluteUri, hlsSegments[0].tags, variables);
1822
1930
  goog.asserts.assert(
1823
- type != shaka.util.ManifestParserUtils.ContentType.TEXT,
1931
+ type != shaka.util.ManifestParserUtils.ContentType.TEXT &&
1932
+ type != shaka.util.ManifestParserUtils.ContentType.IMAGE,
1824
1933
  'Should only get start time from audio or video streams');
1825
1934
  this.playlistStartTime_ = await this.getStartTime_(
1826
1935
  verbatimMediaPlaylistUri, initSegmentRef, mimeType,
1827
1936
  position, /* isDiscontinuity= */ false,
1828
- hlsSegments[0], variables);
1937
+ hlsSegments[0], variables, type);
1829
1938
  }
1830
1939
  firstStartTime = this.playlistStartTime_;
1831
1940
  }
@@ -1878,7 +1987,7 @@ shaka.hls.HlsParser = class {
1878
1987
  // eslint-disable-next-line no-await-in-loop
1879
1988
  timestampOffset = await this.getTimestampOffset_(
1880
1989
  discontintuitySequenceNum, verbatimMediaPlaylistUri, initSegmentRef,
1881
- mimeType, position, item, variables, startTime);
1990
+ mimeType, position, item, variables, startTime, type);
1882
1991
  }
1883
1992
 
1884
1993
  // If the stream is low latency and the user has not configured the
@@ -1903,7 +2012,8 @@ shaka.hls.HlsParser = class {
1903
2012
  startTime,
1904
2013
  timestampOffset,
1905
2014
  variables,
1906
- playlist.absoluteUri);
2015
+ playlist.absoluteUri,
2016
+ type);
1907
2017
 
1908
2018
  references.push(reference);
1909
2019
  } else if (!this.lowLatencyMode_) {
@@ -1915,9 +2025,6 @@ shaka.hls.HlsParser = class {
1915
2025
  }
1916
2026
  }
1917
2027
 
1918
- this.segmentsToNotifyByStream_.push(references);
1919
- this.notifySegments_();
1920
-
1921
2028
  return references;
1922
2029
  }
1923
2030
 
@@ -1933,13 +2040,14 @@ shaka.hls.HlsParser = class {
1933
2040
  * @param {!shaka.hls.Segment} segment
1934
2041
  * @param {!Map.<string, string>} variables
1935
2042
  * @param {number} startTime
2043
+ * @param {string} type
1936
2044
  * @return {!Promise.<number>}
1937
2045
  * @throws {shaka.util.Error}
1938
2046
  * @private
1939
2047
  */
1940
2048
  async getTimestampOffset_(discontintuitySequenceNum,
1941
2049
  verbatimMediaPlaylistUri, initSegmentRef,
1942
- mimeType, mediaSequenceNumber, segment, variables, startTime) {
2050
+ mimeType, mediaSequenceNumber, segment, variables, startTime, type) {
1943
2051
  let timestampOffset = 0;
1944
2052
  if (this.discontinuityToTso_.has(discontintuitySequenceNum)) {
1945
2053
  timestampOffset =
@@ -1948,7 +2056,7 @@ shaka.hls.HlsParser = class {
1948
2056
  const mediaStartTime = await this.getStartTime_(
1949
2057
  verbatimMediaPlaylistUri, initSegmentRef, mimeType,
1950
2058
  mediaSequenceNumber, /* isDiscontinuity= */ true, segment,
1951
- variables);
2059
+ variables, type);
1952
2060
  timestampOffset = startTime - mediaStartTime;
1953
2061
  shaka.log.v1('Segment timestampOffset =', timestampOffset);
1954
2062
  this.discontinuityToTso_.set(
@@ -2035,12 +2143,13 @@ shaka.hls.HlsParser = class {
2035
2143
  * @param {boolean} isDiscontinuity
2036
2144
  * @param {!shaka.hls.Segment} segment
2037
2145
  * @param {!Map.<string, string>} variables
2146
+ * @param {string} type
2038
2147
  * @return {!Promise.<number>}
2039
2148
  * @private
2040
2149
  */
2041
2150
  async getStartTime_(
2042
2151
  verbatimMediaPlaylistUri, initSegmentRef, mimeType, mediaSequenceNumber,
2043
- isDiscontinuity, segment, variables) {
2152
+ isDiscontinuity, segment, variables, type) {
2044
2153
  const segmentRef = this.createSegmentReference_(
2045
2154
  initSegmentRef,
2046
2155
  /* previousReference= */ null,
@@ -2048,7 +2157,8 @@ shaka.hls.HlsParser = class {
2048
2157
  /* startTime= */ 0,
2049
2158
  /* timestampOffset= */ 0,
2050
2159
  variables,
2051
- /* absoluteMediaPlaylistUri= */ '');
2160
+ /* absoluteMediaPlaylistUri= */ '',
2161
+ type);
2052
2162
  // If we are updating the manifest, we can usually skip fetching the segment
2053
2163
  // by examining the references we already have. This won't be possible if
2054
2164
  // there was some kind of lag or delay updating the manifest on the server,
@@ -2424,6 +2534,12 @@ shaka.hls.HlsParser = class {
2424
2534
  }
2425
2535
  }
2426
2536
 
2537
+ if (contentType == ContentType.IMAGE) {
2538
+ if (!codecs || codecs == 'jpeg') {
2539
+ return 'image/jpeg';
2540
+ }
2541
+ }
2542
+
2427
2543
  // If unable to guess mime type, request a segment and try getting it
2428
2544
  // from the response.
2429
2545
  const headRequest = shaka.net.NetworkingEngine.makeRequest(
@@ -2794,6 +2910,19 @@ shaka.hls.HlsParser.TEXT_EXTENSIONS_TO_MIME_TYPES_ = {
2794
2910
  };
2795
2911
 
2796
2912
 
2913
+ /**
2914
+ * @const {!Object.<string, string>}
2915
+ * @private
2916
+ */
2917
+ shaka.hls.HlsParser.IMAGE_EXTENSIONS_TO_MIME_TYPES_ = {
2918
+ 'jpg': 'image/jpeg',
2919
+ 'png': 'image/png',
2920
+ 'svg': 'image/svg+xml',
2921
+ 'webp': 'image/webp',
2922
+ 'avif': 'image/avif',
2923
+ };
2924
+
2925
+
2797
2926
  /**
2798
2927
  * @const {!Object.<string, !Object.<string, string>>}
2799
2928
  * @private
@@ -2802,6 +2931,7 @@ shaka.hls.HlsParser.EXTENSION_MAP_BY_CONTENT_TYPE_ = {
2802
2931
  'audio': shaka.hls.HlsParser.AUDIO_EXTENSIONS_TO_MIME_TYPES_,
2803
2932
  'video': shaka.hls.HlsParser.VIDEO_EXTENSIONS_TO_MIME_TYPES_,
2804
2933
  'text': shaka.hls.HlsParser.TEXT_EXTENSIONS_TO_MIME_TYPES_,
2934
+ 'image': shaka.hls.HlsParser.IMAGE_EXTENSIONS_TO_MIME_TYPES_,
2805
2935
  };
2806
2936
 
2807
2937
 
@@ -4,14 +4,13 @@
4
4
  * SPDX-License-Identifier: Apache-2.0
5
5
  */
6
6
 
7
- goog.provide('shaka.media.IClosedCaptionParser');
8
7
  goog.provide('shaka.media.ClosedCaptionParser');
8
+ goog.provide('shaka.media.IClosedCaptionParser');
9
9
 
10
10
  goog.require('shaka.cea.CeaDecoder');
11
11
  goog.require('shaka.cea.Mp4CeaParser');
12
12
  goog.require('shaka.util.BufferUtils');
13
13
  goog.requireType('shaka.cea.ICaptionDecoder');
14
- goog.requireType('shaka.cea.ICaptionDecoder.ClosedCaption');
15
14
  goog.requireType('shaka.cea.ICeaParser');
16
15
 
17
16