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.
- package/AUTHORS +3 -0
- package/CHANGELOG.md +175 -3
- package/CONTRIBUTORS +3 -0
- package/README.md +4 -4
- package/build/generateExterns.js +1 -1
- package/build/types/polyfill +1 -0
- package/demo/common/asset.js +9 -7
- package/demo/common/assets.js +11 -2
- package/demo/common/message_ids.js +2 -1
- package/demo/config.js +5 -2
- package/demo/index.html +1 -1
- package/demo/locales/en.json +2 -1
- package/demo/locales/source.json +8 -4
- package/demo/main.js +2 -1
- package/dist/controls.css +2 -2
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +15 -15
- package/dist/demo.compiled.debug.map +2 -2
- package/dist/demo.compiled.js +15 -15
- package/dist/demo.compiled.map +2 -2
- package/dist/deps.js +22 -21
- package/dist/locales.js +36 -36
- package/dist/receiver.compiled.debug.js +9 -9
- package/dist/receiver.compiled.debug.map +2 -2
- package/dist/receiver.compiled.js +9 -9
- package/dist/receiver.compiled.map +2 -2
- package/dist/shaka-player.compiled.d.ts +58 -10
- package/dist/shaka-player.compiled.debug.d.ts +58 -10
- package/dist/shaka-player.compiled.debug.externs.js +777 -717
- package/dist/shaka-player.compiled.debug.js +639 -607
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +777 -717
- package/dist/shaka-player.compiled.js +826 -819
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +58 -10
- package/dist/shaka-player.ui.debug.d.ts +58 -10
- package/dist/shaka-player.ui.debug.externs.js +529 -469
- package/dist/shaka-player.ui.debug.js +676 -645
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +529 -469
- package/dist/shaka-player.ui.js +963 -955
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/fairplay.md +1 -1
- package/docs/tutorials/ui.md +5 -5
- package/externs/aria.js +6 -0
- package/externs/shaka/ads.js +24 -1
- package/externs/shaka/manifest.js +6 -1
- package/externs/shaka/offline.js +5 -0
- package/externs/shaka/player.js +53 -9
- package/externs/shaka/text.js +10 -10
- package/externs/texttrack.js +3 -0
- package/karma.conf.js +1 -0
- package/lib/ads/ad_manager.js +16 -15
- package/lib/ads/client_side_ad_manager.js +52 -88
- package/lib/ads/server_side_ad_manager.js +26 -12
- package/lib/cast/cast_proxy.js +11 -2
- package/lib/cast/cast_receiver.js +2 -1
- package/lib/cast/cast_sender.js +2 -2
- package/lib/cast/cast_utils.js +6 -1
- package/lib/cea/cea608_data_channel.js +56 -56
- package/lib/cea/cea608_memory.js +33 -33
- package/lib/cea/cea708_service.js +43 -43
- package/lib/cea/cea708_window.js +38 -38
- package/lib/cea/cea_decoder.js +13 -14
- package/lib/cea/cea_utils.js +23 -23
- package/lib/cea/dtvcc_packet_builder.js +7 -7
- package/lib/cea/i_caption_decoder.js +2 -3
- package/lib/cea/i_cea_parser.js +2 -2
- package/lib/cea/mp4_cea_parser.js +6 -6
- package/lib/dash/dash_parser.js +98 -2
- package/lib/dash/segment_list.js +1 -1
- package/lib/dash/segment_template.js +1 -1
- package/lib/hls/hls_parser.js +159 -29
- package/lib/media/closed_caption_parser.js +1 -2
- package/lib/media/drm_engine.js +169 -192
- package/lib/media/gap_jumping_controller.js +4 -2
- package/lib/media/media_source_engine.js +1 -2
- package/lib/media/segment_index.js +3 -1
- package/lib/media/segment_reference.js +19 -2
- package/lib/media/streaming_engine.js +8 -7
- package/lib/net/networking_engine.js +3 -1
- package/lib/offline/download_manager.js +1 -2
- package/lib/offline/indexeddb/v1_storage_cell.js +1 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +1 -0
- package/lib/offline/manifest_converter.js +3 -1
- package/lib/offline/storage.js +12 -14
- package/lib/player.js +437 -167
- package/lib/polyfill/aria.js +82 -0
- package/lib/polyfill/media_capabilities.js +7 -1
- package/lib/polyfill/mediasource.js +6 -0
- package/lib/polyfill/orientation.js +1 -1
- package/lib/polyfill/patchedmediakeys_apple.js +4 -4
- package/lib/polyfill/patchedmediakeys_ms.js +4 -4
- package/lib/polyfill/patchedmediakeys_webkit.js +4 -4
- package/lib/routing/walker.js +2 -3
- package/lib/text/mp4_ttml_parser.js +3 -0
- package/lib/text/srt_text_parser.js +4 -4
- package/lib/text/text_engine.js +16 -4
- package/lib/text/ttml_text_parser.js +5 -0
- package/lib/text/ui_text_displayer.js +85 -37
- package/lib/text/vtt_text_parser.js +2 -2
- package/lib/text/web_vtt_generator.js +55 -12
- package/lib/util/error.js +6 -0
- package/lib/util/fake_event.js +53 -7
- package/lib/util/manifest_parser_utils.js +1 -0
- package/lib/util/mp4_box_parsers.js +20 -20
- package/lib/util/multi_map.js +8 -0
- package/lib/util/periods.js +4 -1
- package/lib/util/platform.js +13 -1
- package/lib/util/player_configuration.js +13 -1
- package/lib/util/stream_utils.js +153 -85
- package/lib/util/xml_utils.js +31 -12
- package/package.json +1 -1
- package/roadmap.md +24 -22
- package/shaka-player.uncompiled.js +1 -0
- package/test/cast/cast_proxy_unit.js +12 -6
- package/test/cast/cast_utils_unit.js +2 -1
- package/test/cea/cea608_memory_unit.js +1 -1
- package/test/cea/cea708_service_unit.js +8 -8
- package/test/cea/cea708_window_unit.js +6 -6
- package/test/cea/cea_decoder_unit.js +1 -1
- package/test/cea/dtvcc_packet_builder_unit.js +2 -2
- package/test/dash/dash_parser_manifest_unit.js +230 -2
- package/test/hls/hls_parser_unit.js +255 -1
- package/test/media/closed_caption_parser_unit.js +6 -1
- package/test/media/drm_engine_integration.js +86 -12
- package/test/media/drm_engine_unit.js +353 -450
- package/test/offline/manifest_convert_unit.js +2 -0
- package/test/offline/storage_integration.js +9 -19
- package/test/player_integration.js +90 -0
- package/test/player_src_equals_integration.js +52 -0
- package/test/player_unit.js +11 -33
- package/test/test/assets/3675/chunk-stream0-00001.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00002.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00003.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00004.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00005.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00006.m4s +0 -0
- package/test/test/assets/3675/chunk-stream0-00007.m4s +0 -0
- package/test/test/assets/3675/dash_0.mpd +30 -0
- package/test/test/assets/3675/dash_1.mpd +30 -0
- package/test/test/assets/3675/dash_2.mpd +30 -0
- package/test/test/assets/3675/dash_3.mpd +30 -0
- package/test/test/assets/3675/dash_4.mpd +30 -0
- package/test/test/assets/3675/dash_5.mpd +26 -0
- package/test/test/assets/3675/init-stream0.m4s +0 -0
- package/test/test/assets/chapters.srt +11 -0
- package/test/test/assets/chapters.vtt +10 -0
- package/test/test/util/cea_utils.js +12 -12
- package/test/test/util/fake_ad_manager.js +8 -1
- package/test/test/util/manifest_generator.js +2 -0
- package/test/test/util/manifest_parser_util.js +3 -1
- package/test/text/ttml_text_parser_unit.js +9 -0
- package/test/text/ui_text_displayer_unit.js +29 -17
- package/test/text/web_vtt_generator_unit.js +81 -7
- package/test/ui/localization_unit.js +15 -14
- package/test/ui/text_displayer_layout_unit.js +13 -1
- package/test/util/stream_utils_unit.js +153 -10
- package/ui/airplay_button.js +1 -1
- package/ui/audio_language_selection.js +2 -5
- package/ui/cast_button.js +6 -9
- package/ui/constants.js +0 -3
- package/ui/controls.js +4 -6
- package/ui/fast_forward_button.js +2 -3
- package/ui/fullscreen_button.js +1 -3
- package/ui/language_utils.js +1 -1
- package/ui/less/containers.less +3 -7
- package/ui/locales/ru.json +6 -6
- package/ui/localization.js +28 -51
- package/ui/loop_button.js +1 -3
- package/ui/mute_button.js +1 -3
- package/ui/overflow_menu.js +2 -3
- package/ui/pip_button.js +7 -10
- package/ui/playback_rate_selection.js +3 -6
- package/ui/presentation_time.js +1 -3
- package/ui/resolution_selection.js +4 -7
- package/ui/rewind_button.js +2 -3
- package/ui/seek_bar.js +2 -4
- package/ui/spacer.js +1 -1
- package/ui/text_selection.js +8 -11
- package/ui/ui_utils.js +1 -1
- package/ui/volume_bar.js +1 -3
package/lib/hls/hls_parser.js
CHANGED
|
@@ -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
|
|
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
|
|
427
|
+
data.set('language', language);
|
|
426
428
|
}
|
|
427
429
|
if (value) {
|
|
428
|
-
data.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.
|
|
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
|
|
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
|
|