shaka-player 3.3.5 → 4.0.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/.github/config.yml +1 -0
- package/.github/workflows/demo-version-index.yaml +8 -0
- package/.github/workflows/release-please.yaml +18 -2
- package/.github/workflows/sync-labels.yaml +33 -0
- package/.github/workflows/update-issues.yaml +29 -0
- package/.github/workflows/validate-pr-title.yaml +35 -0
- package/AUTHORS +1 -0
- package/CHANGELOG.md +215 -41
- package/CONTRIBUTORS +1 -0
- package/README.md +14 -11
- package/app-engine/demo-version-index/README.md +3 -3
- package/app-engine/demo-version-index/app.yaml +27 -1
- package/app-engine/demo-version-index/generate.py +164 -0
- package/app-engine/demo-version-index/main.py +4 -155
- package/app-engine/demo-version-index/requirements.txt +0 -1
- package/build/checkversion.py +1 -1
- package/build/compiler.py +1 -1
- package/build/misspellings.txt +1 -0
- package/build/shaka-lab.yaml +0 -2
- package/build/types/polyfill +0 -3
- package/demo/common/asset.js +17 -1
- package/demo/common/assets.js +29 -0
- package/demo/common/message_ids.js +6 -3
- package/demo/config.js +10 -11
- package/demo/custom.js +39 -0
- package/demo/demo.less +0 -1
- package/demo/demo_utils.js +0 -1
- package/demo/locales/en.json +6 -3
- package/demo/locales/source.json +22 -10
- package/demo/main.js +9 -6
- package/demo/search.js +2 -1
- package/dist/controls.css +3 -3
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +71 -64
- package/dist/demo.compiled.debug.map +3 -3
- package/dist/demo.compiled.js +71 -64
- package/dist/demo.compiled.map +3 -3
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +17 -20
- package/dist/locales.js +33 -31
- package/dist/receiver.compiled.debug.js +32 -28
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +32 -28
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.d.ts +311 -314
- package/dist/shaka-player.compiled.debug.d.ts +311 -314
- package/dist/shaka-player.compiled.debug.externs.js +126 -126
- package/dist/shaka-player.compiled.debug.js +430 -484
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +126 -126
- package/dist/shaka-player.compiled.js +829 -845
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +357 -358
- package/dist/shaka-player.ui.debug.d.ts +357 -358
- package/dist/shaka-player.ui.debug.externs.js +134 -126
- package/dist/shaka-player.ui.debug.js +489 -541
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +134 -126
- package/dist/shaka-player.ui.js +988 -1000
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/config.md +0 -2
- package/docs/tutorials/drm-config.md +5 -0
- package/docs/tutorials/fairplay.md +7 -22
- package/docs/tutorials/faq.md +0 -11
- package/docs/tutorials/index.json +2 -8
- package/docs/tutorials/plugins.md +1 -3
- package/docs/tutorials/upgrade.md +85 -11
- package/externs/polyfill.js +15 -0
- package/externs/shaka/manifest.js +5 -1
- package/externs/shaka/net.js +12 -0
- package/externs/shaka/offline.js +5 -1
- package/externs/shaka/player.js +39 -21
- package/externs/shaka/text.js +12 -12
- package/externs/sourcebuffer.js +15 -0
- package/lib/abr/simple_abr_manager.js +2 -1
- package/lib/ads/client_side_ad.js +13 -2
- package/lib/ads/client_side_ad_manager.js +22 -4
- package/lib/cast/cast_utils.js +0 -1
- package/lib/dash/content_protection.js +85 -5
- package/lib/dash/dash_parser.js +1 -0
- package/lib/hls/hls_parser.js +390 -747
- package/lib/hls/manifest_text_parser.js +2 -3
- package/lib/media/drm_engine.js +105 -37
- package/lib/media/gap_jumping_controller.js +10 -45
- package/lib/media/media_source_engine.js +150 -30
- package/lib/media/playhead.js +2 -5
- package/lib/media/presentation_timeline.js +1 -2
- package/lib/media/segment_index.js +13 -46
- package/lib/media/segment_reference.js +47 -1
- package/lib/media/streaming_engine.js +28 -11
- package/lib/media/time_ranges_utils.js +4 -9
- package/lib/net/networking_engine.js +3 -0
- 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 +1 -0
- package/lib/offline/storage.js +8 -41
- package/lib/player.js +17 -201
- package/lib/polyfill/media_capabilities.js +12 -6
- package/lib/polyfill/mediasource.js +0 -28
- package/lib/polyfill/patchedmediakeys_nop.js +2 -0
- package/lib/polyfill/patchedmediakeys_webkit.js +2 -0
- package/lib/text/cue.js +0 -6
- package/lib/text/lrc_text_parser.js +8 -0
- package/lib/text/mp4_ttml_parser.js +8 -0
- package/lib/text/mp4_vtt_parser.js +8 -0
- package/lib/text/sbv_text_parser.js +8 -0
- package/lib/text/simple_text_displayer.js +1 -7
- package/lib/text/srt_text_parser.js +8 -0
- package/lib/text/ssa_text_parser.js +8 -0
- package/lib/text/text_engine.js +19 -3
- package/lib/text/ttml_text_parser.js +8 -0
- package/lib/text/ui_text_displayer.js +1 -7
- package/lib/text/vtt_text_parser.js +27 -5
- package/lib/text/web_vtt_generator.js +1 -7
- package/lib/util/error.js +9 -13
- package/lib/util/fairplay_utils.js +109 -0
- package/lib/util/functional.js +0 -42
- package/lib/util/mime_utils.js +16 -5
- package/lib/util/platform.js +45 -0
- package/lib/util/player_configuration.js +17 -6
- package/lib/util/pssh.js +23 -4
- package/lib/util/stream_utils.js +92 -22
- package/lib/util/uint8array_utils.js +0 -16
- package/lib/util/xml_utils.js +1 -1
- package/package.json +5 -2
- package/roadmap.md +19 -19
- package/shaka-player.uncompiled.js +0 -3
- package/test/dash/dash_parser_content_protection_unit.js +44 -0
- package/test/dash/dash_parser_segment_template_unit.js +3 -4
- package/test/demo/demo_unit.js +2 -1
- package/test/hls/hls_live_unit.js +155 -230
- package/test/hls/hls_parser_unit.js +515 -432
- package/test/media/drm_engine_unit.js +86 -120
- package/test/media/media_source_engine_integration.js +25 -3
- package/test/media/media_source_engine_unit.js +3 -2
- package/test/media/playhead_unit.js +27 -191
- package/test/media/segment_index_unit.js +15 -25
- package/test/media/streaming_engine_integration.js +2 -39
- package/test/media/streaming_engine_unit.js +3 -2
- package/test/media/time_ranges_utils_unit.js +0 -5
- package/test/offline/manifest_convert_unit.js +34 -4
- package/test/offline/offline_manifest_parser_unit.js +1 -0
- package/test/offline/storage_integration.js +5 -4
- package/test/player_external.js +0 -6
- package/test/player_integration.js +16 -0
- package/test/player_unit.js +26 -0
- package/test/test/util/fake_media_source_engine.js +11 -4
- package/test/test/util/manifest_generator.js +3 -1
- package/test/test/util/manifest_parser_util.js +4 -1
- package/test/test/util/offline_utils.js +1 -0
- package/test/test/util/streaming_engine_util.js +1 -0
- package/test/test/util/test_scheme.js +24 -1
- package/test/test/util/util.js +4 -4
- package/test/text/cue_integration.js +2 -2
- package/test/text/lrc_text_parser_unit.js +6 -7
- package/test/text/mp4_ttml_parser_unit.js +6 -4
- package/test/text/mp4_vtt_parser_unit.js +6 -5
- package/test/text/sbv_text_parser_unit.js +5 -6
- package/test/text/srt_text_parser_unit.js +5 -6
- package/test/text/ssa_text_parser_unit.js +17 -29
- package/test/text/text_engine_unit.js +45 -5
- package/test/text/ttml_text_parser_unit.js +77 -77
- package/test/text/vtt_text_parser_unit.js +116 -59
- package/test/ui/ui_integration.js +0 -16
- package/test/ui/ui_unit.js +27 -0
- package/test/util/cmcd_manager_unit.js +3 -0
- package/test/util/stream_utils_unit.js +23 -7
- package/ui/controls.js +65 -40
- package/ui/fullscreen_button.js +26 -6
- package/ui/less/containers.less +4 -4
- package/ui/less/general.less +1 -1
- package/ui/less/range_elements.less +1 -0
- package/ui/locales/en.json +1 -0
- package/ui/locales/source.json +5 -0
- package/ui/resolution_selection.js +31 -33
- package/ui/ui.js +0 -17
- package/.github/pull_request_template.md +0 -10
- package/docs/tutorials/upgrade-v2-5.md +0 -441
- package/docs/tutorials/upgrade-v3.md +0 -38
- package/lib/polyfill/mathround.js +0 -49
- package/lib/polyfill/patchedmediakeys_apple.js +0 -744
- package/lib/polyfill/patchedmediakeys_ms.js +0 -698
- package/test/util/functional_unit.js +0 -82
package/lib/player.js
CHANGED
|
@@ -43,7 +43,6 @@ goog.require('shaka.util.Error');
|
|
|
43
43
|
goog.require('shaka.util.EventManager');
|
|
44
44
|
goog.require('shaka.util.FakeEvent');
|
|
45
45
|
goog.require('shaka.util.FakeEventTarget');
|
|
46
|
-
goog.require('shaka.util.Functional');
|
|
47
46
|
goog.require('shaka.util.IDestroyable');
|
|
48
47
|
goog.require('shaka.util.LanguageUtils');
|
|
49
48
|
goog.require('shaka.util.ManifestParserUtils');
|
|
@@ -301,22 +300,6 @@ goog.requireType('shaka.routing.Payload');
|
|
|
301
300
|
*/
|
|
302
301
|
|
|
303
302
|
|
|
304
|
-
/**
|
|
305
|
-
* @event shaka.Player.LargeGapEvent
|
|
306
|
-
* @description Fired when the playhead enters a large gap. If the
|
|
307
|
-
* <code>streaming.jumpLargeGaps</code> configuration is set, the default
|
|
308
|
-
* action of this event is to jump the gap; this can be prevented by calling
|
|
309
|
-
* <code>preventDefault()</code> on the event object.
|
|
310
|
-
* @property {string} type
|
|
311
|
-
* 'largegap'
|
|
312
|
-
* @property {number} currentTime
|
|
313
|
-
* The current time of the playhead.
|
|
314
|
-
* @property {number} gapSize
|
|
315
|
-
* The size of the gap, in seconds.
|
|
316
|
-
* @exportDoc
|
|
317
|
-
*/
|
|
318
|
-
|
|
319
|
-
|
|
320
303
|
/**
|
|
321
304
|
* @event shaka.Player.ManifestParsedEvent
|
|
322
305
|
* @description Fired after the manifest has been parsed, but before anything
|
|
@@ -591,8 +574,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
591
574
|
this.adManager_ = null;
|
|
592
575
|
|
|
593
576
|
if (shaka.Player.adManagerFactory_) {
|
|
594
|
-
this.adManager_ =
|
|
595
|
-
shaka.util.Functional.callFactory(shaka.Player.adManagerFactory_);
|
|
577
|
+
this.adManager_ = shaka.Player.adManagerFactory_();
|
|
596
578
|
}
|
|
597
579
|
|
|
598
580
|
// If the browser comes back online after being offline, then try to play
|
|
@@ -870,10 +852,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
870
852
|
return false;
|
|
871
853
|
}
|
|
872
854
|
|
|
873
|
-
// We do not support iOS 9, 10, or
|
|
874
|
-
// Safari.
|
|
855
|
+
// We do not support iOS 9, 10, 11 or 12, nor those same versions of
|
|
856
|
+
// desktop Safari.
|
|
875
857
|
const safariVersion = shaka.util.Platform.safariVersion();
|
|
876
|
-
if (safariVersion && safariVersion <
|
|
858
|
+
if (safariVersion && safariVersion < 13) {
|
|
877
859
|
return false;
|
|
878
860
|
}
|
|
879
861
|
|
|
@@ -1579,8 +1561,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1579
1561
|
// text displayer and streaming engine are always in sync, wait until they
|
|
1580
1562
|
// are both initialized before setting the initial value.
|
|
1581
1563
|
const textDisplayerFactory = this.config_.textDisplayFactory;
|
|
1582
|
-
const textDisplayer =
|
|
1583
|
-
shaka.util.Functional.callFactory(textDisplayerFactory);
|
|
1564
|
+
const textDisplayer = textDisplayerFactory();
|
|
1584
1565
|
this.lastTextFactory_ = textDisplayerFactory;
|
|
1585
1566
|
|
|
1586
1567
|
const mediaSourceEngine = this.createMediaSourceEngine(
|
|
@@ -1590,6 +1571,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1590
1571
|
(metadata, offset, endTime) => {
|
|
1591
1572
|
this.processTimedMetadataMediaSrc_(metadata, offset, endTime);
|
|
1592
1573
|
});
|
|
1574
|
+
const {segmentRelativeVttTiming} = this.config_.manifest;
|
|
1575
|
+
mediaSourceEngine.setSegmentRelativeVttTiming(segmentRelativeVttTiming);
|
|
1593
1576
|
|
|
1594
1577
|
// Wait for media source engine to finish opening. This promise should
|
|
1595
1578
|
// NEVER be rejected as per the media source engine implementation.
|
|
@@ -1651,7 +1634,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1651
1634
|
this.config_.manifest.retryParameters,
|
|
1652
1635
|
has.mimeType);
|
|
1653
1636
|
goog.asserts.assert(this.parserFactory_, 'Must have manifest parser');
|
|
1654
|
-
this.parser_ =
|
|
1637
|
+
this.parser_ = this.parserFactory_();
|
|
1655
1638
|
|
|
1656
1639
|
const manifestConfig =
|
|
1657
1640
|
shaka.util.ObjectUtils.cloneObject(this.config_.manifest);
|
|
@@ -1937,13 +1920,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1937
1920
|
const abrFactory = this.config_.abrFactory;
|
|
1938
1921
|
if (!this.abrManager_ || this.abrManagerFactory_ != abrFactory) {
|
|
1939
1922
|
this.abrManagerFactory_ = abrFactory;
|
|
1940
|
-
this.abrManager_ =
|
|
1941
|
-
if (typeof this.abrManager_.playbackRateChanged != 'function') {
|
|
1942
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
1943
|
-
'AbrManager',
|
|
1944
|
-
'Please use an AbrManager with playbackRateChanged function.');
|
|
1945
|
-
this.abrManager_.playbackRateChanged = (rate) => {};
|
|
1946
|
-
}
|
|
1923
|
+
this.abrManager_ = abrFactory();
|
|
1947
1924
|
this.abrManager_.configure(this.config_.abr);
|
|
1948
1925
|
}
|
|
1949
1926
|
|
|
@@ -2716,8 +2693,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2716
2693
|
this.manifest_,
|
|
2717
2694
|
this.config_.streaming,
|
|
2718
2695
|
startTime,
|
|
2719
|
-
() => this.onSeek_()
|
|
2720
|
-
(event) => this.dispatchEvent(event));
|
|
2696
|
+
() => this.onSeek_());
|
|
2721
2697
|
}
|
|
2722
2698
|
|
|
2723
2699
|
/**
|
|
@@ -2976,17 +2952,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2976
2952
|
|
|
2977
2953
|
goog.asserts.assert(typeof(config) == 'object', 'Should be an object!');
|
|
2978
2954
|
|
|
2979
|
-
// Deprecate 'manifest.dash.defaultPresentationDelay' configuration.
|
|
2980
|
-
if (config['manifest'] && config['manifest']['dash'] &&
|
|
2981
|
-
'defaultPresentationDelay' in config['manifest']['dash']) {
|
|
2982
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
2983
|
-
'manifest.dash.defaultPresentationDelay configuration',
|
|
2984
|
-
'Please Use manifest.defaultPresentationDelay instead.');
|
|
2985
|
-
config['manifest']['defaultPresentationDelay'] =
|
|
2986
|
-
config['manifest']['dash']['defaultPresentationDelay'];
|
|
2987
|
-
delete config['manifest']['dash']['defaultPresentationDelay'];
|
|
2988
|
-
}
|
|
2989
|
-
|
|
2990
2955
|
// If lowLatencyMode is enabled, and inaccurateManifestTolerance and
|
|
2991
2956
|
// rebufferingGoal are not specified, set inaccurateManifestTolerance to 0
|
|
2992
2957
|
// and rebufferingGoal to 0.01 by default for low latency streaming.
|
|
@@ -3053,10 +3018,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3053
3018
|
}
|
|
3054
3019
|
|
|
3055
3020
|
if (this.mediaSourceEngine_) {
|
|
3021
|
+
const {segmentRelativeVttTiming} = this.config_.manifest;
|
|
3022
|
+
this.mediaSourceEngine_.setSegmentRelativeVttTiming(
|
|
3023
|
+
segmentRelativeVttTiming);
|
|
3024
|
+
|
|
3056
3025
|
const textDisplayerFactory = this.config_.textDisplayFactory;
|
|
3057
3026
|
if (this.lastTextFactory_ != textDisplayerFactory) {
|
|
3058
|
-
const displayer =
|
|
3059
|
-
shaka.util.Functional.callFactory(textDisplayerFactory);
|
|
3027
|
+
const displayer = textDisplayerFactory();
|
|
3060
3028
|
this.mediaSourceEngine_.setTextDisplayer(displayer);
|
|
3061
3029
|
this.lastTextFactory_ = textDisplayerFactory;
|
|
3062
3030
|
|
|
@@ -4441,158 +4409,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4441
4409
|
return this.stats_.getBlob();
|
|
4442
4410
|
}
|
|
4443
4411
|
|
|
4444
|
-
/**
|
|
4445
|
-
* Adds the given text track to the loaded manifest. <code>load()</code> must
|
|
4446
|
-
* resolve before calling. The presentation must have a duration.
|
|
4447
|
-
*
|
|
4448
|
-
* This returns the created track, which can immediately be selected by the
|
|
4449
|
-
* application. The track will not be automatically selected.
|
|
4450
|
-
*
|
|
4451
|
-
* @param {string} uri
|
|
4452
|
-
* @param {string} language
|
|
4453
|
-
* @param {string} kind
|
|
4454
|
-
* @param {string=} mimeType
|
|
4455
|
-
* @param {string=} codec
|
|
4456
|
-
* @param {string=} label
|
|
4457
|
-
* @param {boolean=} forced
|
|
4458
|
-
* @return {shaka.extern.Track}
|
|
4459
|
-
* @export
|
|
4460
|
-
*/
|
|
4461
|
-
addTextTrack(uri, language, kind, mimeType, codec, label, forced = false) {
|
|
4462
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
4463
|
-
'addTextTrack',
|
|
4464
|
-
'Please use an addTextTrackAsync.');
|
|
4465
|
-
if (this.loadMode_ != shaka.Player.LoadMode.MEDIA_SOURCE &&
|
|
4466
|
-
this.loadMode_ != shaka.Player.LoadMode.SRC_EQUALS) {
|
|
4467
|
-
shaka.log.error(
|
|
4468
|
-
'Must call load() and wait for it to resolve before adding text ' +
|
|
4469
|
-
'tracks.');
|
|
4470
|
-
throw new shaka.util.Error(
|
|
4471
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4472
|
-
shaka.util.Error.Category.PLAYER,
|
|
4473
|
-
shaka.util.Error.Code.CONTENT_NOT_LOADED);
|
|
4474
|
-
}
|
|
4475
|
-
|
|
4476
|
-
if (!mimeType) {
|
|
4477
|
-
// Try using the uri extension.
|
|
4478
|
-
const extension = shaka.media.ManifestParser.getExtension(uri);
|
|
4479
|
-
mimeType = shaka.Player.TEXT_EXTENSIONS_TO_MIME_TYPES_[extension];
|
|
4480
|
-
|
|
4481
|
-
if (!mimeType) {
|
|
4482
|
-
shaka.log.error(
|
|
4483
|
-
'The mimeType has not been provided and it could not be deduced ' +
|
|
4484
|
-
'from its extension.');
|
|
4485
|
-
throw new shaka.util.Error(
|
|
4486
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4487
|
-
shaka.util.Error.Category.TEXT,
|
|
4488
|
-
shaka.util.Error.Code.TEXT_COULD_NOT_GUESS_MIME_TYPE,
|
|
4489
|
-
extension);
|
|
4490
|
-
}
|
|
4491
|
-
}
|
|
4492
|
-
|
|
4493
|
-
if (this.loadMode_ == shaka.Player.LoadMode.SRC_EQUALS) {
|
|
4494
|
-
if (mimeType != 'text/vtt') {
|
|
4495
|
-
shaka.log.error('Only WebVTT is supported when using src=');
|
|
4496
|
-
throw new shaka.util.Error(
|
|
4497
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4498
|
-
shaka.util.Error.Category.TEXT,
|
|
4499
|
-
shaka.util.Error.Code.TEXT_ONLY_WEBVTT_SRC_EQUALS,
|
|
4500
|
-
mimeType);
|
|
4501
|
-
}
|
|
4502
|
-
if (forced) {
|
|
4503
|
-
// See: https://github.com/whatwg/html/issues/4472
|
|
4504
|
-
kind = 'forced';
|
|
4505
|
-
}
|
|
4506
|
-
const trackElement =
|
|
4507
|
-
/** @type {!HTMLTrackElement} */(document.createElement('track'));
|
|
4508
|
-
trackElement.src = this.cmcdManager_.appendTextTrackData(uri);
|
|
4509
|
-
trackElement.label = label || '';
|
|
4510
|
-
trackElement.kind = kind;
|
|
4511
|
-
trackElement.srclang = language;
|
|
4512
|
-
// Because we're pulling in the text track file via Javascript, the
|
|
4513
|
-
// same-origin policy applies. If you'd like to have a player served
|
|
4514
|
-
// from one domain, but the text track served from another, you'll
|
|
4515
|
-
// need to enable CORS in order to do so. In addition to enabling CORS
|
|
4516
|
-
// on the server serving the text tracks, you will need to add the
|
|
4517
|
-
// crossorigin attribute to the video element itself.
|
|
4518
|
-
if (!this.video_.getAttribute('crossorigin')) {
|
|
4519
|
-
this.video_.setAttribute('crossorigin', 'anonymous');
|
|
4520
|
-
}
|
|
4521
|
-
this.video_.appendChild(trackElement);
|
|
4522
|
-
const textTracks = this.getTextTracks();
|
|
4523
|
-
const srcTrack = textTracks.find((t) => {
|
|
4524
|
-
return t.language == language &&
|
|
4525
|
-
t.label == (label || '') &&
|
|
4526
|
-
t.kind == kind;
|
|
4527
|
-
});
|
|
4528
|
-
if (srcTrack) {
|
|
4529
|
-
this.onTracksChanged_();
|
|
4530
|
-
return srcTrack;
|
|
4531
|
-
}
|
|
4532
|
-
// This should not happen, but there are browser implementations that may
|
|
4533
|
-
// not support the Track element.
|
|
4534
|
-
shaka.log.error('Cannot add this text when loaded with src=');
|
|
4535
|
-
throw new shaka.util.Error(
|
|
4536
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4537
|
-
shaka.util.Error.Category.TEXT,
|
|
4538
|
-
shaka.util.Error.Code.CANNOT_ADD_EXTERNAL_TEXT_TO_SRC_EQUALS);
|
|
4539
|
-
}
|
|
4540
|
-
|
|
4541
|
-
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
4542
|
-
|
|
4543
|
-
const duration = this.manifest_.presentationTimeline.getDuration();
|
|
4544
|
-
if (duration == Infinity) {
|
|
4545
|
-
throw new shaka.util.Error(
|
|
4546
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4547
|
-
shaka.util.Error.Category.MANIFEST,
|
|
4548
|
-
shaka.util.Error.Code.CANNOT_ADD_EXTERNAL_TEXT_TO_LIVE_STREAM);
|
|
4549
|
-
}
|
|
4550
|
-
|
|
4551
|
-
/** @type {shaka.extern.Stream} */
|
|
4552
|
-
const stream = {
|
|
4553
|
-
id: this.nextExternalStreamId_++,
|
|
4554
|
-
originalId: null,
|
|
4555
|
-
createSegmentIndex: () => Promise.resolve(),
|
|
4556
|
-
segmentIndex: shaka.media.SegmentIndex.forSingleSegment(
|
|
4557
|
-
/* startTime= */ 0,
|
|
4558
|
-
/* duration= */ duration,
|
|
4559
|
-
/* uris= */ [uri]),
|
|
4560
|
-
mimeType: mimeType || '',
|
|
4561
|
-
codecs: codec || '',
|
|
4562
|
-
kind: kind,
|
|
4563
|
-
encrypted: false,
|
|
4564
|
-
drmInfos: [],
|
|
4565
|
-
keyIds: new Set(),
|
|
4566
|
-
language: language,
|
|
4567
|
-
label: label || null,
|
|
4568
|
-
type: ContentType.TEXT,
|
|
4569
|
-
primary: false,
|
|
4570
|
-
trickModeVideo: null,
|
|
4571
|
-
emsgSchemeIdUris: null,
|
|
4572
|
-
roles: [],
|
|
4573
|
-
forced: !!forced,
|
|
4574
|
-
channelsCount: null,
|
|
4575
|
-
audioSamplingRate: null,
|
|
4576
|
-
spatialAudio: false,
|
|
4577
|
-
closedCaptions: null,
|
|
4578
|
-
};
|
|
4579
|
-
|
|
4580
|
-
const fullMimeType = shaka.util.MimeUtils.getFullType(
|
|
4581
|
-
stream.mimeType, stream.codecs);
|
|
4582
|
-
const supported = shaka.text.TextEngine.isTypeSupported(fullMimeType);
|
|
4583
|
-
if (!supported) {
|
|
4584
|
-
throw new shaka.util.Error(
|
|
4585
|
-
shaka.util.Error.Severity.CRITICAL,
|
|
4586
|
-
shaka.util.Error.Category.TEXT,
|
|
4587
|
-
shaka.util.Error.Code.MISSING_TEXT_PLUGIN,
|
|
4588
|
-
mimeType);
|
|
4589
|
-
}
|
|
4590
|
-
|
|
4591
|
-
this.manifest_.textStreams.push(stream);
|
|
4592
|
-
this.onTracksChanged_();
|
|
4593
|
-
return shaka.util.StreamUtils.textStreamToTrack(stream);
|
|
4594
|
-
}
|
|
4595
|
-
|
|
4596
4412
|
/**
|
|
4597
4413
|
* Adds the given text track to the loaded manifest. <code>load()</code> must
|
|
4598
4414
|
* resolve before calling. The presentation must have a duration.
|
|
@@ -4918,6 +4734,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4918
4734
|
periodStart: 0,
|
|
4919
4735
|
segmentStart: 0,
|
|
4920
4736
|
segmentEnd: this.video_.duration,
|
|
4737
|
+
vttOffset: 0,
|
|
4921
4738
|
};
|
|
4922
4739
|
const data = shaka.util.BufferUtils.toUint8(buffer);
|
|
4923
4740
|
const cues = obj.parseMedia(data, time);
|
|
@@ -6574,7 +6391,6 @@ shaka.Player.EventName = {
|
|
|
6574
6391
|
Emsg: 'emsg',
|
|
6575
6392
|
Error: 'error',
|
|
6576
6393
|
ExpirationUpdated: 'expirationupdated',
|
|
6577
|
-
LargeGap: 'largegap',
|
|
6578
6394
|
Loaded: 'loaded',
|
|
6579
6395
|
Loading: 'loading',
|
|
6580
6396
|
ManifestParsed: 'manifestparsed',
|
|
@@ -6634,7 +6450,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6634
6450
|
* @define {string} A version number taken from git at compile time.
|
|
6635
6451
|
* @export
|
|
6636
6452
|
*/
|
|
6637
|
-
shaka.Player.version = '
|
|
6453
|
+
shaka.Player.version = 'v4.0.2-uncompiled';
|
|
6638
6454
|
|
|
6639
6455
|
// Initialize the deprecation system using the version string we just set
|
|
6640
6456
|
// on the player.
|
|
@@ -24,8 +24,8 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
24
24
|
* @export
|
|
25
25
|
*/
|
|
26
26
|
static install() {
|
|
27
|
-
// Since MediaCapabilities is not fully supported on Chromecast yet,
|
|
28
|
-
// should always install polyfill for Chromecast.
|
|
27
|
+
// Since MediaCapabilities is not fully supported on some Chromecast yet,
|
|
28
|
+
// we should always install polyfill for all Chromecast not Android-based.
|
|
29
29
|
// TODO: re-evaluate MediaCapabilities in the future versions of Chromecast.
|
|
30
30
|
// Since MediaCapabilities implementation is buggy in Apple browsers, we
|
|
31
31
|
// should always install polyfill for Apple browsers.
|
|
@@ -37,10 +37,16 @@ shaka.polyfill.MediaCapabilities = class {
|
|
|
37
37
|
// See: https://github.com/shaka-project/shaka-player/issues/3582
|
|
38
38
|
// TODO: re-evaluate MediaCapabilities in the future versions of PS5
|
|
39
39
|
// Browsers.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
let canUseNativeMCap = true;
|
|
41
|
+
if (shaka.util.Platform.isApple() ||
|
|
42
|
+
shaka.util.Platform.isPS5() ||
|
|
43
|
+
shaka.util.Platform.isChromecast()) {
|
|
44
|
+
canUseNativeMCap = false;
|
|
45
|
+
}
|
|
46
|
+
if (shaka.util.Platform.isAndroidCastDevice()) {
|
|
47
|
+
canUseNativeMCap = true;
|
|
48
|
+
}
|
|
49
|
+
if (canUseNativeMCap && navigator.mediaCapabilities) {
|
|
44
50
|
shaka.log.info(
|
|
45
51
|
'MediaCapabilities: Native mediaCapabilities support found.');
|
|
46
52
|
return;
|
|
@@ -38,11 +38,6 @@ shaka.polyfill.MediaSource = class {
|
|
|
38
38
|
// Chromecast cannot make accurate determinations via isTypeSupported.
|
|
39
39
|
shaka.polyfill.MediaSource.patchCastIsTypeSupported_();
|
|
40
40
|
} else if (safariVersion) {
|
|
41
|
-
// TS content is broken on Safari in general.
|
|
42
|
-
// See https://github.com/shaka-project/shaka-player/issues/743
|
|
43
|
-
// and https://bugs.webkit.org/show_bug.cgi?id=165342
|
|
44
|
-
shaka.polyfill.MediaSource.rejectTsContent_();
|
|
45
|
-
|
|
46
41
|
// NOTE: shaka.Player.isBrowserSupported() has its own restrictions on
|
|
47
42
|
// Safari version.
|
|
48
43
|
if (safariVersion <= 12) {
|
|
@@ -127,29 +122,6 @@ shaka.polyfill.MediaSource = class {
|
|
|
127
122
|
};
|
|
128
123
|
}
|
|
129
124
|
|
|
130
|
-
/**
|
|
131
|
-
* Patch isTypeSupported() to reject TS content. Used to avoid TS-related MSE
|
|
132
|
-
* bugs on Safari.
|
|
133
|
-
*
|
|
134
|
-
* @private
|
|
135
|
-
*/
|
|
136
|
-
static rejectTsContent_() {
|
|
137
|
-
const originalIsTypeSupported = MediaSource.isTypeSupported;
|
|
138
|
-
|
|
139
|
-
MediaSource.isTypeSupported = (mimeType) => {
|
|
140
|
-
// Parse the basic MIME type from its parameters.
|
|
141
|
-
const pieces = mimeType.split(/ *; */);
|
|
142
|
-
const basicMimeType = pieces[0];
|
|
143
|
-
const container = basicMimeType.split('/')[1];
|
|
144
|
-
|
|
145
|
-
if (container.toLowerCase() == 'mp2t') {
|
|
146
|
-
return false;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
return originalIsTypeSupported(mimeType);
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
125
|
/**
|
|
154
126
|
* Patch |MediaSource.isTypeSupported| to always reject |codec|. This is used
|
|
155
127
|
* when we know that we are on a platform that does not work well with a given
|
|
@@ -49,6 +49,8 @@ shaka.polyfill.PatchedMediaKeysNop = class {
|
|
|
49
49
|
// These are not usable, but allow Player.isBrowserSupported to pass.
|
|
50
50
|
window.MediaKeys = PatchedMediaKeysNop.MediaKeys;
|
|
51
51
|
window.MediaKeySystemAccess = PatchedMediaKeysNop.MediaKeySystemAccess;
|
|
52
|
+
|
|
53
|
+
window.shakaMediaKeysPolyfill = true;
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
/**
|
|
@@ -72,6 +72,8 @@ shaka.polyfill.PatchedMediaKeysWebkit = class {
|
|
|
72
72
|
PatchedMediaKeysWebkit.setMediaKeys;
|
|
73
73
|
window.MediaKeys = PatchedMediaKeysWebkit.MediaKeys;
|
|
74
74
|
window.MediaKeySystemAccess = PatchedMediaKeysWebkit.MediaKeySystemAccess;
|
|
75
|
+
|
|
76
|
+
window.shakaMediaKeysPolyfill = true;
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
/**
|
package/lib/text/cue.js
CHANGED
|
@@ -27,6 +27,14 @@ shaka.text.SbvTextParser = class {
|
|
|
27
27
|
goog.asserts.assert(false, 'SubViewer does not have init segments');
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
/**
|
|
31
|
+
* @override
|
|
32
|
+
* @export
|
|
33
|
+
*/
|
|
34
|
+
setSequenceMode(sequenceMode) {
|
|
35
|
+
// Unused.
|
|
36
|
+
}
|
|
37
|
+
|
|
30
38
|
/**
|
|
31
39
|
* @override
|
|
32
40
|
* @export
|
|
@@ -12,7 +12,6 @@
|
|
|
12
12
|
goog.provide('shaka.text.SimpleTextDisplayer');
|
|
13
13
|
|
|
14
14
|
goog.require('goog.asserts');
|
|
15
|
-
goog.require('shaka.Deprecate');
|
|
16
15
|
goog.require('shaka.log');
|
|
17
16
|
goog.require('shaka.text.Cue');
|
|
18
17
|
|
|
@@ -108,12 +107,7 @@ shaka.text.SimpleTextDisplayer = class {
|
|
|
108
107
|
return `${acc}</${tag}>`;
|
|
109
108
|
}, '');
|
|
110
109
|
|
|
111
|
-
if (cue.lineBreak
|
|
112
|
-
if (cue.spacer) {
|
|
113
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
114
|
-
'shaka.extern.Cue',
|
|
115
|
-
'Please use lineBreak instead of spacer.');
|
|
116
|
-
}
|
|
110
|
+
if (cue.lineBreak) {
|
|
117
111
|
// This is a vertical lineBreak, so insert a newline.
|
|
118
112
|
return '\n';
|
|
119
113
|
} else if (cue.nestedCues.length) {
|
package/lib/text/text_engine.js
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
goog.provide('shaka.text.TextEngine');
|
|
8
8
|
|
|
9
9
|
goog.require('goog.asserts');
|
|
10
|
+
goog.require('shaka.log');
|
|
10
11
|
goog.require('shaka.text.Cue');
|
|
11
12
|
goog.require('shaka.util.BufferUtils');
|
|
12
|
-
goog.require('shaka.util.Functional');
|
|
13
13
|
goog.require('shaka.util.IDestroyable');
|
|
14
14
|
goog.require('shaka.util.MimeUtils');
|
|
15
15
|
goog.requireType('shaka.cea.ICaptionDecoder');
|
|
@@ -30,6 +30,9 @@ shaka.text.TextEngine = class {
|
|
|
30
30
|
/** @private {shaka.extern.TextDisplayer} */
|
|
31
31
|
this.displayer_ = displayer;
|
|
32
32
|
|
|
33
|
+
/** @private {boolean} */
|
|
34
|
+
this.segmentRelativeVttTiming_ = false;
|
|
35
|
+
|
|
33
36
|
/** @private {number} */
|
|
34
37
|
this.timestampOffset_ = 0;
|
|
35
38
|
|
|
@@ -128,8 +131,10 @@ shaka.text.TextEngine = class {
|
|
|
128
131
|
* called at least once before appendBuffer.
|
|
129
132
|
*
|
|
130
133
|
* @param {string} mimeType
|
|
134
|
+
* @param {boolean} sequenceMode
|
|
135
|
+
* @param {boolean} segmentRelativeVttTiming
|
|
131
136
|
*/
|
|
132
|
-
initParser(mimeType) {
|
|
137
|
+
initParser(mimeType, sequenceMode, segmentRelativeVttTiming) {
|
|
133
138
|
// No parser for CEA, which is extracted from video and side-loaded
|
|
134
139
|
// into TextEngine and TextDisplayer.
|
|
135
140
|
if (mimeType == shaka.util.MimeUtils.CEA608_CLOSED_CAPTION_MIMETYPE ||
|
|
@@ -140,7 +145,14 @@ shaka.text.TextEngine = class {
|
|
|
140
145
|
const factory = shaka.text.TextEngine.parserMap_[mimeType];
|
|
141
146
|
goog.asserts.assert(
|
|
142
147
|
factory, 'Text type negotiation should have happened already');
|
|
143
|
-
this.parser_ =
|
|
148
|
+
this.parser_ = factory();
|
|
149
|
+
if (this.parser_.setSequenceMode) {
|
|
150
|
+
this.parser_.setSequenceMode(sequenceMode);
|
|
151
|
+
} else {
|
|
152
|
+
shaka.log.alwaysWarn(
|
|
153
|
+
'Text parsers should have a "setSequenceMode" method!');
|
|
154
|
+
}
|
|
155
|
+
this.segmentRelativeVttTiming_ = segmentRelativeVttTiming;
|
|
144
156
|
}
|
|
145
157
|
|
|
146
158
|
/**
|
|
@@ -166,11 +178,15 @@ shaka.text.TextEngine = class {
|
|
|
166
178
|
return;
|
|
167
179
|
}
|
|
168
180
|
|
|
181
|
+
const vttOffset = this.segmentRelativeVttTiming_ ?
|
|
182
|
+
startTime : this.timestampOffset_;
|
|
183
|
+
|
|
169
184
|
/** @type {shaka.extern.TextParser.TimeContext} **/
|
|
170
185
|
const time = {
|
|
171
186
|
periodStart: this.timestampOffset_,
|
|
172
187
|
segmentStart: startTime,
|
|
173
188
|
segmentEnd: endTime,
|
|
189
|
+
vttOffset: vttOffset,
|
|
174
190
|
};
|
|
175
191
|
|
|
176
192
|
// Parse the buffer and add the new cues.
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
goog.provide('shaka.text.UITextDisplayer');
|
|
9
9
|
|
|
10
10
|
goog.require('goog.asserts');
|
|
11
|
-
goog.require('shaka.Deprecate');
|
|
12
11
|
goog.require('shaka.text.Cue');
|
|
13
12
|
goog.require('shaka.text.CueRegion');
|
|
14
13
|
goog.require('shaka.util.Dom');
|
|
@@ -343,12 +342,7 @@ shaka.text.UITextDisplayer = class {
|
|
|
343
342
|
createCue_(cue, parents) {
|
|
344
343
|
const isNested = parents.length > 1;
|
|
345
344
|
let type = isNested ? 'span' : 'div';
|
|
346
|
-
if (cue.lineBreak
|
|
347
|
-
if (cue.spacer) {
|
|
348
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
349
|
-
'shaka.extern.Cue',
|
|
350
|
-
'Please use lineBreak instead of spacer.');
|
|
351
|
-
}
|
|
345
|
+
if (cue.lineBreak) {
|
|
352
346
|
type = 'br';
|
|
353
347
|
}
|
|
354
348
|
|