shaka-player 4.7.3 → 4.7.5
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 +3 -1
- package/dist/locales.js +32 -32
- package/dist/shaka-player.compiled.d.ts +4 -0
- package/dist/shaka-player.compiled.debug.d.ts +4 -0
- package/dist/shaka-player.compiled.debug.externs.js +5 -0
- package/dist/shaka-player.compiled.debug.js +121 -119
- package/dist/shaka-player.compiled.debug.map +3 -3
- package/dist/shaka-player.compiled.externs.js +5 -0
- package/dist/shaka-player.compiled.js +689 -687
- package/dist/shaka-player.compiled.map +3 -3
- package/dist/shaka-player.ui.d.ts +4 -0
- package/dist/shaka-player.ui.debug.d.ts +4 -0
- package/dist/shaka-player.ui.debug.externs.js +5 -0
- package/dist/shaka-player.ui.debug.js +145 -142
- package/dist/shaka-player.ui.debug.map +3 -3
- package/dist/shaka-player.ui.externs.js +5 -0
- package/dist/shaka-player.ui.js +831 -829
- package/dist/shaka-player.ui.map +3 -3
- package/lib/ads/client_side_ad.js +4 -2
- package/lib/ads/client_side_ad_manager.js +5 -3
- package/lib/cast/cast_proxy.js +18 -0
- package/lib/cea/cea608_memory.js +1 -1
- package/lib/cea/cea_decoder.js +1 -1
- package/lib/hls/hls_parser.js +16 -0
- package/lib/hls/hls_utils.js +5 -5
- package/lib/media/media_source_engine.js +4 -4
- package/lib/media/play_rate_controller.js +1 -0
- package/lib/media/presentation_timeline.js +11 -0
- package/lib/offline/session_deleter.js +0 -8
- package/lib/player.js +41 -6
- package/lib/polyfill/patchedmediakeys_apple.js +0 -6
- package/lib/text/ttml_text_parser.js +5 -0
- package/lib/text/vtt_text_parser.js +5 -0
- package/lib/util/language_utils.js +7 -8
- package/lib/util/periods.js +3 -1
- package/package.json +1 -1
- package/ui/play_button.js +17 -0
- package/ui/playback_rate_selection.js +4 -0
- package/ui/small_play_button.js +2 -2
|
@@ -155,6 +155,7 @@ shaka.ads.ClientSideAd = class {
|
|
|
155
155
|
* @export
|
|
156
156
|
*/
|
|
157
157
|
setVolume(volume) {
|
|
158
|
+
this.video_.volume = volume;
|
|
158
159
|
return this.manager_.setVolume(volume);
|
|
159
160
|
}
|
|
160
161
|
|
|
@@ -197,13 +198,14 @@ shaka.ads.ClientSideAd = class {
|
|
|
197
198
|
* @export
|
|
198
199
|
*/
|
|
199
200
|
setMuted(muted) {
|
|
201
|
+
this.video_.muted = muted;
|
|
200
202
|
// Emulate the "mute" functionality, where current, pre-mute
|
|
201
203
|
// volume is saved and can be restored on unmute.
|
|
202
204
|
if (muted) {
|
|
203
205
|
this.volume_ = this.getVolume();
|
|
204
|
-
this.setVolume(0);
|
|
206
|
+
this.manager_.setVolume(0);
|
|
205
207
|
} else {
|
|
206
|
-
this.setVolume(this.volume_);
|
|
208
|
+
this.manager_.setVolume(this.volume_);
|
|
207
209
|
}
|
|
208
210
|
}
|
|
209
211
|
|
|
@@ -234,10 +234,12 @@ shaka.ads.ClientSideAdManager = class {
|
|
|
234
234
|
videoPlayHead.currentTime = this.video_.currentTime;
|
|
235
235
|
});
|
|
236
236
|
this.eventManager_.listen(this.video_, 'volumechange', () => {
|
|
237
|
+
if (!this.ad_) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
this.ad_.setVolume(this.video_.volume);
|
|
237
241
|
if (this.video_.muted) {
|
|
238
|
-
this.
|
|
239
|
-
} else {
|
|
240
|
-
this.imaAdsManager_.setVolume(this.video_.volume);
|
|
242
|
+
this.ad_.setMuted(true);
|
|
241
243
|
}
|
|
242
244
|
});
|
|
243
245
|
}
|
package/lib/cast/cast_proxy.js
CHANGED
|
@@ -496,6 +496,16 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
|
|
|
496
496
|
startTime = this.sender_.get('video', 'currentTime');
|
|
497
497
|
}
|
|
498
498
|
|
|
499
|
+
let activeTextTrack;
|
|
500
|
+
const textTracks = this.sender_.get('player', 'getTextTracks')();
|
|
501
|
+
|
|
502
|
+
if (textTracks && textTracks.length) {
|
|
503
|
+
activeTextTrack = textTracks.find((t) => t.active);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
const isTextTrackVisible =
|
|
507
|
+
this.sender_.get('player', 'isTextTrackVisible')();
|
|
508
|
+
|
|
499
509
|
// Now load the manifest, if present.
|
|
500
510
|
if (assetUri) {
|
|
501
511
|
// Don't autoplay the content until we finish setting up initial state.
|
|
@@ -527,6 +537,14 @@ shaka.cast.CastProxy = class extends shaka.util.FakeEventTarget {
|
|
|
527
537
|
/** @type {Object} */(this.localPlayer_)[setter](value);
|
|
528
538
|
}
|
|
529
539
|
|
|
540
|
+
this.localPlayer_.setTextTrackVisibility(isTextTrackVisible);
|
|
541
|
+
if (activeTextTrack) {
|
|
542
|
+
this.localPlayer_.selectTextLanguage(
|
|
543
|
+
activeTextTrack.language,
|
|
544
|
+
activeTextTrack.roles,
|
|
545
|
+
activeTextTrack.forced);
|
|
546
|
+
}
|
|
547
|
+
|
|
530
548
|
// Restore the original autoplay setting.
|
|
531
549
|
this.localVideo_.autoplay = autoplay;
|
|
532
550
|
if (assetUri) {
|
package/lib/cea/cea608_memory.js
CHANGED
|
@@ -79,7 +79,7 @@ shaka.cea.Cea608Memory = class {
|
|
|
79
79
|
* @return {?shaka.extern.ICaptionDecoder.ClosedCaption}
|
|
80
80
|
*/
|
|
81
81
|
forceEmit(startTime, endTime) {
|
|
82
|
-
const stream = `CC${(this.fieldNum_<< 1) | this.channelNum_ +1}`;
|
|
82
|
+
const stream = `CC${((this.fieldNum_<< 1) | this.channelNum_) + 1}`;
|
|
83
83
|
const topLevelCue = new shaka.text.Cue(
|
|
84
84
|
startTime, endTime, /* payload= */ '');
|
|
85
85
|
topLevelCue.lineInterpretation =
|
package/lib/cea/cea_decoder.js
CHANGED
|
@@ -283,7 +283,7 @@ shaka.cea.CeaDecoder = class {
|
|
|
283
283
|
// Get the correct stream for this caption packet (CC1, ..., CC4)
|
|
284
284
|
const selectedChannel = fieldNum ?
|
|
285
285
|
this.currentField2Channel_ : this.currentField1Channel_;
|
|
286
|
-
const selectedMode = `CC${(fieldNum << 1) | selectedChannel + 1}`;
|
|
286
|
+
const selectedMode = `CC${((fieldNum << 1) | selectedChannel) + 1}`;
|
|
287
287
|
const selectedStream = this.cea608ModeToStream_.get(selectedMode);
|
|
288
288
|
|
|
289
289
|
// Check for bad frames (bad pairs). This can be two 0xff, two 0x00, or any
|
package/lib/hls/hls_parser.js
CHANGED
|
@@ -979,6 +979,22 @@ shaka.hls.HlsParser = class {
|
|
|
979
979
|
this.presentationTimeline_.setSegmentAvailabilityDuration(
|
|
980
980
|
segmentAvailabilityDuration);
|
|
981
981
|
}
|
|
982
|
+
|
|
983
|
+
if (!this.presentationTimeline_.isStartTimeLocked()) {
|
|
984
|
+
const streamInfos = Array.from(this.uriToStreamInfosMap_.values());
|
|
985
|
+
const activeStreamInfos =
|
|
986
|
+
streamInfos.filter((s) => s.stream.segmentIndex);
|
|
987
|
+
for (const streamInfo of activeStreamInfos) {
|
|
988
|
+
if (streamInfo.type != 'audio' && streamInfo.type != 'video') {
|
|
989
|
+
continue;
|
|
990
|
+
}
|
|
991
|
+
const firstReference = streamInfo.stream.segmentIndex.get(0);
|
|
992
|
+
if (firstReference && firstReference.syncTime) {
|
|
993
|
+
const syncTime = firstReference.syncTime;
|
|
994
|
+
this.presentationTimeline_.setPresentationStartTime(syncTime);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
}
|
|
982
998
|
} else {
|
|
983
999
|
// Use the minimum duration as the presentation duration.
|
|
984
1000
|
this.presentationTimeline_.setDuration(this.getMinDuration_());
|
package/lib/hls/hls_utils.js
CHANGED
|
@@ -47,12 +47,12 @@ shaka.hls.Utils = class {
|
|
|
47
47
|
* @return {?shaka.hls.Tag}
|
|
48
48
|
*/
|
|
49
49
|
static getFirstTagWithName(tags, name) {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
for (const tag of tags) {
|
|
51
|
+
if (tag.name === name) {
|
|
52
|
+
return tag;
|
|
53
|
+
}
|
|
53
54
|
}
|
|
54
|
-
|
|
55
|
-
return tagsWithName[0];
|
|
55
|
+
return null;
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/**
|
|
@@ -168,9 +168,6 @@ shaka.media.MediaSourceEngine = class {
|
|
|
168
168
|
|
|
169
169
|
const mediaSource = new ManagedMediaSource();
|
|
170
170
|
|
|
171
|
-
this.eventManager_.listenOnce(
|
|
172
|
-
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
173
|
-
|
|
174
171
|
this.eventManager_.listen(
|
|
175
172
|
mediaSource, 'startstreaming', () => {
|
|
176
173
|
this.streamingAllowed_ = true;
|
|
@@ -181,6 +178,9 @@ shaka.media.MediaSourceEngine = class {
|
|
|
181
178
|
this.streamingAllowed_ = false;
|
|
182
179
|
});
|
|
183
180
|
|
|
181
|
+
this.eventManager_.listenOnce(
|
|
182
|
+
mediaSource, 'sourceopen', () => this.onSourceOpen_(p));
|
|
183
|
+
|
|
184
184
|
// Correctly set when playback has begun.
|
|
185
185
|
this.eventManager_.listenOnce(this.video_, 'playing', () => {
|
|
186
186
|
this.playbackHasBegun_ = true;
|
|
@@ -1805,7 +1805,7 @@ shaka.media.MediaSourceEngine = class {
|
|
|
1805
1805
|
|
|
1806
1806
|
this.destroyer_.ensureNotDestroyed();
|
|
1807
1807
|
|
|
1808
|
-
this.eventManager_.listenOnce(this.video_, '
|
|
1808
|
+
this.eventManager_.listenOnce(this.video_, 'canplaythrough', () => {
|
|
1809
1809
|
this.destroyer_.ensureNotDestroyed();
|
|
1810
1810
|
|
|
1811
1811
|
this.video_.autoplay = previousAutoPlayState;
|
|
@@ -328,6 +328,17 @@ shaka.media.PresentationTimeline = class {
|
|
|
328
328
|
}
|
|
329
329
|
|
|
330
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Returns if the presentation timeline's start time is locked.
|
|
333
|
+
*
|
|
334
|
+
* @return {boolean}
|
|
335
|
+
* @export
|
|
336
|
+
*/
|
|
337
|
+
isStartTimeLocked() {
|
|
338
|
+
return this.startTimeLocked_;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
|
|
331
342
|
/**
|
|
332
343
|
* Gives PresentationTimeline a Stream's minimum segment start time.
|
|
333
344
|
*
|
|
@@ -71,14 +71,6 @@ shaka.offline.SessionDeleter = class {
|
|
|
71
71
|
return [];
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
try {
|
|
75
|
-
await drmEngine.setServerCertificate();
|
|
76
|
-
} catch (e) {
|
|
77
|
-
shaka.log.warning('Error setting server certificate', e);
|
|
78
|
-
await drmEngine.destroy();
|
|
79
|
-
return [];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
74
|
/** @type {!Array.<string>} */
|
|
83
75
|
const sessionIds = [];
|
|
84
76
|
await Promise.all(bucket.sessionIds.map(async (sessionId) => {
|
package/lib/player.js
CHANGED
|
@@ -550,6 +550,12 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
550
550
|
*/
|
|
551
551
|
this.loadEventManager_ = new shaka.util.EventManager();
|
|
552
552
|
|
|
553
|
+
/**
|
|
554
|
+
* For listeners scoped to the lifetime of the loaded content.
|
|
555
|
+
* @private {shaka.util.EventManager}
|
|
556
|
+
*/
|
|
557
|
+
this.trickPlayEventManager_ = new shaka.util.EventManager();
|
|
558
|
+
|
|
553
559
|
/** @private {shaka.net.NetworkingEngine} */
|
|
554
560
|
this.networkingEngine_ = null;
|
|
555
561
|
|
|
@@ -848,6 +854,10 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
848
854
|
this.loadEventManager_.release();
|
|
849
855
|
this.loadEventManager_ = null;
|
|
850
856
|
}
|
|
857
|
+
if (this.trickPlayEventManager_) {
|
|
858
|
+
this.trickPlayEventManager_.release();
|
|
859
|
+
this.trickPlayEventManager_ = null;
|
|
860
|
+
}
|
|
851
861
|
|
|
852
862
|
this.abrManagerFactory_ = null;
|
|
853
863
|
this.config_ = null;
|
|
@@ -1166,6 +1176,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
1166
1176
|
// element.
|
|
1167
1177
|
if (this.video_) {
|
|
1168
1178
|
this.loadEventManager_.removeAll();
|
|
1179
|
+
this.trickPlayEventManager_.removeAll();
|
|
1169
1180
|
}
|
|
1170
1181
|
|
|
1171
1182
|
// Stop the variant checker timer
|
|
@@ -3569,6 +3580,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3569
3580
|
shaka.log.alwaysWarn('A trick play rate of 0 is unsupported!');
|
|
3570
3581
|
return;
|
|
3571
3582
|
}
|
|
3583
|
+
this.trickPlayEventManager_.removeAll();
|
|
3572
3584
|
|
|
3573
3585
|
if (this.video_.paused) {
|
|
3574
3586
|
// Our fast forward is implemented with playbackRate and needs the video
|
|
@@ -3582,6 +3594,22 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3582
3594
|
this.abrManager_.playbackRateChanged(rate);
|
|
3583
3595
|
this.streamingEngine_.setTrickPlay(Math.abs(rate) > 1);
|
|
3584
3596
|
}
|
|
3597
|
+
if (this.isLive()) {
|
|
3598
|
+
this.trickPlayEventManager_.listen(this.video_, 'timeupdate', () => {
|
|
3599
|
+
const currentTime = this.video_.currentTime;
|
|
3600
|
+
const seekRange = this.seekRange();
|
|
3601
|
+
const safeSeekOffset = this.config_.streaming.safeSeekOffset;
|
|
3602
|
+
if (rate > 0) {
|
|
3603
|
+
if (currentTime >= seekRange.end) {
|
|
3604
|
+
this.cancelTrickPlay();
|
|
3605
|
+
}
|
|
3606
|
+
} else {
|
|
3607
|
+
if (currentTime <= (seekRange.start + safeSeekOffset)) {
|
|
3608
|
+
this.cancelTrickPlay();
|
|
3609
|
+
}
|
|
3610
|
+
}
|
|
3611
|
+
});
|
|
3612
|
+
}
|
|
3585
3613
|
}
|
|
3586
3614
|
|
|
3587
3615
|
/**
|
|
@@ -3601,6 +3629,7 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
3601
3629
|
this.abrManager_.playbackRateChanged(defaultPlaybackRate);
|
|
3602
3630
|
this.streamingEngine_.setTrickPlay(false);
|
|
3603
3631
|
}
|
|
3632
|
+
this.trickPlayEventManager_.removeAll();
|
|
3604
3633
|
}
|
|
3605
3634
|
|
|
3606
3635
|
/**
|
|
@@ -4837,12 +4866,18 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4837
4866
|
|
|
4838
4867
|
const references = [];
|
|
4839
4868
|
for (const cue of cues) {
|
|
4840
|
-
|
|
4841
|
-
|
|
4869
|
+
let uris = null;
|
|
4870
|
+
const getUris = () => {
|
|
4871
|
+
if (uris == null) {
|
|
4872
|
+
uris = shaka.util.ManifestParserUtils.resolveUris(
|
|
4873
|
+
[uri], [cue.payload]);
|
|
4874
|
+
}
|
|
4875
|
+
return uris || [];
|
|
4876
|
+
};
|
|
4842
4877
|
const reference = new shaka.media.SegmentReference(
|
|
4843
4878
|
cue.startTime,
|
|
4844
4879
|
cue.endTime,
|
|
4845
|
-
|
|
4880
|
+
getUris,
|
|
4846
4881
|
/* startByte= */ 0,
|
|
4847
4882
|
/* endByte= */ null,
|
|
4848
4883
|
/* initSegmentReference= */ null,
|
|
@@ -4850,8 +4885,8 @@ shaka.Player = class extends shaka.util.FakeEventTarget {
|
|
|
4850
4885
|
/* appendWindowStart= */ 0,
|
|
4851
4886
|
/* appendWindowEnd= */ Infinity,
|
|
4852
4887
|
);
|
|
4853
|
-
if (
|
|
4854
|
-
const spriteInfo =
|
|
4888
|
+
if (cue.payload.includes('#xywh')) {
|
|
4889
|
+
const spriteInfo = cue.payload.split('#xywh=')[1].split(',');
|
|
4855
4890
|
if (spriteInfo.length === 4) {
|
|
4856
4891
|
reference.setThumbnailSprite({
|
|
4857
4892
|
height: parseInt(spriteInfo[3], 10),
|
|
@@ -6865,7 +6900,7 @@ shaka.Player.TYPICAL_BUFFERING_THRESHOLD_ = 0.5;
|
|
|
6865
6900
|
* @export
|
|
6866
6901
|
*/
|
|
6867
6902
|
// eslint-disable-next-line no-useless-concat
|
|
6868
|
-
shaka.Player.version = 'v4.7.
|
|
6903
|
+
shaka.Player.version = 'v4.7.5' + '-uncompiled'; // x-release-please-version
|
|
6869
6904
|
|
|
6870
6905
|
// Initialize the deprecation system using the version string we just set
|
|
6871
6906
|
// on the player.
|
|
@@ -791,9 +791,3 @@ shaka.polyfill.PatchedMediaKeysApple.MediaKeyStatusMap = class {
|
|
|
791
791
|
goog.asserts.assert(false, 'Not used! Provided only for the compiler.');
|
|
792
792
|
}
|
|
793
793
|
};
|
|
794
|
-
|
|
795
|
-
if (!navigator.requestMediaKeySystemAccess ||
|
|
796
|
-
// eslint-disable-next-line no-restricted-syntax
|
|
797
|
-
!MediaKeySystemAccess.prototype.getConfiguration) {
|
|
798
|
-
shaka.polyfill.register(shaka.polyfill.PatchedMediaKeysApple.install);
|
|
799
|
-
}
|
|
@@ -491,6 +491,11 @@ shaka.text.TtmlTextParser = class {
|
|
|
491
491
|
region.viewportAnchorX = region.viewportAnchorX * 100 /
|
|
492
492
|
globalWidth;
|
|
493
493
|
}
|
|
494
|
+
} else if (!extent) {
|
|
495
|
+
region.width = 100 - region.viewportAnchorX;
|
|
496
|
+
region.widthUnits = shaka.text.CueRegion.units.PERCENTAGE;
|
|
497
|
+
region.height = 100 - region.viewportAnchorY;
|
|
498
|
+
region.heightUnits = shaka.text.CueRegion.units.PERCENTAGE;
|
|
494
499
|
}
|
|
495
500
|
|
|
496
501
|
region.viewportAnchorUnits = percentage || globalWidth != null ?
|
|
@@ -451,6 +451,11 @@ shaka.text.VttTextParser = class {
|
|
|
451
451
|
*/
|
|
452
452
|
static parseCueStyles(payload, rootCue, styles) {
|
|
453
453
|
const VttTextParser = shaka.text.VttTextParser;
|
|
454
|
+
// Optimization for unstyled payloads.
|
|
455
|
+
if (!payload.includes('<')) {
|
|
456
|
+
rootCue.payload = VttTextParser.htmlUnescape_(payload);
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
454
459
|
if (styles.size === 0) {
|
|
455
460
|
VttTextParser.addDefaultTextColor_(styles);
|
|
456
461
|
}
|
|
@@ -192,25 +192,24 @@ shaka.util.LanguageUtils = class {
|
|
|
192
192
|
const LanguageUtils = shaka.util.LanguageUtils;
|
|
193
193
|
|
|
194
194
|
const privateusePrefix = 'x-';
|
|
195
|
-
const
|
|
196
|
-
|
|
195
|
+
const [languageRegion = '', privateuseSuffix = ''] =
|
|
196
|
+
locale.split(`-${privateusePrefix}`);
|
|
197
|
+
const [languageCode = '', regionCode = ''] = languageRegion.split('-');
|
|
197
198
|
|
|
198
199
|
// We are only going to use the language, the region and the "privateuse" part (as per https://datatracker.ietf.org/doc/html/rfc5646).
|
|
199
200
|
// Anything else is thrown away.
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
const privateuse = components[1] ?
|
|
203
|
-
`${privateusePrefix}${components[1]}` : '';
|
|
201
|
+
const privateuse = privateuseSuffix ?
|
|
202
|
+
`${privateusePrefix}${privateuseSuffix}` : '';
|
|
204
203
|
|
|
205
204
|
// Convert the language to lower case. It is standard for the language code
|
|
206
205
|
// to be in lower case, but it will also make the map look-up easier.
|
|
207
|
-
language =
|
|
206
|
+
let language = languageCode.toLowerCase();
|
|
208
207
|
language = LanguageUtils.isoMap_.get(language) || language;
|
|
209
208
|
|
|
210
209
|
// Convert the region to upper case. It is standard for the region to be in
|
|
211
210
|
// upper case. If there is no upper code, then it will be an empty string
|
|
212
211
|
// and this will be a no-op.
|
|
213
|
-
region =
|
|
212
|
+
const region = regionCode.toUpperCase();
|
|
214
213
|
|
|
215
214
|
return `${region ? `${language}-${region}` : language}${
|
|
216
215
|
privateuse ? `-${privateuse}` : ''}`;
|
package/lib/util/periods.js
CHANGED
|
@@ -724,7 +724,9 @@ shaka.util.PeriodCombiner = class {
|
|
|
724
724
|
// Add the codec of this stream to the output stream's codecs.
|
|
725
725
|
const codecs = new Set(outputStream.codecs.split(','));
|
|
726
726
|
for (const codec of match.codecs.split(',')) {
|
|
727
|
-
|
|
727
|
+
if (codec) {
|
|
728
|
+
codecs.add(codec);
|
|
729
|
+
}
|
|
728
730
|
}
|
|
729
731
|
const PeriodCombiner = shaka.util.PeriodCombiner;
|
|
730
732
|
outputStream.codecs = PeriodCombiner.filterDuplicateCodecs_(
|
package/package.json
CHANGED
package/ui/play_button.js
CHANGED
|
@@ -72,6 +72,11 @@ shaka.ui.PlayButton = class extends shaka.ui.Element {
|
|
|
72
72
|
this.updateIcon();
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
+
this.eventManager.listen(this.adManager, AdManager.AD_STOPPED, () => {
|
|
76
|
+
this.updateAriaLabel();
|
|
77
|
+
this.updateIcon();
|
|
78
|
+
});
|
|
79
|
+
|
|
75
80
|
this.eventManager.listen(this.button, 'click', () => {
|
|
76
81
|
if (this.ad && this.ad.isLinear()) {
|
|
77
82
|
this.controls.playPauseAd();
|
|
@@ -99,6 +104,18 @@ shaka.ui.PlayButton = class extends shaka.ui.Element {
|
|
|
99
104
|
return this.controls.presentationIsPaused();
|
|
100
105
|
}
|
|
101
106
|
|
|
107
|
+
/**
|
|
108
|
+
* @return {boolean}
|
|
109
|
+
* @protected
|
|
110
|
+
*/
|
|
111
|
+
isEnded() {
|
|
112
|
+
if (this.ad && this.ad.isLinear()) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return this.video.ended;
|
|
117
|
+
}
|
|
118
|
+
|
|
102
119
|
/**
|
|
103
120
|
* Called when the button's aria label needs to change.
|
|
104
121
|
* To be overridden by subclasses.
|
|
@@ -44,6 +44,10 @@ shaka.ui.PlaybackRateSelection = class extends shaka.ui.SettingsMenu {
|
|
|
44
44
|
this.updateLocalizedStrings_();
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
this.eventManager.listen(this.player, 'loaded', () => {
|
|
48
|
+
this.updatePlaybackRateSelection_(this.player.getPlaybackRate());
|
|
49
|
+
});
|
|
50
|
+
|
|
47
51
|
this.eventManager.listen(this.player, 'ratechange', () => {
|
|
48
52
|
this.updatePlaybackRateSelection_(this.player.getPlaybackRate());
|
|
49
53
|
});
|
package/ui/small_play_button.js
CHANGED
|
@@ -38,7 +38,7 @@ shaka.ui.SmallPlayButton = class extends shaka.ui.PlayButton {
|
|
|
38
38
|
/** @override */
|
|
39
39
|
updateIcon() {
|
|
40
40
|
const Icons = shaka.ui.Enums.MaterialDesignIcons;
|
|
41
|
-
if (this.
|
|
41
|
+
if (this.isEnded()) {
|
|
42
42
|
this.button.textContent = Icons.REPLAY;
|
|
43
43
|
} else {
|
|
44
44
|
this.button.textContent = this.isPaused() ? Icons.PLAY : Icons.PAUSE;
|
|
@@ -48,7 +48,7 @@ shaka.ui.SmallPlayButton = class extends shaka.ui.PlayButton {
|
|
|
48
48
|
/** @override */
|
|
49
49
|
updateAriaLabel() {
|
|
50
50
|
const LocIds = shaka.ui.Locales.Ids;
|
|
51
|
-
if (this.
|
|
51
|
+
if (this.isEnded()) {
|
|
52
52
|
this.button.ariaLabel = this.localization.resolve(LocIds.REPLAY);
|
|
53
53
|
} else {
|
|
54
54
|
const label = this.isPaused() ? LocIds.PLAY : LocIds.PAUSE;
|