shaka-player 3.3.4 → 4.0.0
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/workflows/build-and-test.yaml +0 -1
- package/.github/workflows/demo-version-index.yaml +8 -0
- package/.github/workflows/release-please.yaml +23 -2
- package/.github/workflows/selenium-lab-tests.yaml +0 -1
- 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 +198 -32
- package/CONTRIBUTORS +1 -0
- package/README.md +10 -7
- 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/README.md +2 -2
- package/build/compiler.py +1 -1
- package/build/generateTsDefs.py +0 -2
- package/build/shaka-lab.yaml +0 -2
- package/build/test.py +7 -1
- package/build/types/core +0 -1
- 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_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 +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 +16 -20
- package/dist/locales.js +31 -29
- 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 +78 -83
- package/dist/shaka-player.compiled.debug.d.ts +78 -83
- package/dist/shaka-player.compiled.debug.externs.js +126 -126
- package/dist/shaka-player.compiled.debug.js +426 -483
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +126 -126
- package/dist/shaka-player.compiled.js +838 -856
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +80 -83
- package/dist/shaka-player.ui.debug.d.ts +80 -83
- package/dist/shaka-player.ui.debug.externs.js +134 -126
- package/dist/shaka-player.ui.debug.js +488 -543
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +134 -126
- package/dist/shaka-player.ui.js +980 -994
- 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 +83 -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 -32
- package/externs/shaka/text.js +12 -12
- package/externs/sourcebuffer.js +15 -0
- 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 -1
- package/lib/hls/hls_parser.js +378 -743
- package/lib/hls/manifest_text_parser.js +2 -3
- package/lib/media/drm_engine.js +102 -53
- package/lib/media/gap_jumping_controller.js +10 -45
- package/lib/media/media_source_engine.js +87 -15
- 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 +29 -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 +100 -132
- 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 +24 -2
- 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 +2 -0
- package/lib/util/platform.js +45 -0
- package/lib/util/player_configuration.js +12 -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 +1 -1
- package/roadmap.md +19 -19
- package/shaka-player.uncompiled.js +0 -3
- package/test/cast/cast_utils_unit.js +1 -0
- package/test/dash/dash_parser_content_protection_unit.js +44 -0
- package/test/dash/dash_parser_manifest_unit.js +0 -24
- 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 +99 -220
- 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 +26 -3
- package/test/media/media_source_engine_unit.js +7 -6
- package/test/media/playhead_unit.js +27 -191
- package/test/media/segment_index_unit.js +15 -25
- package/test/media/streaming_engine_integration.js +4 -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 +55 -57
- 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 +3 -3
- 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/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/lib/util/mutex.js +0 -52
- 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
|
|
@@ -576,8 +559,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
576
559
|
this.adManager_ = null;
|
|
577
560
|
|
|
578
561
|
if (shaka.Player.adManagerFactory_) {
|
|
579
|
-
this.adManager_ =
|
|
580
|
-
shaka.util.Functional.callFactory(shaka.Player.adManagerFactory_);
|
|
562
|
+
this.adManager_ = shaka.Player.adManagerFactory_();
|
|
581
563
|
}
|
|
582
564
|
|
|
583
565
|
// If the browser comes back online after being offline, then try to play
|
|
@@ -847,10 +829,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
847
829
|
return false;
|
|
848
830
|
}
|
|
849
831
|
|
|
850
|
-
// We do not support iOS 9, 10, or
|
|
851
|
-
// Safari.
|
|
832
|
+
// We do not support iOS 9, 10, 11 or 12, nor those same versions of
|
|
833
|
+
// desktop Safari.
|
|
852
834
|
const safariVersion = shaka.util.Platform.safariVersion();
|
|
853
|
-
if (safariVersion && safariVersion <
|
|
835
|
+
if (safariVersion && safariVersion < 13) {
|
|
854
836
|
return false;
|
|
855
837
|
}
|
|
856
838
|
|
|
@@ -1560,8 +1542,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1560
1542
|
// text displayer and streaming engine are always in sync, wait until they
|
|
1561
1543
|
// are both initialized before setting the initial value.
|
|
1562
1544
|
const textDisplayerFactory = this.config_.textDisplayFactory;
|
|
1563
|
-
const textDisplayer =
|
|
1564
|
-
shaka.util.Functional.callFactory(textDisplayerFactory);
|
|
1545
|
+
const textDisplayer = textDisplayerFactory();
|
|
1565
1546
|
this.lastTextFactory_ = textDisplayerFactory;
|
|
1566
1547
|
|
|
1567
1548
|
const mediaSourceEngine = this.createMediaSourceEngine(
|
|
@@ -1571,6 +1552,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1571
1552
|
(metadata, offset, endTime) => {
|
|
1572
1553
|
this.processTimedMetadataMediaSrc_(metadata, offset, endTime);
|
|
1573
1554
|
});
|
|
1555
|
+
const {segmentRelativeVttTiming} = this.config_.manifest;
|
|
1556
|
+
mediaSourceEngine.setSegmentRelativeVttTiming(segmentRelativeVttTiming);
|
|
1574
1557
|
|
|
1575
1558
|
// Wait for media source engine to finish opening. This promise should
|
|
1576
1559
|
// NEVER be rejected as per the media source engine implementation.
|
|
@@ -1632,7 +1615,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1632
1615
|
this.config_.manifest.retryParameters,
|
|
1633
1616
|
has.mimeType);
|
|
1634
1617
|
goog.asserts.assert(this.parserFactory_, 'Must have manifest parser');
|
|
1635
|
-
this.parser_ =
|
|
1618
|
+
this.parser_ = this.parserFactory_();
|
|
1636
1619
|
|
|
1637
1620
|
const manifestConfig =
|
|
1638
1621
|
shaka.util.ObjectUtils.cloneObject(this.config_.manifest);
|
|
@@ -1918,13 +1901,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1918
1901
|
const abrFactory = this.config_.abrFactory;
|
|
1919
1902
|
if (!this.abrManager_ || this.abrManagerFactory_ != abrFactory) {
|
|
1920
1903
|
this.abrManagerFactory_ = abrFactory;
|
|
1921
|
-
this.abrManager_ =
|
|
1922
|
-
if (typeof this.abrManager_.playbackRateChanged != 'function') {
|
|
1923
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
1924
|
-
'AbrManager',
|
|
1925
|
-
'Please use an AbrManager with playbackRateChanged function.');
|
|
1926
|
-
this.abrManager_.playbackRateChanged = (rate) => {};
|
|
1927
|
-
}
|
|
1904
|
+
this.abrManager_ = abrFactory();
|
|
1928
1905
|
this.abrManager_.configure(this.config_.abr);
|
|
1929
1906
|
}
|
|
1930
1907
|
|
|
@@ -2683,8 +2660,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2683
2660
|
this.manifest_,
|
|
2684
2661
|
this.config_.streaming,
|
|
2685
2662
|
startTime,
|
|
2686
|
-
() => this.onSeek_()
|
|
2687
|
-
(event) => this.dispatchEvent(event));
|
|
2663
|
+
() => this.onSeek_());
|
|
2688
2664
|
}
|
|
2689
2665
|
|
|
2690
2666
|
/**
|
|
@@ -2943,17 +2919,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2943
2919
|
|
|
2944
2920
|
goog.asserts.assert(typeof(config) == 'object', 'Should be an object!');
|
|
2945
2921
|
|
|
2946
|
-
// Deprecate 'manifest.dash.defaultPresentationDelay' configuration.
|
|
2947
|
-
if (config['manifest'] && config['manifest']['dash'] &&
|
|
2948
|
-
'defaultPresentationDelay' in config['manifest']['dash']) {
|
|
2949
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
2950
|
-
'manifest.dash.defaultPresentationDelay configuration',
|
|
2951
|
-
'Please Use manifest.defaultPresentationDelay instead.');
|
|
2952
|
-
config['manifest']['defaultPresentationDelay'] =
|
|
2953
|
-
config['manifest']['dash']['defaultPresentationDelay'];
|
|
2954
|
-
delete config['manifest']['dash']['defaultPresentationDelay'];
|
|
2955
|
-
}
|
|
2956
|
-
|
|
2957
2922
|
// If lowLatencyMode is enabled, and inaccurateManifestTolerance and
|
|
2958
2923
|
// rebufferingGoal are not specified, set inaccurateManifestTolerance to 0
|
|
2959
2924
|
// and rebufferingGoal to 0.01 by default for low latency streaming.
|
|
@@ -3020,10 +2985,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3020
2985
|
}
|
|
3021
2986
|
|
|
3022
2987
|
if (this.mediaSourceEngine_) {
|
|
2988
|
+
const {segmentRelativeVttTiming} = this.config_.manifest;
|
|
2989
|
+
this.mediaSourceEngine_.setSegmentRelativeVttTiming(
|
|
2990
|
+
segmentRelativeVttTiming);
|
|
2991
|
+
|
|
3023
2992
|
const textDisplayerFactory = this.config_.textDisplayFactory;
|
|
3024
2993
|
if (this.lastTextFactory_ != textDisplayerFactory) {
|
|
3025
|
-
const displayer =
|
|
3026
|
-
shaka.util.Functional.callFactory(textDisplayerFactory);
|
|
2994
|
+
const displayer = textDisplayerFactory();
|
|
3027
2995
|
this.mediaSourceEngine_.setTextDisplayer(displayer);
|
|
3028
2996
|
this.lastTextFactory_ = textDisplayerFactory;
|
|
3029
2997
|
|
|
@@ -4408,158 +4376,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4408
4376
|
return this.stats_.getBlob();
|
|
4409
4377
|
}
|
|
4410
4378
|
|
|
4411
|
-
/**
|
|
4412
|
-
* Adds the given text track to the loaded manifest. <code>load()</code> must
|
|
4413
|
-
* resolve before calling. The presentation must have a duration.
|
|
4414
|
-
*
|
|
4415
|
-
* This returns the created track, which can immediately be selected by the
|
|
4416
|
-
* application. The track will not be automatically selected.
|
|
4417
|
-
*
|
|
4418
|
-
* @param {string} uri
|
|
4419
|
-
* @param {string} language
|
|
4420
|
-
* @param {string} kind
|
|
4421
|
-
* @param {string=} mimeType
|
|
4422
|
-
* @param {string=} codec
|
|
4423
|
-
* @param {string=} label
|
|
4424
|
-
* @param {boolean=} forced
|
|
4425
|
-
* @return {shaka.extern.Track}
|
|
4426
|
-
* @export
|
|
4427
|
-
*/
|
|
4428
|
-
addTextTrack(uri, language, kind, mimeType, codec, label, forced = false) {
|
|
4429
|
-
shaka.Deprecate.deprecateFeature(4,
|
|
4430
|
-
'addTextTrack',
|
|
4431
|
-
'Please use an addTextTrackAsync.');
|
|
4432
|
-
if (this.loadMode_ != shaka.Player.LoadMode.MEDIA_SOURCE &&
|
|
4433
|
-
this.loadMode_ != shaka.Player.LoadMode.SRC_EQUALS) {
|
|
4434
|
-
shaka.log.error(
|
|
4435
|
-
'Must call load() and wait for it to resolve before adding text ' +
|
|
4436
|
-
'tracks.');
|
|
4437
|
-
throw new shaka.util.Error(
|
|
4438
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4439
|
-
shaka.util.Error.Category.PLAYER,
|
|
4440
|
-
shaka.util.Error.Code.CONTENT_NOT_LOADED);
|
|
4441
|
-
}
|
|
4442
|
-
|
|
4443
|
-
if (!mimeType) {
|
|
4444
|
-
// Try using the uri extension.
|
|
4445
|
-
const extension = shaka.media.ManifestParser.getExtension(uri);
|
|
4446
|
-
mimeType = shaka.Player.TEXT_EXTENSIONS_TO_MIME_TYPES_[extension];
|
|
4447
|
-
|
|
4448
|
-
if (!mimeType) {
|
|
4449
|
-
shaka.log.error(
|
|
4450
|
-
'The mimeType has not been provided and it could not be deduced ' +
|
|
4451
|
-
'from its extension.');
|
|
4452
|
-
throw new shaka.util.Error(
|
|
4453
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4454
|
-
shaka.util.Error.Category.TEXT,
|
|
4455
|
-
shaka.util.Error.Code.TEXT_COULD_NOT_GUESS_MIME_TYPE,
|
|
4456
|
-
extension);
|
|
4457
|
-
}
|
|
4458
|
-
}
|
|
4459
|
-
|
|
4460
|
-
if (this.loadMode_ == shaka.Player.LoadMode.SRC_EQUALS) {
|
|
4461
|
-
if (mimeType != 'text/vtt') {
|
|
4462
|
-
shaka.log.error('Only WebVTT is supported when using src=');
|
|
4463
|
-
throw new shaka.util.Error(
|
|
4464
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4465
|
-
shaka.util.Error.Category.TEXT,
|
|
4466
|
-
shaka.util.Error.Code.TEXT_ONLY_WEBVTT_SRC_EQUALS,
|
|
4467
|
-
mimeType);
|
|
4468
|
-
}
|
|
4469
|
-
if (forced) {
|
|
4470
|
-
// See: https://github.com/whatwg/html/issues/4472
|
|
4471
|
-
kind = 'forced';
|
|
4472
|
-
}
|
|
4473
|
-
const trackElement =
|
|
4474
|
-
/** @type {!HTMLTrackElement} */(document.createElement('track'));
|
|
4475
|
-
trackElement.src = this.cmcdManager_.appendTextTrackData(uri);
|
|
4476
|
-
trackElement.label = label || '';
|
|
4477
|
-
trackElement.kind = kind;
|
|
4478
|
-
trackElement.srclang = language;
|
|
4479
|
-
// Because we're pulling in the text track file via Javascript, the
|
|
4480
|
-
// same-origin policy applies. If you'd like to have a player served
|
|
4481
|
-
// from one domain, but the text track served from another, you'll
|
|
4482
|
-
// need to enable CORS in order to do so. In addition to enabling CORS
|
|
4483
|
-
// on the server serving the text tracks, you will need to add the
|
|
4484
|
-
// crossorigin attribute to the video element itself.
|
|
4485
|
-
if (!this.video_.getAttribute('crossorigin')) {
|
|
4486
|
-
this.video_.setAttribute('crossorigin', 'anonymous');
|
|
4487
|
-
}
|
|
4488
|
-
this.video_.appendChild(trackElement);
|
|
4489
|
-
const textTracks = this.getTextTracks();
|
|
4490
|
-
const srcTrack = textTracks.find((t) => {
|
|
4491
|
-
return t.language == language &&
|
|
4492
|
-
t.label == (label || '') &&
|
|
4493
|
-
t.kind == kind;
|
|
4494
|
-
});
|
|
4495
|
-
if (srcTrack) {
|
|
4496
|
-
this.onTracksChanged_();
|
|
4497
|
-
return srcTrack;
|
|
4498
|
-
}
|
|
4499
|
-
// This should not happen, but there are browser implementations that may
|
|
4500
|
-
// not support the Track element.
|
|
4501
|
-
shaka.log.error('Cannot add this text when loaded with src=');
|
|
4502
|
-
throw new shaka.util.Error(
|
|
4503
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4504
|
-
shaka.util.Error.Category.TEXT,
|
|
4505
|
-
shaka.util.Error.Code.CANNOT_ADD_EXTERNAL_TEXT_TO_SRC_EQUALS);
|
|
4506
|
-
}
|
|
4507
|
-
|
|
4508
|
-
const ContentType = shaka.util.ManifestParserUtils.ContentType;
|
|
4509
|
-
|
|
4510
|
-
const duration = this.manifest_.presentationTimeline.getDuration();
|
|
4511
|
-
if (duration == Infinity) {
|
|
4512
|
-
throw new shaka.util.Error(
|
|
4513
|
-
shaka.util.Error.Severity.RECOVERABLE,
|
|
4514
|
-
shaka.util.Error.Category.MANIFEST,
|
|
4515
|
-
shaka.util.Error.Code.CANNOT_ADD_EXTERNAL_TEXT_TO_LIVE_STREAM);
|
|
4516
|
-
}
|
|
4517
|
-
|
|
4518
|
-
/** @type {shaka.extern.Stream} */
|
|
4519
|
-
const stream = {
|
|
4520
|
-
id: this.nextExternalStreamId_++,
|
|
4521
|
-
originalId: null,
|
|
4522
|
-
createSegmentIndex: () => Promise.resolve(),
|
|
4523
|
-
segmentIndex: shaka.media.SegmentIndex.forSingleSegment(
|
|
4524
|
-
/* startTime= */ 0,
|
|
4525
|
-
/* duration= */ duration,
|
|
4526
|
-
/* uris= */ [uri]),
|
|
4527
|
-
mimeType: mimeType || '',
|
|
4528
|
-
codecs: codec || '',
|
|
4529
|
-
kind: kind,
|
|
4530
|
-
encrypted: false,
|
|
4531
|
-
drmInfos: [],
|
|
4532
|
-
keyIds: new Set(),
|
|
4533
|
-
language: language,
|
|
4534
|
-
label: label || null,
|
|
4535
|
-
type: ContentType.TEXT,
|
|
4536
|
-
primary: false,
|
|
4537
|
-
trickModeVideo: null,
|
|
4538
|
-
emsgSchemeIdUris: null,
|
|
4539
|
-
roles: [],
|
|
4540
|
-
forced: !!forced,
|
|
4541
|
-
channelsCount: null,
|
|
4542
|
-
audioSamplingRate: null,
|
|
4543
|
-
spatialAudio: false,
|
|
4544
|
-
closedCaptions: null,
|
|
4545
|
-
};
|
|
4546
|
-
|
|
4547
|
-
const fullMimeType = shaka.util.MimeUtils.getFullType(
|
|
4548
|
-
stream.mimeType, stream.codecs);
|
|
4549
|
-
const supported = shaka.text.TextEngine.isTypeSupported(fullMimeType);
|
|
4550
|
-
if (!supported) {
|
|
4551
|
-
throw new shaka.util.Error(
|
|
4552
|
-
shaka.util.Error.Severity.CRITICAL,
|
|
4553
|
-
shaka.util.Error.Category.TEXT,
|
|
4554
|
-
shaka.util.Error.Code.MISSING_TEXT_PLUGIN,
|
|
4555
|
-
mimeType);
|
|
4556
|
-
}
|
|
4557
|
-
|
|
4558
|
-
this.manifest_.textStreams.push(stream);
|
|
4559
|
-
this.onTracksChanged_();
|
|
4560
|
-
return shaka.util.StreamUtils.textStreamToTrack(stream);
|
|
4561
|
-
}
|
|
4562
|
-
|
|
4563
4379
|
/**
|
|
4564
4380
|
* Adds the given text track to the loaded manifest. <code>load()</code> must
|
|
4565
4381
|
* resolve before calling. The presentation must have a duration.
|
|
@@ -4864,6 +4680,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4864
4680
|
periodStart: 0,
|
|
4865
4681
|
segmentStart: 0,
|
|
4866
4682
|
segmentEnd: this.video_.duration,
|
|
4683
|
+
vttOffset: 0,
|
|
4867
4684
|
};
|
|
4868
4685
|
const data = shaka.util.BufferUtils.toUint8(buffer);
|
|
4869
4686
|
const cues = obj.parseMedia(data, time);
|
|
@@ -6516,7 +6333,6 @@ shaka.Player.EventName = {
|
|
|
6516
6333
|
Emsg: 'emsg',
|
|
6517
6334
|
Error: 'error',
|
|
6518
6335
|
ExpirationUpdated: 'expirationupdated',
|
|
6519
|
-
LargeGap: 'largegap',
|
|
6520
6336
|
Loaded: 'loaded',
|
|
6521
6337
|
Loading: 'loading',
|
|
6522
6338
|
ManifestParsed: 'manifestparsed',
|
|
@@ -6576,7 +6392,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6576
6392
|
* @define {string} A version number taken from git at compile time.
|
|
6577
6393
|
* @export
|
|
6578
6394
|
*/
|
|
6579
|
-
shaka.Player.version = '
|
|
6395
|
+
shaka.Player.version = 'v4.0.0-uncompiled';
|
|
6580
6396
|
|
|
6581
6397
|
// Initialize the deprecation system using the version string we just set
|
|
6582
6398
|
// 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
|
|