shaka-player 4.11.13 → 4.12.1
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/README.md +47 -0
- package/dist/deps.js +8 -8
- package/dist/locales.js +35 -35
- package/dist/shaka-player.compiled.d.ts +36 -13
- package/dist/shaka-player.compiled.debug.d.ts +36 -13
- package/dist/shaka-player.compiled.debug.externs.js +46 -11
- package/dist/shaka-player.compiled.debug.js +543 -517
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +46 -11
- package/dist/shaka-player.compiled.js +1348 -1331
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.d.ts +37 -14
- package/dist/shaka-player.ui.debug.d.ts +37 -14
- package/dist/shaka-player.ui.debug.externs.js +46 -11
- package/dist/shaka-player.ui.debug.js +629 -598
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +46 -11
- package/dist/shaka-player.ui.js +1624 -1603
- package/dist/shaka-player.ui.map +4 -4
- package/externs/shaka/ads.js +9 -0
- package/externs/shaka/manifest.js +26 -1
- package/externs/shaka/offline.js +8 -2
- package/externs/shaka/player.js +80 -28
- package/externs/shaka/text.js +9 -0
- package/lib/ads/ad_manager.js +6 -0
- package/lib/ads/ad_utils.js +1 -0
- package/lib/ads/client_side_ad.js +8 -0
- package/lib/ads/interstitial_ad.js +25 -4
- package/lib/ads/interstitial_ad_manager.js +67 -8
- package/lib/ads/media_tailor_ad.js +8 -0
- package/lib/ads/server_side_ad.js +8 -0
- package/lib/dash/content_protection.js +31 -0
- package/lib/dash/dash_parser.js +22 -12
- package/lib/hls/hls_parser.js +63 -49
- package/lib/media/adaptation_set.js +11 -17
- package/lib/media/adaptation_set_criteria.js +4 -9
- package/lib/media/drm_engine.js +3 -1
- package/lib/media/manifest_filterer.js +2 -1
- package/lib/media/media_source_engine.js +286 -20
- package/lib/media/playhead.js +3 -1
- package/lib/media/preload_manager.js +10 -7
- package/lib/media/segment_prefetch.js +32 -13
- package/lib/media/segment_reference.js +3 -3
- package/lib/media/streaming_engine.js +87 -261
- package/lib/mss/mss_parser.js +1 -0
- package/lib/offline/download_info.js +5 -1
- package/lib/offline/indexeddb/storage_mechanism.js +4 -3
- package/lib/offline/indexeddb/v1_storage_cell.js +2 -0
- package/lib/offline/indexeddb/v2_storage_cell.js +2 -0
- package/lib/offline/manifest_converter.js +4 -0
- package/lib/offline/storage.js +277 -5
- package/lib/player.js +224 -78
- package/lib/text/simple_text_displayer.js +7 -0
- package/lib/text/stub_text_displayer.js +7 -0
- package/lib/text/ui_text_displayer.js +12 -0
- package/lib/util/dom_utils.js +14 -0
- package/lib/util/error.js +5 -0
- package/lib/util/periods.js +2 -0
- package/lib/util/platform.js +15 -0
- package/lib/util/player_configuration.js +11 -4
- package/lib/util/stream_utils.js +20 -1
- package/package.json +1 -1
- package/ui/ad_statistics_button.js +12 -0
- package/ui/controls.js +31 -7
- package/ui/externs/ui.js +8 -1
- package/ui/fullscreen_button.js +9 -0
- package/ui/locales/be.json +49 -0
- package/ui/mute_button.js +42 -11
- package/ui/skip_ad_button.js +16 -11
- package/ui/statistics_button.js +12 -0
- package/ui/ui.js +10 -5
package/lib/player.js
CHANGED
|
@@ -556,6 +556,18 @@ goog.requireType('shaka.media.PresentationTimeline');
|
|
|
556
556
|
*/
|
|
557
557
|
|
|
558
558
|
|
|
559
|
+
/**
|
|
560
|
+
* @event shaka.Player.ProducerReferenceTimeEvent
|
|
561
|
+
* @description Fired when the content includes ProducerReferenceTime (PRFT)
|
|
562
|
+
* info.
|
|
563
|
+
* @property {string} type
|
|
564
|
+
* 'prft'
|
|
565
|
+
* @property {shaka.extern.ProducerReferenceTime} detail
|
|
566
|
+
* An object which contains the content of the PRFT box.
|
|
567
|
+
* @exportDoc
|
|
568
|
+
*/
|
|
569
|
+
|
|
570
|
+
|
|
559
571
|
/**
|
|
560
572
|
* @summary The main player object for Shaka Player.
|
|
561
573
|
*
|
|
@@ -786,7 +798,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
786
798
|
this.config_.preferredAudioLabel,
|
|
787
799
|
this.config_.preferredVideoLabel,
|
|
788
800
|
this.config_.mediaSource.codecSwitchingStrategy,
|
|
789
|
-
this.config_.manifest.dash.enableAudioGroups,
|
|
790
801
|
/* audioCodec= */ '');
|
|
791
802
|
|
|
792
803
|
/** @private {string} */
|
|
@@ -1447,16 +1458,17 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1447
1458
|
if (this.video_) {
|
|
1448
1459
|
// Remove all track nodes
|
|
1449
1460
|
shaka.util.Dom.removeAllChildren(this.video_);
|
|
1450
|
-
}
|
|
1451
1461
|
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
this.video_.
|
|
1459
|
-
|
|
1462
|
+
// In order to unload a media element, we need to remove the src
|
|
1463
|
+
// attribute and then load again. When we destroy media source engine,
|
|
1464
|
+
// this will be done for us, but for src=, we need to do it here.
|
|
1465
|
+
//
|
|
1466
|
+
// DrmEngine requires this to be done before we destroy DrmEngine
|
|
1467
|
+
// itself.
|
|
1468
|
+
if (this.video_.src) {
|
|
1469
|
+
this.video_.removeAttribute('src');
|
|
1470
|
+
this.video_.load();
|
|
1471
|
+
}
|
|
1460
1472
|
}
|
|
1461
1473
|
|
|
1462
1474
|
if (this.drmEngine_) {
|
|
@@ -1780,6 +1792,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1780
1792
|
startTimeOfLoad, prefetchedVariant, segmentPrefetchById);
|
|
1781
1793
|
}, 'loadInner_');
|
|
1782
1794
|
preloadManager.stopQueuingLatePhaseQueuedOperations();
|
|
1795
|
+
|
|
1796
|
+
if (this.mimeType_ && shaka.util.Platform.isSafari() &&
|
|
1797
|
+
shaka.util.MimeUtils.isHlsType(this.mimeType_)) {
|
|
1798
|
+
this.mediaSourceEngine_.addSecondarySource(
|
|
1799
|
+
this.assetUri_, this.mimeType_);
|
|
1800
|
+
}
|
|
1783
1801
|
}
|
|
1784
1802
|
this.dispatchEvent(shaka.Player.makeEvent_(
|
|
1785
1803
|
shaka.util.FakeEvent.EventName.Loaded));
|
|
@@ -2059,7 +2077,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2059
2077
|
// Avoid having to detect the resolution again if it has already been
|
|
2060
2078
|
// detected or set
|
|
2061
2079
|
if (this.maxHwRes_.width == Infinity &&
|
|
2062
|
-
this.maxHwRes_.height == Infinity
|
|
2080
|
+
this.maxHwRes_.height == Infinity &&
|
|
2081
|
+
!this.config_.ignoreHardwareResolution) {
|
|
2063
2082
|
const maxResolution =
|
|
2064
2083
|
await shaka.util.Platform.detectMaxHardwareResolution();
|
|
2065
2084
|
this.maxHwRes_.width = maxResolution.width;
|
|
@@ -2395,6 +2414,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2395
2414
|
|
|
2396
2415
|
this.makeStateChangeEvent_('media-source');
|
|
2397
2416
|
|
|
2417
|
+
// Remove children if we had any, i.e. from previously used src= mode.
|
|
2418
|
+
this.video_.removeAttribute('src');
|
|
2419
|
+
shaka.util.Dom.removeAllChildren(this.video_);
|
|
2420
|
+
|
|
2398
2421
|
this.createTextDisplayer_();
|
|
2399
2422
|
goog.asserts.assert(this.textDisplayer_,
|
|
2400
2423
|
'Text displayer should be created already');
|
|
@@ -2406,6 +2429,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2406
2429
|
onMetadata: (metadata, offset, endTime) => {
|
|
2407
2430
|
this.processTimedMetadataMediaSrc_(metadata, offset, endTime);
|
|
2408
2431
|
},
|
|
2432
|
+
onEvent: (event) => this.dispatchEvent(event),
|
|
2433
|
+
onManifestUpdate: () => this.onManifestUpdate_(),
|
|
2409
2434
|
},
|
|
2410
2435
|
this.lcevcDec_);
|
|
2411
2436
|
mediaSourceEngine.configure(this.config_.mediaSource);
|
|
@@ -2690,6 +2715,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2690
2715
|
// text.
|
|
2691
2716
|
if (initialTextStream && this.shouldStreamText_()) {
|
|
2692
2717
|
this.streamingEngine_.switchTextStream(initialTextStream);
|
|
2718
|
+
this.setTextDisplayerLanguage_();
|
|
2693
2719
|
}
|
|
2694
2720
|
}
|
|
2695
2721
|
|
|
@@ -2866,6 +2892,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2866
2892
|
external: false,
|
|
2867
2893
|
fastSwitching: false,
|
|
2868
2894
|
fullMimeTypes: new Set(),
|
|
2895
|
+
isAudioMuxedInVideo: false,
|
|
2869
2896
|
};
|
|
2870
2897
|
stream.fullMimeTypes.add(shaka.util.MimeUtils.getFullType(
|
|
2871
2898
|
stream.mimeType, stream.codecs));
|
|
@@ -2991,12 +3018,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
2991
3018
|
playbackUri += ',' + this.config_.playRangeEnd;
|
|
2992
3019
|
}
|
|
2993
3020
|
}
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
mediaElement.disableRemotePlayback = false;
|
|
3021
|
+
|
|
3022
|
+
if (this.mediaSourceEngine_ ) {
|
|
3023
|
+
await this.mediaSourceEngine_.destroy();
|
|
3024
|
+
this.mediaSourceEngine_ = null;
|
|
2999
3025
|
}
|
|
3026
|
+
shaka.util.Dom.removeAllChildren(mediaElement);
|
|
3027
|
+
|
|
3028
|
+
mediaElement.src = playbackUri;
|
|
3000
3029
|
|
|
3001
3030
|
// Tizen 3 / WebOS won't load anything unless you call load() explicitly,
|
|
3002
3031
|
// no matter the value of the preload attribute. This is harmful on some
|
|
@@ -3740,7 +3769,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3740
3769
|
netEngine: this.networkingEngine_,
|
|
3741
3770
|
onError: (error) => this.onError_(error),
|
|
3742
3771
|
onEvent: (event) => this.dispatchEvent(event),
|
|
3743
|
-
onManifestUpdate: () => this.onManifestUpdate_(),
|
|
3744
3772
|
onSegmentAppended: (reference, stream) => {
|
|
3745
3773
|
this.onSegmentAppended_(
|
|
3746
3774
|
reference.startTime, reference.endTime, stream.type,
|
|
@@ -3755,9 +3783,6 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3755
3783
|
beforeAppendSegment: (contentType, segment) => {
|
|
3756
3784
|
return this.drmEngine_.parseInbandPssh(contentType, segment);
|
|
3757
3785
|
},
|
|
3758
|
-
onMetadata: (metadata, offset, endTime) => {
|
|
3759
|
-
this.processTimedMetadataMediaSrc_(metadata, offset, endTime);
|
|
3760
|
-
},
|
|
3761
3786
|
disableStream: (stream, time) => this.disableStream(stream, time),
|
|
3762
3787
|
};
|
|
3763
3788
|
|
|
@@ -3970,6 +3995,33 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3970
3995
|
delete config['manifest']['hls']['useSafariBehaviorForLive'];
|
|
3971
3996
|
}
|
|
3972
3997
|
|
|
3998
|
+
// Deprecate 'streaming.parsePrftBox' configuration.
|
|
3999
|
+
if (config['streaming'] && 'parsePrftBox' in config['streaming']) {
|
|
4000
|
+
shaka.Deprecate.deprecateFeature(5,
|
|
4001
|
+
'streaming.parsePrftBox configuration',
|
|
4002
|
+
'Now fired without needing a configuration.');
|
|
4003
|
+
delete config['streaming']['parsePrftBox'];
|
|
4004
|
+
}
|
|
4005
|
+
|
|
4006
|
+
// Deprecate 'manifest.dash.enableAudioGroups' configuration.
|
|
4007
|
+
if (config['manifest'] && config['manifest']['dash'] &&
|
|
4008
|
+
'enableAudioGroups' in config['manifest']['dash']) {
|
|
4009
|
+
shaka.Deprecate.deprecateFeature(5,
|
|
4010
|
+
'manifest.dash.enableAudioGroups configuration',
|
|
4011
|
+
'It is now enabled by default and cannot be disabled.');
|
|
4012
|
+
delete config['manifest']['dash']['enableAudioGroups'];
|
|
4013
|
+
}
|
|
4014
|
+
|
|
4015
|
+
// Deprecate 'streaming.dispatchAllEmsgBoxes' configuration.
|
|
4016
|
+
if (config['streaming'] && 'dispatchAllEmsgBoxes' in config['streaming']) {
|
|
4017
|
+
shaka.Deprecate.deprecateFeature(5,
|
|
4018
|
+
'streaming.dispatchAllEmsgBoxes configuration',
|
|
4019
|
+
'Please Use mediaSource.dispatchAllEmsgBoxes instead.');
|
|
4020
|
+
config['mediaSource']['dispatchAllEmsgBoxes'] =
|
|
4021
|
+
config['streaming']['dispatchAllEmsgBoxes'];
|
|
4022
|
+
delete config['streaming']['dispatchAllEmsgBoxes'];
|
|
4023
|
+
}
|
|
4024
|
+
|
|
3973
4025
|
// If lowLatencyMode is enabled, and inaccurateManifestTolerance and
|
|
3974
4026
|
// rebufferingGoal and segmentPrefetchLimit and baseDelay and
|
|
3975
4027
|
// autoCorrectDrift and maxDisabledTime are not specified, set
|
|
@@ -4107,6 +4159,11 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4107
4159
|
'Text displayer w/ configure',
|
|
4108
4160
|
'Text displayer should have a "configure" method!');
|
|
4109
4161
|
}
|
|
4162
|
+
if (!this.textDisplayer_.setTextLanguage) {
|
|
4163
|
+
shaka.Deprecate.deprecateFeature(5,
|
|
4164
|
+
'Text displayer w/ setTextLanguage',
|
|
4165
|
+
'Text displayer should have a "setTextLanguage" method!');
|
|
4166
|
+
}
|
|
4110
4167
|
this.textDisplayer_.setTextVisibility(oldDisplayer.isTextVisible());
|
|
4111
4168
|
oldDisplayer.destroy();
|
|
4112
4169
|
if (this.mediaSourceEngine_) {
|
|
@@ -4946,12 +5003,14 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4946
5003
|
* @export
|
|
4947
5004
|
*/
|
|
4948
5005
|
selectTextTrack(track) {
|
|
4949
|
-
|
|
5006
|
+
const selectMediaSourceMode = () => {
|
|
4950
5007
|
const stream = this.manifest_.textStreams.find(
|
|
4951
5008
|
(stream) => stream.id == track.id);
|
|
4952
5009
|
|
|
4953
5010
|
if (!stream) {
|
|
4954
|
-
|
|
5011
|
+
if (!this.isRemotePlayback()) {
|
|
5012
|
+
shaka.log.error('No stream with id', track.id);
|
|
5013
|
+
}
|
|
4955
5014
|
return;
|
|
4956
5015
|
}
|
|
4957
5016
|
|
|
@@ -4964,30 +5023,48 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4964
5023
|
this.addTextStreamToSwitchHistory_(stream, /* fromAdaptation= */ false);
|
|
4965
5024
|
this.streamingEngine_.switchTextStream(stream);
|
|
4966
5025
|
this.onTextChanged_();
|
|
5026
|
+
this.setTextDisplayerLanguage_();
|
|
4967
5027
|
|
|
4968
5028
|
// Workaround for
|
|
4969
5029
|
// https://github.com/shaka-project/shaka-player/issues/1299
|
|
4970
5030
|
// When track is selected, back-propagate the language to
|
|
4971
5031
|
// currentTextLanguage_.
|
|
4972
5032
|
this.currentTextLanguage_ = stream.language;
|
|
4973
|
-
}
|
|
4974
|
-
|
|
4975
|
-
|
|
4976
|
-
|
|
4977
|
-
|
|
4978
|
-
|
|
4979
|
-
|
|
4980
|
-
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
5033
|
+
};
|
|
5034
|
+
const selectSrcEqualsMode = () => {
|
|
5035
|
+
if (this.video_ && this.video_.textTracks) {
|
|
5036
|
+
const textTracks = this.getFilteredTextTracks_();
|
|
5037
|
+
const oldTrack = textTracks.find((textTrack) =>
|
|
5038
|
+
textTrack.mode !== 'disabled');
|
|
5039
|
+
const newTrack = textTracks.find((textTrack) =>
|
|
5040
|
+
shaka.util.StreamUtils.html5TrackId(textTrack) === track.id);
|
|
5041
|
+
if (!newTrack) {
|
|
5042
|
+
shaka.log.error('No track with id', track.id);
|
|
5043
|
+
return;
|
|
4984
5044
|
}
|
|
4985
|
-
if (newTrack) {
|
|
4986
|
-
|
|
5045
|
+
if (oldTrack !== newTrack) {
|
|
5046
|
+
if (oldTrack) {
|
|
5047
|
+
oldTrack.mode = 'disabled';
|
|
5048
|
+
this.loadEventManager_.unlisten(oldTrack, 'cuechange');
|
|
5049
|
+
this.textDisplayer_.remove(0, Infinity);
|
|
5050
|
+
}
|
|
5051
|
+
if (newTrack) {
|
|
5052
|
+
this.enableNativeTrack_(newTrack);
|
|
5053
|
+
}
|
|
4987
5054
|
}
|
|
5055
|
+
this.onTextChanged_();
|
|
5056
|
+
this.setTextDisplayerLanguage_();
|
|
5057
|
+
}
|
|
5058
|
+
};
|
|
5059
|
+
if (this.manifest_ && this.playhead_) {
|
|
5060
|
+
selectMediaSourceMode();
|
|
5061
|
+
// When using MSE + remote we need to set tracks for both MSE and native
|
|
5062
|
+
// apis so that synchronization is maintained.
|
|
5063
|
+
if (!this.isRemotePlayback()) {
|
|
5064
|
+
return;
|
|
4988
5065
|
}
|
|
4989
|
-
this.onTextChanged_();
|
|
4990
5066
|
}
|
|
5067
|
+
selectSrcEqualsMode();
|
|
4991
5068
|
}
|
|
4992
5069
|
|
|
4993
5070
|
/**
|
|
@@ -5037,11 +5114,13 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5037
5114
|
* @export
|
|
5038
5115
|
*/
|
|
5039
5116
|
selectVariantTrack(track, clearBuffer = false, safeMargin = 0) {
|
|
5040
|
-
|
|
5117
|
+
const selectMediaSourceMode = () => {
|
|
5041
5118
|
const variant = this.manifest_.variants.find(
|
|
5042
5119
|
(variant) => variant.id == track.id);
|
|
5043
5120
|
if (!variant) {
|
|
5044
|
-
|
|
5121
|
+
if (!this.isRemotePlayback()) {
|
|
5122
|
+
shaka.log.error('No variant with id', track.id);
|
|
5123
|
+
}
|
|
5045
5124
|
return;
|
|
5046
5125
|
}
|
|
5047
5126
|
|
|
@@ -5065,8 +5144,15 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5065
5144
|
'calling selectVariantTrack().');
|
|
5066
5145
|
}
|
|
5067
5146
|
|
|
5068
|
-
this.
|
|
5069
|
-
|
|
5147
|
+
if (this.isRemotePlayback()) {
|
|
5148
|
+
this.switchVariant_(
|
|
5149
|
+
variant, /* fromAdaptation= */ false,
|
|
5150
|
+
/* clearBuffer= */ false, /* safeMargin= */ 0);
|
|
5151
|
+
} else {
|
|
5152
|
+
this.switchVariant_(
|
|
5153
|
+
variant, /* fromAdaptation= */ false,
|
|
5154
|
+
clearBuffer || false, safeMargin || 0);
|
|
5155
|
+
}
|
|
5070
5156
|
|
|
5071
5157
|
// Workaround for
|
|
5072
5158
|
// https://github.com/shaka-project/shaka-player/issues/1299
|
|
@@ -5074,23 +5160,34 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5074
5160
|
// currentAudioLanguage_.
|
|
5075
5161
|
this.currentAdaptationSetCriteria_ = new shaka.media.ExampleBasedCriteria(
|
|
5076
5162
|
variant,
|
|
5077
|
-
this.config_.mediaSource.codecSwitchingStrategy
|
|
5078
|
-
this.config_.manifest.dash.enableAudioGroups);
|
|
5163
|
+
this.config_.mediaSource.codecSwitchingStrategy);
|
|
5079
5164
|
|
|
5080
5165
|
// Update AbrManager variants to match these new settings.
|
|
5081
5166
|
this.updateAbrManagerVariants_();
|
|
5082
|
-
}
|
|
5083
|
-
|
|
5084
|
-
|
|
5085
|
-
|
|
5086
|
-
|
|
5087
|
-
|
|
5088
|
-
|
|
5089
|
-
|
|
5090
|
-
|
|
5167
|
+
};
|
|
5168
|
+
const selectSrcEqualsMode = () => {
|
|
5169
|
+
if (this.video_ && this.video_.audioTracks) {
|
|
5170
|
+
// Safari's native HLS won't let you choose an explicit variant, though
|
|
5171
|
+
// you can choose audio languages this way.
|
|
5172
|
+
const audioTracks = Array.from(this.video_.audioTracks);
|
|
5173
|
+
for (const audioTrack of audioTracks) {
|
|
5174
|
+
if (shaka.util.StreamUtils.html5TrackId(audioTrack) == track.id) {
|
|
5175
|
+
// This will reset the "enabled" of other tracks to false.
|
|
5176
|
+
this.switchHtml5Track_(audioTrack);
|
|
5177
|
+
return;
|
|
5178
|
+
}
|
|
5091
5179
|
}
|
|
5092
5180
|
}
|
|
5181
|
+
};
|
|
5182
|
+
if (this.manifest_ && this.playhead_) {
|
|
5183
|
+
selectMediaSourceMode();
|
|
5184
|
+
// When using MSE + remote we need to set tracks for both MSE and native
|
|
5185
|
+
// apis so that synchronization is maintained.
|
|
5186
|
+
if (!this.isRemotePlayback()) {
|
|
5187
|
+
return;
|
|
5188
|
+
}
|
|
5093
5189
|
}
|
|
5190
|
+
selectSrcEqualsMode();
|
|
5094
5191
|
}
|
|
5095
5192
|
|
|
5096
5193
|
/**
|
|
@@ -5151,20 +5248,19 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5151
5248
|
*/
|
|
5152
5249
|
selectAudioLanguage(language, role, channelsCount = 0, safeMargin = 0,
|
|
5153
5250
|
codec = '') {
|
|
5154
|
-
|
|
5251
|
+
const selectMediaSourceMode = () => {
|
|
5155
5252
|
this.currentAdaptationSetCriteria_ =
|
|
5156
5253
|
new shaka.media.PreferenceBasedCriteria(
|
|
5157
5254
|
language,
|
|
5158
5255
|
role || '',
|
|
5159
|
-
channelsCount,
|
|
5256
|
+
channelsCount || 0,
|
|
5160
5257
|
/* hdrLevel= */ '',
|
|
5161
5258
|
/* spatialAudio= */ false,
|
|
5162
5259
|
/* videoLayout= */ '',
|
|
5163
5260
|
/* audioLabel= */ '',
|
|
5164
5261
|
/* videoLabel= */ '',
|
|
5165
5262
|
this.config_.mediaSource.codecSwitchingStrategy,
|
|
5166
|
-
|
|
5167
|
-
codec);
|
|
5263
|
+
codec || '');
|
|
5168
5264
|
|
|
5169
5265
|
const diff = (a, b) => {
|
|
5170
5266
|
if (!a.video && !b.video) {
|
|
@@ -5198,19 +5294,32 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5198
5294
|
}
|
|
5199
5295
|
if (bestVariant) {
|
|
5200
5296
|
const track = shaka.util.StreamUtils.variantToTrack(bestVariant);
|
|
5201
|
-
this.selectVariantTrack(
|
|
5297
|
+
this.selectVariantTrack(
|
|
5298
|
+
track, /* clearBuffer= */ true, safeMargin || 0);
|
|
5202
5299
|
return;
|
|
5203
5300
|
}
|
|
5204
5301
|
|
|
5205
5302
|
// If we haven't switched yet, just use ABR to find a new track.
|
|
5206
5303
|
this.chooseVariantAndSwitch_();
|
|
5207
|
-
}
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5304
|
+
};
|
|
5305
|
+
const selectSrcEqualsMode = () => {
|
|
5306
|
+
if (this.video_ && this.video_.audioTracks) {
|
|
5307
|
+
const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
|
|
5308
|
+
this.getVariantTracks(), language, role || '', false)[0];
|
|
5309
|
+
if (track) {
|
|
5310
|
+
this.selectVariantTrack(track);
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
};
|
|
5314
|
+
if (this.manifest_ && this.playhead_) {
|
|
5315
|
+
selectMediaSourceMode();
|
|
5316
|
+
// When using MSE + remote we need to set tracks for both MSE and native
|
|
5317
|
+
// apis so that synchronization is maintained.
|
|
5318
|
+
if (!this.isRemotePlayback()) {
|
|
5319
|
+
return;
|
|
5212
5320
|
}
|
|
5213
5321
|
}
|
|
5322
|
+
selectSrcEqualsMode();
|
|
5214
5323
|
}
|
|
5215
5324
|
|
|
5216
5325
|
/**
|
|
@@ -5224,10 +5333,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5224
5333
|
* @export
|
|
5225
5334
|
*/
|
|
5226
5335
|
selectTextLanguage(language, role, forced = false) {
|
|
5227
|
-
|
|
5336
|
+
const selectMediaSourceMode = () => {
|
|
5228
5337
|
this.currentTextLanguage_ = language;
|
|
5229
5338
|
this.currentTextRole_ = role || '';
|
|
5230
|
-
this.currentTextForced_ = forced;
|
|
5339
|
+
this.currentTextForced_ = forced || false;
|
|
5231
5340
|
|
|
5232
5341
|
const chosenText = this.chooseTextStream_();
|
|
5233
5342
|
if (chosenText) {
|
|
@@ -5241,15 +5350,26 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5241
5350
|
if (this.shouldStreamText_()) {
|
|
5242
5351
|
this.streamingEngine_.switchTextStream(chosenText);
|
|
5243
5352
|
this.onTextChanged_();
|
|
5353
|
+
this.setTextDisplayerLanguage_();
|
|
5244
5354
|
}
|
|
5245
5355
|
}
|
|
5246
|
-
}
|
|
5356
|
+
};
|
|
5357
|
+
const selectSrcEqualsMode = () => {
|
|
5247
5358
|
const track = shaka.util.StreamUtils.filterStreamsByLanguageAndRole(
|
|
5248
|
-
this.getTextTracks(), language, role || '', forced)[0];
|
|
5359
|
+
this.getTextTracks(), language, role || '', forced || false)[0];
|
|
5249
5360
|
if (track) {
|
|
5250
5361
|
this.selectTextTrack(track);
|
|
5251
5362
|
}
|
|
5363
|
+
};
|
|
5364
|
+
if (this.manifest_ && this.playhead_) {
|
|
5365
|
+
selectMediaSourceMode();
|
|
5366
|
+
// When using MSE + remote we need to set tracks for both MSE and native
|
|
5367
|
+
// apis so that synchronization is maintained.
|
|
5368
|
+
if (!this.isRemotePlayback()) {
|
|
5369
|
+
return;
|
|
5370
|
+
}
|
|
5252
5371
|
}
|
|
5372
|
+
selectSrcEqualsMode();
|
|
5253
5373
|
}
|
|
5254
5374
|
|
|
5255
5375
|
/**
|
|
@@ -5267,7 +5387,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5267
5387
|
* @export
|
|
5268
5388
|
*/
|
|
5269
5389
|
selectVariantsByLabel(label, clearBuffer = true, safeMargin = 0) {
|
|
5270
|
-
|
|
5390
|
+
const selectMediaSourceMode = () => {
|
|
5271
5391
|
let firstVariantWithLabel = null;
|
|
5272
5392
|
for (const variant of this.manifest_.variants) {
|
|
5273
5393
|
if (variant.audio.label == label) {
|
|
@@ -5297,24 +5417,35 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5297
5417
|
label,
|
|
5298
5418
|
/* videoLabel= */ '',
|
|
5299
5419
|
this.config_.mediaSource.codecSwitchingStrategy,
|
|
5300
|
-
this.config_.manifest.dash.enableAudioGroups,
|
|
5301
5420
|
/* audioCodec= */ '');
|
|
5302
5421
|
|
|
5303
5422
|
this.chooseVariantAndSwitch_(clearBuffer, safeMargin);
|
|
5304
|
-
}
|
|
5305
|
-
|
|
5423
|
+
};
|
|
5424
|
+
const selectSrcEqualsMode = () => {
|
|
5425
|
+
if (this.video_ && this.video_.audioTracks) {
|
|
5426
|
+
const audioTracks = Array.from(this.video_.audioTracks);
|
|
5306
5427
|
|
|
5307
|
-
|
|
5428
|
+
let trackMatch = null;
|
|
5308
5429
|
|
|
5309
|
-
|
|
5310
|
-
|
|
5311
|
-
|
|
5430
|
+
for (const audioTrack of audioTracks) {
|
|
5431
|
+
if (audioTrack.label == label) {
|
|
5432
|
+
trackMatch = audioTrack;
|
|
5433
|
+
}
|
|
5434
|
+
}
|
|
5435
|
+
if (trackMatch) {
|
|
5436
|
+
this.switchHtml5Track_(trackMatch);
|
|
5312
5437
|
}
|
|
5313
5438
|
}
|
|
5314
|
-
|
|
5315
|
-
|
|
5439
|
+
};
|
|
5440
|
+
if (this.manifest_ && this.playhead_) {
|
|
5441
|
+
selectMediaSourceMode();
|
|
5442
|
+
// When using MSE + remote we need to set tracks for both MSE and native
|
|
5443
|
+
// apis so that synchronization is maintained.
|
|
5444
|
+
if (!this.isRemotePlayback()) {
|
|
5445
|
+
return;
|
|
5316
5446
|
}
|
|
5317
5447
|
}
|
|
5448
|
+
selectSrcEqualsMode();
|
|
5318
5449
|
}
|
|
5319
5450
|
|
|
5320
5451
|
/**
|
|
@@ -5345,7 +5476,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5345
5476
|
* @export
|
|
5346
5477
|
*/
|
|
5347
5478
|
getChaptersTracks() {
|
|
5348
|
-
if (this.video_ && this.video_.
|
|
5479
|
+
if (this.video_ && this.video_.currentSrc && this.video_.textTracks) {
|
|
5349
5480
|
const textTracks = this.getChaptersTracks_();
|
|
5350
5481
|
const StreamUtils = shaka.util.StreamUtils;
|
|
5351
5482
|
return textTracks.map((text) => StreamUtils.html5TextTrackToTrack(text));
|
|
@@ -5362,7 +5493,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5362
5493
|
* @export
|
|
5363
5494
|
*/
|
|
5364
5495
|
getChapters(language) {
|
|
5365
|
-
if (!this.video_ || !this.video_.
|
|
5496
|
+
if (!this.video_ || !this.video_.currentSrc || !this.video_.textTracks) {
|
|
5366
5497
|
return [];
|
|
5367
5498
|
}
|
|
5368
5499
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
@@ -5484,6 +5615,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5484
5615
|
if (streams.length > 0) {
|
|
5485
5616
|
this.streamingEngine_.switchTextStream(streams[0]);
|
|
5486
5617
|
this.onTextChanged_();
|
|
5618
|
+
this.setTextDisplayerLanguage_();
|
|
5487
5619
|
}
|
|
5488
5620
|
}
|
|
5489
5621
|
} else {
|
|
@@ -5857,6 +5989,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
5857
5989
|
fastSwitching: false,
|
|
5858
5990
|
fullMimeTypes: new Set([shaka.util.MimeUtils.getFullType(
|
|
5859
5991
|
mimeType || '', codec || '')]),
|
|
5992
|
+
isAudioMuxedInVideo: false,
|
|
5860
5993
|
};
|
|
5861
5994
|
|
|
5862
5995
|
const fullMimeType = shaka.util.MimeUtils.getFullType(
|
|
@@ -6022,6 +6155,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6022
6155
|
fastSwitching: false,
|
|
6023
6156
|
fullMimeTypes: new Set([shaka.util.MimeUtils.getFullType(
|
|
6024
6157
|
segmentMimeType || '', '')]),
|
|
6158
|
+
isAudioMuxedInVideo: false,
|
|
6025
6159
|
};
|
|
6026
6160
|
|
|
6027
6161
|
if (this.loadMode_ == shaka.Player.LoadMode.SRC_EQUALS) {
|
|
@@ -6507,6 +6641,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
6507
6641
|
fastSwitching: false,
|
|
6508
6642
|
fullMimeTypes: new Set([shaka.util.MimeUtils.getFullType(
|
|
6509
6643
|
mimeType, '')]),
|
|
6644
|
+
isAudioMuxedInVideo: false,
|
|
6510
6645
|
};
|
|
6511
6646
|
manifest.textStreams.push(textStream);
|
|
6512
6647
|
closedCaptionsSet.add(id);
|
|
@@ -7415,6 +7550,17 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
7415
7550
|
shaka.util.FakeEvent.EventName.AbrStatusChanged, data));
|
|
7416
7551
|
}
|
|
7417
7552
|
|
|
7553
|
+
/**
|
|
7554
|
+
* @private
|
|
7555
|
+
*/
|
|
7556
|
+
setTextDisplayerLanguage_() {
|
|
7557
|
+
const activeTextTrack = this.getTextTracks().find((t) => t.active);
|
|
7558
|
+
if (activeTextTrack &&
|
|
7559
|
+
this.textDisplayer_ && this.textDisplayer_.setTextLanguage) {
|
|
7560
|
+
this.textDisplayer_.setTextLanguage(activeTextTrack.language);
|
|
7561
|
+
}
|
|
7562
|
+
}
|
|
7563
|
+
|
|
7418
7564
|
/**
|
|
7419
7565
|
* @param {boolean} updateAbrManager
|
|
7420
7566
|
* @private
|
|
@@ -8123,7 +8269,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
8123
8269
|
* @export
|
|
8124
8270
|
*/
|
|
8125
8271
|
// eslint-disable-next-line no-useless-concat, max-len
|
|
8126
|
-
shaka.Player.version = 'v4.
|
|
8272
|
+
shaka.Player.version = 'v4.12.1' + '-uncompiled'; // x-release-please-version
|
|
8127
8273
|
|
|
8128
8274
|
// Initialize the deprecation system using the version string we just set
|
|
8129
8275
|
// on the player.
|
|
@@ -189,6 +189,13 @@ shaka.text.SimpleTextDisplayer = class {
|
|
|
189
189
|
this.textTrack_.mode = on ? 'showing' : 'hidden';
|
|
190
190
|
}
|
|
191
191
|
|
|
192
|
+
/**
|
|
193
|
+
* @override
|
|
194
|
+
* @export
|
|
195
|
+
*/
|
|
196
|
+
setTextLanguage(language) {
|
|
197
|
+
}
|
|
198
|
+
|
|
192
199
|
/**
|
|
193
200
|
* Iterate over all the cues in a text track and remove all those for which
|
|
194
201
|
* |predicate(cue)| returns true.
|
|
@@ -258,6 +258,18 @@ shaka.text.UITextDisplayer = class {
|
|
|
258
258
|
this.updateCaptions_(/* forceUpdate= */ true);
|
|
259
259
|
}
|
|
260
260
|
|
|
261
|
+
/**
|
|
262
|
+
* @override
|
|
263
|
+
* @export
|
|
264
|
+
*/
|
|
265
|
+
setTextLanguage(language) {
|
|
266
|
+
if (language && language != 'und') {
|
|
267
|
+
this.textContainer_.setAttribute('lang', language);
|
|
268
|
+
} else {
|
|
269
|
+
this.textContainer_.setAttribute('lang', '');
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
261
273
|
/**
|
|
262
274
|
* @private
|
|
263
275
|
*/
|
package/lib/util/dom_utils.js
CHANGED
|
@@ -42,6 +42,20 @@ shaka.util.Dom = class {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* @param {string} url
|
|
47
|
+
* @param {string=} mimeType
|
|
48
|
+
* @return {!HTMLSourceElement}
|
|
49
|
+
*/
|
|
50
|
+
static createSourceElement(url, mimeType = '') {
|
|
51
|
+
const source =
|
|
52
|
+
/** @type {HTMLSourceElement} */ (document.createElement('source'));
|
|
53
|
+
source.src = url;
|
|
54
|
+
source.type = mimeType;
|
|
55
|
+
return source;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
45
59
|
/**
|
|
46
60
|
* Cast a Node/Element to an HTMLElement
|
|
47
61
|
*
|
package/lib/util/error.js
CHANGED
|
@@ -784,6 +784,11 @@ shaka.util.Error.Code = {
|
|
|
784
784
|
*/
|
|
785
785
|
'HLS_EMPTY_MEDIA_PLAYLIST': 4053,
|
|
786
786
|
|
|
787
|
+
/**
|
|
788
|
+
* We do not support playing encrypted content with MSE
|
|
789
|
+
* and legacy Apple MediaKeys API.
|
|
790
|
+
*/
|
|
791
|
+
'DASH_MSE_ENCRYPTED_LEGACY_APPLE_MEDIA_KEYS_NOT_SUPPORTED': 4054,
|
|
787
792
|
|
|
788
793
|
// RETIRED: 'INCONSISTENT_BUFFER_STATE': 5000,
|
|
789
794
|
// RETIRED: 'INVALID_SEGMENT_INDEX': 5001,
|