shaka-player 2.5.1 → 2.5.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/.csslintrc +13 -0
- package/AUTHORS +3 -0
- package/CHANGELOG.md +156 -0
- package/CONTRIBUTORS +3 -0
- package/README.md +3 -0
- package/build/README.md +5 -5
- package/build/apps.py +3 -1
- package/build/build.py +5 -2
- package/build/check.py +17 -0
- package/build/compiler.py +49 -0
- package/build/conformance.textproto +1 -0
- package/build/docs.py +0 -6
- package/build/generateExterns.js +72 -20
- package/build/install-linux-prereqs.sh +4 -4
- package/build/shakaBuildHelpers.py +7 -8
- package/build/test.py +21 -9
- package/build/types/core +1 -0
- package/build/types/ui +6 -1
- package/demo/asset_card.js +129 -41
- package/demo/cast_receiver/receiver_app.css +27 -13
- package/demo/close_button.js +10 -15
- package/demo/common/asset.js +6 -6
- package/demo/common/assets.js +72 -14
- package/demo/config.js +28 -25
- package/demo/custom.js +20 -16
- package/demo/demo.less +107 -16
- package/demo/demo_uncompiled.js +33 -0
- package/demo/demo_utils.js +4 -3
- package/demo/front.js +12 -8
- package/demo/index.html +14 -17
- package/demo/input.js +30 -23
- package/demo/input_container.js +15 -11
- package/demo/load.js +5 -7
- package/demo/main.js +138 -49
- package/demo/search.js +40 -36
- package/demo/service_worker.js +1 -1
- package/demo/tooltip.js +16 -24
- package/dist/.csslintstamp +0 -0
- package/dist/controls.css +1 -1
- package/dist/controls.css.map +1 -1
- package/dist/demo.compiled.debug.js +165 -152
- package/dist/demo.compiled.debug.map +4 -4
- package/dist/demo.compiled.js +165 -152
- package/dist/demo.compiled.map +4 -4
- package/dist/demo.css +1 -1
- package/dist/demo.css.map +1 -1
- package/dist/deps.js +28 -11
- package/dist/receiver.compiled.debug.js +11 -11
- package/dist/receiver.compiled.debug.map +3 -3
- package/dist/receiver.compiled.js +11 -11
- package/dist/receiver.compiled.map +3 -3
- package/dist/shaka-player.compiled.debug.externs.js +232 -102
- package/dist/shaka-player.compiled.debug.js +189 -165
- package/dist/shaka-player.compiled.debug.map +4 -4
- package/dist/shaka-player.compiled.externs.js +232 -102
- package/dist/shaka-player.compiled.js +567 -553
- package/dist/shaka-player.compiled.map +4 -4
- package/dist/shaka-player.ui.debug.externs.js +338 -113
- package/dist/shaka-player.ui.debug.js +296 -276
- package/dist/shaka-player.ui.debug.map +4 -4
- package/dist/shaka-player.ui.externs.js +338 -113
- package/dist/shaka-player.ui.js +685 -671
- package/dist/shaka-player.ui.map +4 -4
- package/docs/tutorials/drm-config.md +1 -0
- package/docs/tutorials/fairplay.md +77 -0
- package/docs/tutorials/index.json +1 -0
- package/docs/tutorials/manifest-parser.md +1 -1
- package/docs/tutorials/ui-customization.md +5 -2
- package/docs/tutorials/ui.md +10 -4
- package/docs/tutorials/welcome.md +2 -2
- package/externs/mediasession.js +16 -1
- package/externs/shaka/net.js +14 -4
- package/externs/shaka/player.js +136 -90
- package/externs/tippy.js +30 -0
- package/externs/webkitmediakeys.js +4 -0
- package/karma.conf.js +30 -24
- package/lib/cast/cast_proxy.js +94 -23
- package/lib/cast/cast_receiver.js +8 -1
- package/lib/dash/content_protection.js +33 -1
- package/lib/dash/dash_parser.js +13 -5
- package/lib/hls/hls_parser.js +20 -4
- package/lib/media/drm_engine.js +29 -2
- package/lib/media/media_source_engine.js +9 -6
- package/lib/media/play_rate_controller.js +14 -3
- package/lib/media/playhead.js +8 -3
- package/lib/media/streaming_engine.js +68 -20
- package/lib/media/transmuxer.js +2 -2
- package/lib/media/video_wrapper.js +8 -3
- package/lib/net/data_uri_plugin.js +5 -2
- package/lib/net/http_fetch_plugin.js +3 -3
- package/lib/net/http_plugin_utils.js +2 -4
- package/lib/net/http_xhr_plugin.js +2 -2
- package/lib/net/networking_engine.js +1 -0
- package/lib/offline/offline_scheme.js +7 -2
- package/lib/player.js +18 -8
- package/lib/polyfill/input_event.js +7 -11
- package/lib/polyfill/mediasource.js +1 -1
- package/lib/polyfill/patchedmediakeys_apple.js +2 -72
- package/lib/text/cue.js +1 -1
- package/lib/text/ttml_text_parser.js +1 -1
- package/lib/util/config_utils.js +1 -0
- package/lib/util/error.js +45 -11
- package/lib/util/event_manager.js +211 -100
- package/lib/util/fairplay_utils.js +122 -0
- package/lib/util/i_releasable.js +1 -0
- package/lib/util/player_configuration.js +7 -0
- package/lib/util/pssh.js +41 -0
- package/lib/util/string_utils.js +42 -6
- package/lib/util/timer.js +1 -1
- package/package.json +33 -33
- package/roadmap.md +96 -0
- package/shaka-player.uncompiled.js +5 -1
- package/test/dash/dash_parser_content_protection_unit.js +35 -1
- package/test/dash/dash_parser_manifest_unit.js +60 -0
- package/test/hls/hls_live_unit.js +7 -1
- package/test/hls/hls_parser_unit.js +50 -0
- package/test/media/drm_engine_unit.js +10 -4
- package/test/media/media_source_engine_integration.js +12 -0
- package/test/media/media_source_engine_unit.js +3 -1
- package/test/media/playhead_unit.js +7 -5
- package/test/media/streaming_engine_unit.js +46 -1
- package/test/media/transmuxer_integration.js +13 -0
- package/test/net/data_uri_plugin_unit.js +13 -2
- package/test/net/http_plugin_unit.js +17 -12
- package/test/net/networking_engine_unit.js +17 -8
- package/test/offline/offline_scheme_unit.js +18 -8
- package/test/player_external.js +3 -2
- package/test/player_integration.js +94 -3
- package/test/player_src_equals_integration.js +2 -2
- package/test/player_unit.js +21 -8
- package/test/test/boot.js +20 -5
- package/test/test/externs/jasmine.js +48 -0
- package/test/test/util/expect_async_polyfill.js +145 -0
- package/test/test/util/fake_networking_engine.js +1 -0
- package/test/test/util/manifest_generator.js +2 -1
- package/test/test/util/test_scheme.js +34 -2
- package/test/test/util/ui_utils.js +41 -0
- package/test/test/util/util.js +16 -8
- package/test/ui/ui_unit.js +130 -4
- package/ui/audio_language_selection.js +17 -96
- package/ui/big_play_button.js +61 -0
- package/ui/controls.js +226 -335
- package/ui/controls.less +3 -5
- package/ui/element.js +24 -6
- package/ui/externs/ui.js +62 -9
- package/ui/fullscreen_button.js +2 -52
- package/ui/less/buttons.less +10 -16
- package/ui/less/containers.less +75 -20
- package/ui/less/general.less +18 -2
- package/ui/less/other_elements.less +2 -1
- package/ui/less/overflow_menu.less +11 -10
- package/ui/less/range_elements.less +12 -10
- package/ui/less/spinner.less +2 -0
- package/ui/overflow_menu.js +1 -1
- package/ui/pip_button.js +1 -1
- package/ui/{play_pause_button.js → play_button.js} +17 -47
- package/ui/presentation_time.js +17 -12
- package/ui/range_element.js +176 -0
- package/ui/resolution_selection.js +43 -106
- package/ui/seek_bar.js +204 -0
- package/ui/settings_menu.js +113 -0
- package/ui/small_play_button.js +73 -0
- package/ui/text_displayer.js +17 -14
- package/ui/text_selection.js +42 -107
- package/ui/ui.js +17 -40
- package/ui/volume_bar.js +40 -68
package/ui/controls.js
CHANGED
|
@@ -19,12 +19,12 @@
|
|
|
19
19
|
goog.provide('shaka.ui.Controls');
|
|
20
20
|
goog.provide('shaka.ui.ControlsPanel');
|
|
21
21
|
|
|
22
|
-
goog.require('goog.asserts');
|
|
23
22
|
goog.require('shaka.log');
|
|
24
23
|
goog.require('shaka.ui.Constants');
|
|
25
24
|
goog.require('shaka.ui.Enums');
|
|
26
25
|
goog.require('shaka.ui.Locales');
|
|
27
26
|
goog.require('shaka.ui.Localization');
|
|
27
|
+
goog.require('shaka.ui.SeekBar');
|
|
28
28
|
goog.require('shaka.ui.Utils');
|
|
29
29
|
goog.require('shaka.util.Dom');
|
|
30
30
|
goog.require('shaka.util.EventManager');
|
|
@@ -54,7 +54,7 @@ shaka.ui.Controls = function(player, videoContainer, video, config) {
|
|
|
54
54
|
/** @private {boolean} */
|
|
55
55
|
this.overrideCssShowControls_ = false;
|
|
56
56
|
|
|
57
|
-
/** shaka.extern.UIConfiguration */
|
|
57
|
+
/** @private {shaka.extern.UIConfiguration} */
|
|
58
58
|
this.config_ = config;
|
|
59
59
|
|
|
60
60
|
/** @private {shaka.cast.CastProxy} */
|
|
@@ -79,19 +79,14 @@ shaka.ui.Controls = function(player, videoContainer, video, config) {
|
|
|
79
79
|
/** @private {!HTMLElement} */
|
|
80
80
|
this.videoContainer_ = videoContainer;
|
|
81
81
|
|
|
82
|
+
/** @private {shaka.ui.SeekBar} */
|
|
83
|
+
this.seekBar_ = null;
|
|
84
|
+
|
|
82
85
|
/** @private {boolean} */
|
|
83
86
|
this.isSeeking_ = false;
|
|
84
87
|
|
|
85
|
-
/**
|
|
86
|
-
|
|
87
|
-
* the seek bar and the seek being sent to the player.
|
|
88
|
-
*
|
|
89
|
-
* @private {shaka.util.Timer}
|
|
90
|
-
*/
|
|
91
|
-
this.seekTimer_ = new shaka.util.Timer(() => {
|
|
92
|
-
goog.asserts.assert(this.seekBar_ != null, 'Seekbar should not be null!');
|
|
93
|
-
this.video_.currentTime = parseFloat(this.seekBar_.value);
|
|
94
|
-
});
|
|
88
|
+
/** @private {!Array.<!Element>} */
|
|
89
|
+
this.settingsMenus_ = [];
|
|
95
90
|
|
|
96
91
|
/**
|
|
97
92
|
* This timer is used to detect when the user has stopped moving the mouse
|
|
@@ -133,7 +128,10 @@ shaka.ui.Controls = function(player, videoContainer, video, config) {
|
|
|
133
128
|
* @private {shaka.util.Timer}
|
|
134
129
|
*/
|
|
135
130
|
this.timeAndSeekRangeTimer_ = new shaka.util.Timer(() => {
|
|
136
|
-
|
|
131
|
+
// Suppress timer-based updates if the controls are hidden.
|
|
132
|
+
if (this.isOpaque_()) {
|
|
133
|
+
this.updateTimeAndSeekRange_();
|
|
134
|
+
}
|
|
137
135
|
});
|
|
138
136
|
|
|
139
137
|
/** @private {?number} */
|
|
@@ -145,13 +143,12 @@ shaka.ui.Controls = function(player, videoContainer, video, config) {
|
|
|
145
143
|
/** @private {shaka.ui.Localization} */
|
|
146
144
|
this.localization_ = shaka.ui.Controls.createLocalization_();
|
|
147
145
|
|
|
148
|
-
this.createDOM_();
|
|
149
|
-
|
|
150
|
-
this.updateLocalizedStrings_();
|
|
151
|
-
|
|
152
146
|
/** @private {shaka.util.EventManager} */
|
|
153
147
|
this.eventManager_ = new shaka.util.EventManager();
|
|
154
148
|
|
|
149
|
+
// Configure and create the layout of the controls
|
|
150
|
+
this.configure(this.config_);
|
|
151
|
+
|
|
155
152
|
this.addEventListeners_();
|
|
156
153
|
|
|
157
154
|
/**
|
|
@@ -188,11 +185,6 @@ shaka.ui.Controls.prototype.destroy = async function() {
|
|
|
188
185
|
this.eventManager_ = null;
|
|
189
186
|
}
|
|
190
187
|
|
|
191
|
-
if (this.seekTimer_) {
|
|
192
|
-
this.seekTimer_.stop();
|
|
193
|
-
this.seekTimer_ = null;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
188
|
if (this.mouseStillTimer_) {
|
|
197
189
|
this.mouseStillTimer_.stop();
|
|
198
190
|
this.mouseStillTimer_ = null;
|
|
@@ -229,6 +221,10 @@ shaka.ui.Controls.prototype.destroy = async function() {
|
|
|
229
221
|
|
|
230
222
|
await Promise.all(this.elements_.map((element) => element.destroy()));
|
|
231
223
|
this.elements_ = [];
|
|
224
|
+
|
|
225
|
+
if (this.seekBar_) {
|
|
226
|
+
await this.seekBar_.destroy();
|
|
227
|
+
}
|
|
232
228
|
};
|
|
233
229
|
|
|
234
230
|
|
|
@@ -351,6 +347,62 @@ shaka.ui.Controls.prototype.loadComplete = function() {
|
|
|
351
347
|
};
|
|
352
348
|
|
|
353
349
|
|
|
350
|
+
/**
|
|
351
|
+
* @param {!shaka.extern.UIConfiguration} config
|
|
352
|
+
* @export
|
|
353
|
+
*/
|
|
354
|
+
shaka.ui.Controls.prototype.configure = function(config) {
|
|
355
|
+
this.config_ = config;
|
|
356
|
+
|
|
357
|
+
this.castProxy_.changeReceiverId(config.castReceiverAppId);
|
|
358
|
+
|
|
359
|
+
// Deconstruct the old layout if applicable
|
|
360
|
+
if (this.seekBar_) {
|
|
361
|
+
this.seekBar_.destroy();
|
|
362
|
+
this.seekBar_ = null;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (this.playButton_) {
|
|
366
|
+
this.playButton_.destroy();
|
|
367
|
+
this.playButton_ = null;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (this.controlsContainer_) {
|
|
371
|
+
shaka.util.Dom.removeAllChildren(this.controlsContainer_);
|
|
372
|
+
this.videoContainer_.removeChild(this.spinnerContainer_);
|
|
373
|
+
} else {
|
|
374
|
+
this.addControlsContainer_();
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// Create the new layout
|
|
378
|
+
this.createDOM_();
|
|
379
|
+
|
|
380
|
+
// Init the play state
|
|
381
|
+
this.onPlayStateChange_();
|
|
382
|
+
|
|
383
|
+
// Elements that should not propagate clicks (controls panel, menus)
|
|
384
|
+
const noPropagationElements = this.videoContainer_.getElementsByClassName(
|
|
385
|
+
'shaka-no-propagation');
|
|
386
|
+
for (const element of noPropagationElements) {
|
|
387
|
+
const cb = (event) => event.stopPropagation();
|
|
388
|
+
this.eventManager_.listen(element, 'click', cb);
|
|
389
|
+
this.eventManager_.listen(element, 'dblclick', cb);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// Keep showing controls if one of those elements is hovered
|
|
393
|
+
const showControlsElements = this.videoContainer_.getElementsByClassName(
|
|
394
|
+
'shaka-show-controls-on-mouse-over');
|
|
395
|
+
for (const element of showControlsElements) {
|
|
396
|
+
this.eventManager_.listen(element, 'mouseover', () => {
|
|
397
|
+
this.overrideCssShowControls_ = true;
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
this.eventManager_.listen(element, 'mouseleave', () => {
|
|
401
|
+
this.overrideCssShowControls_ = false;
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
|
|
354
406
|
/**
|
|
355
407
|
* Enable or disable the custom controls. Enabling disables native
|
|
356
408
|
* browser controls.
|
|
@@ -361,16 +413,20 @@ shaka.ui.Controls.prototype.loadComplete = function() {
|
|
|
361
413
|
shaka.ui.Controls.prototype.setEnabledShakaControls = function(enabled) {
|
|
362
414
|
this.enabled_ = enabled;
|
|
363
415
|
if (enabled) {
|
|
416
|
+
shaka.ui.Utils.setDisplay(this.controlsContainer_, true);
|
|
417
|
+
|
|
418
|
+
// Spinner lives outside of the main controls div
|
|
364
419
|
shaka.ui.Utils.setDisplay(
|
|
365
|
-
this.
|
|
420
|
+
this.spinnerContainer_, this.player_.isBuffering());
|
|
366
421
|
|
|
367
422
|
// If we're hiding native controls, make sure the video element itself is
|
|
368
423
|
// not tab-navigable. Our custom controls will still be tab-navigable.
|
|
369
424
|
this.video_.tabIndex = -1;
|
|
370
425
|
this.video_.controls = false;
|
|
371
426
|
} else {
|
|
372
|
-
shaka.ui.Utils.setDisplay(
|
|
373
|
-
|
|
427
|
+
shaka.ui.Utils.setDisplay(this.controlsContainer_, false);
|
|
428
|
+
// Spinner lives outside of the main controls div
|
|
429
|
+
shaka.ui.Utils.setDisplay(this.spinnerContainer_, false);
|
|
374
430
|
}
|
|
375
431
|
|
|
376
432
|
// The effects of play state changes are inhibited while showing native
|
|
@@ -379,6 +435,15 @@ shaka.ui.Controls.prototype.setEnabledShakaControls = function(enabled) {
|
|
|
379
435
|
};
|
|
380
436
|
|
|
381
437
|
|
|
438
|
+
/**
|
|
439
|
+
* @param {boolean} seeking
|
|
440
|
+
* @export
|
|
441
|
+
*/
|
|
442
|
+
shaka.ui.Controls.prototype.setSeeking = function(seeking) {
|
|
443
|
+
this.isSeeking_ = seeking;
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
|
|
382
447
|
/**
|
|
383
448
|
* Enable or disable native browser controls. Enabling disables shaka
|
|
384
449
|
* controls.
|
|
@@ -417,6 +482,24 @@ shaka.ui.Controls.prototype.getLocalization = function() {
|
|
|
417
482
|
return this.localization_;
|
|
418
483
|
};
|
|
419
484
|
|
|
485
|
+
/** @export */
|
|
486
|
+
shaka.ui.Controls.prototype.toggleFullScreen = async function() {
|
|
487
|
+
if (document.fullscreenElement) {
|
|
488
|
+
document.exitFullscreen();
|
|
489
|
+
} else {
|
|
490
|
+
// If we are in PiP mode, leave PiP mode first.
|
|
491
|
+
try {
|
|
492
|
+
if (document.pictureInPictureElement) {
|
|
493
|
+
await document.exitPictureInPicture();
|
|
494
|
+
}
|
|
495
|
+
} catch (error) {
|
|
496
|
+
this.dispatchEvent(new shaka.util.FakeEvent('error', {
|
|
497
|
+
detail: error,
|
|
498
|
+
}));
|
|
499
|
+
}
|
|
500
|
+
await this.videoContainer_.requestFullscreen();
|
|
501
|
+
}
|
|
502
|
+
};
|
|
420
503
|
|
|
421
504
|
/**
|
|
422
505
|
* @return {!HTMLElement}
|
|
@@ -504,11 +587,7 @@ shaka.ui.Controls.prototype.isCastAllowed = function() {
|
|
|
504
587
|
* @export
|
|
505
588
|
*/
|
|
506
589
|
shaka.ui.Controls.prototype.getDisplayTime = function() {
|
|
507
|
-
|
|
508
|
-
Number(this.seekBar_.value) :
|
|
509
|
-
Number(this.video_.currentTime);
|
|
510
|
-
|
|
511
|
-
return displayTime;
|
|
590
|
+
return this.seekBar_ ? this.seekBar_.getValue() : this.video_.currentTime;
|
|
512
591
|
};
|
|
513
592
|
|
|
514
593
|
|
|
@@ -554,67 +633,28 @@ shaka.ui.Controls.prototype.hideSettingsMenus = function() {
|
|
|
554
633
|
};
|
|
555
634
|
|
|
556
635
|
|
|
557
|
-
/**
|
|
558
|
-
* @private
|
|
559
|
-
*/
|
|
560
|
-
shaka.ui.Controls.prototype.updateLocalizedStrings_ = function() {
|
|
561
|
-
const LocIds = shaka.ui.Locales.Ids;
|
|
562
|
-
|
|
563
|
-
if (this.seekBar_) {
|
|
564
|
-
this.seekBar_.setAttribute(shaka.ui.Constants.ARIA_LABEL,
|
|
565
|
-
this.localization_.resolve(LocIds.SEEK));
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
// Localize state-dependant labels
|
|
569
|
-
const makePlayNotPause = this.video_.paused && !this.isSeeking_;
|
|
570
|
-
const playButtonAriaLabelId = makePlayNotPause ? LocIds.PLAY : LocIds.PAUSE;
|
|
571
|
-
this.playButton_.setAttribute(shaka.ui.Constants.ARIA_LABEL,
|
|
572
|
-
this.localization_.resolve(playButtonAriaLabelId));
|
|
573
|
-
};
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* @private
|
|
578
|
-
*/
|
|
579
|
-
shaka.ui.Controls.prototype.initOptionalElementsToNull_ = function() {
|
|
580
|
-
// TODO: encapsulate/abstract range inputs and their containers
|
|
581
|
-
|
|
582
|
-
/** @private {HTMLElement} */
|
|
583
|
-
this.seekBarContainer_ = null;
|
|
584
|
-
|
|
585
|
-
/** @private {HTMLInputElement} */
|
|
586
|
-
this.seekBar_ = null;
|
|
587
|
-
};
|
|
588
|
-
|
|
589
|
-
|
|
590
636
|
/**
|
|
591
637
|
* @private
|
|
592
638
|
*/
|
|
593
639
|
shaka.ui.Controls.prototype.createDOM_ = function() {
|
|
594
|
-
this.initOptionalElementsToNull_();
|
|
595
|
-
|
|
596
640
|
this.videoContainer_.classList.add('shaka-video-container');
|
|
597
641
|
this.video_.classList.add('shaka-video');
|
|
598
642
|
|
|
599
|
-
this.
|
|
600
|
-
|
|
601
|
-
|
|
643
|
+
if (this.config_.addBigPlayButton) {
|
|
644
|
+
this.addPlayButton_();
|
|
645
|
+
}
|
|
602
646
|
|
|
603
647
|
this.addBufferingSpinner_();
|
|
604
648
|
|
|
605
649
|
this.addControlsButtonPanel_();
|
|
606
650
|
|
|
607
|
-
// Seek bar
|
|
608
|
-
if (this.config_.addSeekBar) {
|
|
609
|
-
this.addSeekBar_();
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
/** @private {!Array.<!Element>} */
|
|
613
651
|
this.settingsMenus_ = Array.from(
|
|
614
652
|
this.videoContainer_.getElementsByClassName('shaka-settings-menu'));
|
|
615
653
|
|
|
616
|
-
|
|
617
|
-
|
|
654
|
+
if (this.config_.addSeekBar) {
|
|
655
|
+
this.seekBar_ = new shaka.ui.SeekBar(this.bottomControls_, this);
|
|
656
|
+
} else {
|
|
657
|
+
// Settings menus need to be positioned lower, if the seekbar is absent.
|
|
618
658
|
for (let menu of this.settingsMenus_) {
|
|
619
659
|
menu.classList.add('shaka-low-position');
|
|
620
660
|
}
|
|
@@ -630,6 +670,14 @@ shaka.ui.Controls.prototype.addControlsContainer_ = function() {
|
|
|
630
670
|
this.controlsContainer_ = shaka.util.Dom.createHTMLElement('div');
|
|
631
671
|
this.controlsContainer_.classList.add('shaka-controls-container');
|
|
632
672
|
this.videoContainer_.appendChild(this.controlsContainer_);
|
|
673
|
+
|
|
674
|
+
this.eventManager_.listen(this.controlsContainer_, 'touchstart', (e) => {
|
|
675
|
+
this.onContainerTouch_(e);
|
|
676
|
+
}, {passive: false});
|
|
677
|
+
|
|
678
|
+
this.eventManager_.listen(this.controlsContainer_, 'click', (e) => {
|
|
679
|
+
this.onContainerClick_(e);
|
|
680
|
+
});
|
|
633
681
|
};
|
|
634
682
|
|
|
635
683
|
|
|
@@ -637,16 +685,13 @@ shaka.ui.Controls.prototype.addControlsContainer_ = function() {
|
|
|
637
685
|
* @private
|
|
638
686
|
*/
|
|
639
687
|
shaka.ui.Controls.prototype.addPlayButton_ = function() {
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
this.
|
|
643
|
-
this.controlsContainer_.appendChild(this.playButtonContainer_);
|
|
688
|
+
const playButtonContainer = shaka.util.Dom.createHTMLElement('div');
|
|
689
|
+
playButtonContainer.classList.add('shaka-play-button-container');
|
|
690
|
+
this.controlsContainer_.appendChild(playButtonContainer);
|
|
644
691
|
|
|
645
|
-
/** @private {
|
|
646
|
-
this.playButton_ =
|
|
647
|
-
|
|
648
|
-
this.playButton_.setAttribute('icon', 'play');
|
|
649
|
-
this.playButtonContainer_.appendChild(this.playButton_);
|
|
692
|
+
/** @private {shaka.ui.BigPlayButton} */
|
|
693
|
+
this.playButton_ =
|
|
694
|
+
new shaka.ui.BigPlayButton(playButtonContainer, this);
|
|
650
695
|
};
|
|
651
696
|
|
|
652
697
|
|
|
@@ -654,19 +699,23 @@ shaka.ui.Controls.prototype.addPlayButton_ = function() {
|
|
|
654
699
|
* @private
|
|
655
700
|
*/
|
|
656
701
|
shaka.ui.Controls.prototype.addBufferingSpinner_ = function() {
|
|
657
|
-
|
|
658
|
-
|
|
702
|
+
/** @private {!HTMLElement} */
|
|
703
|
+
this.spinnerContainer_ = shaka.util.Dom.createHTMLElement('div');
|
|
704
|
+
this.spinnerContainer_.classList.add('shaka-spinner-container');
|
|
705
|
+
this.videoContainer_.appendChild(this.spinnerContainer_);
|
|
706
|
+
|
|
707
|
+
const spinner = shaka.util.Dom.createHTMLElement('div');
|
|
708
|
+
spinner.classList.add('shaka-spinner');
|
|
709
|
+
this.spinnerContainer_.appendChild(spinner);
|
|
659
710
|
|
|
660
711
|
// Svg elements have to be created with the svg xml namespace.
|
|
661
712
|
const xmlns = 'http://www.w3.org/2000/svg';
|
|
662
713
|
|
|
663
|
-
|
|
664
|
-
this.bufferingSpinner_ =
|
|
714
|
+
const svg =
|
|
665
715
|
/** @type {!HTMLElement} */(document.createElementNS(xmlns, 'svg'));
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
this.playButton_.appendChild(this.bufferingSpinner_);
|
|
716
|
+
svg.setAttribute('class', 'shaka-spinner-svg');
|
|
717
|
+
svg.setAttribute('viewBox', '0 0 30 30');
|
|
718
|
+
spinner.appendChild(svg);
|
|
670
719
|
|
|
671
720
|
// These coordinates are relative to the SVG viewBox above. This is distinct
|
|
672
721
|
// from the actual display size in the page, since the "S" is for "Scalable."
|
|
@@ -680,7 +729,7 @@ shaka.ui.Controls.prototype.addBufferingSpinner_ = function() {
|
|
|
680
729
|
spinnerCircle.setAttribute('fill', 'none');
|
|
681
730
|
spinnerCircle.setAttribute('stroke-width', '1');
|
|
682
731
|
spinnerCircle.setAttribute('stroke-miterlimit', '10');
|
|
683
|
-
|
|
732
|
+
svg.appendChild(spinnerCircle);
|
|
684
733
|
};
|
|
685
734
|
|
|
686
735
|
|
|
@@ -688,12 +737,25 @@ shaka.ui.Controls.prototype.addBufferingSpinner_ = function() {
|
|
|
688
737
|
* @private
|
|
689
738
|
*/
|
|
690
739
|
shaka.ui.Controls.prototype.addControlsButtonPanel_ = function() {
|
|
740
|
+
/** @private {!HTMLElement} */
|
|
741
|
+
this.bottomControls_ = shaka.util.Dom.createHTMLElement('div');
|
|
742
|
+
this.bottomControls_.classList.add('shaka-bottom-controls');
|
|
743
|
+
this.controlsContainer_.appendChild(this.bottomControls_);
|
|
744
|
+
|
|
691
745
|
/** @private {!HTMLElement} */
|
|
692
746
|
this.controlsButtonPanel_ = shaka.util.Dom.createHTMLElement('div');
|
|
693
747
|
this.controlsButtonPanel_.classList.add('shaka-controls-button-panel');
|
|
694
748
|
this.controlsButtonPanel_.classList.add('shaka-no-propagation');
|
|
695
749
|
this.controlsButtonPanel_.classList.add('shaka-show-controls-on-mouse-over');
|
|
696
|
-
this.
|
|
750
|
+
this.bottomControls_.appendChild(this.controlsButtonPanel_);
|
|
751
|
+
|
|
752
|
+
// Overflow menus are supposed to hide once you click elsewhere
|
|
753
|
+
// on the video element. The code in onContainerClick_ ensures that.
|
|
754
|
+
// However, clicks on controls panel don't propagate to the container,
|
|
755
|
+
// so we have to explicitly hide the menus onclick here.
|
|
756
|
+
this.eventManager_.listen(this.controlsButtonPanel_, 'click', () => {
|
|
757
|
+
this.hideSettingsMenus();
|
|
758
|
+
});
|
|
697
759
|
|
|
698
760
|
// Create the elements specified by controlPanelElements
|
|
699
761
|
for (let i = 0; i < this.config_.controlPanelElements.length; i++) {
|
|
@@ -710,12 +772,36 @@ shaka.ui.Controls.prototype.addControlsButtonPanel_ = function() {
|
|
|
710
772
|
|
|
711
773
|
|
|
712
774
|
/**
|
|
775
|
+
* When a mobile device is rotated to landscape layout, and the video is
|
|
776
|
+
* loaded, make the demo app go into fullscreen.
|
|
777
|
+
* Similarly, exit fullscreen when the device is rotated to portrait layout.
|
|
778
|
+
* @private
|
|
779
|
+
*/
|
|
780
|
+
shaka.ui.Controls.prototype.onScreenRotation_ = function() {
|
|
781
|
+
if (!this.video_ ||
|
|
782
|
+
this.video_.readyState == 0 ||
|
|
783
|
+
this.castProxy_.isCasting()) { return; }
|
|
784
|
+
|
|
785
|
+
if (screen.orientation.type.includes('landscape') &&
|
|
786
|
+
!document.fullscreenElement) {
|
|
787
|
+
this.videoContainer_.requestFullscreen();
|
|
788
|
+
} else if (screen.orientation.type.includes('portrait') &&
|
|
789
|
+
document.fullscreenElement) {
|
|
790
|
+
document.exitFullscreen();
|
|
791
|
+
}
|
|
792
|
+
};
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
/**
|
|
796
|
+
* Adds static event listeners. This should only add event listeners to
|
|
797
|
+
* things that don't change (e.g. Player). Dynamic elements (e.g. controls)
|
|
798
|
+
* should have their event listeners added when they are created.
|
|
713
799
|
* @private
|
|
714
800
|
*/
|
|
715
801
|
shaka.ui.Controls.prototype.addEventListeners_ = function() {
|
|
716
802
|
// TODO: Convert adding event listers to the "() =>" form.
|
|
717
803
|
|
|
718
|
-
this.
|
|
804
|
+
this.eventManager_.listen(this.player_, 'buffering', () => {
|
|
719
805
|
this.onBufferingStateChange_();
|
|
720
806
|
});
|
|
721
807
|
// Set the initial state, as well.
|
|
@@ -725,117 +811,41 @@ shaka.ui.Controls.prototype.addEventListeners_ = function() {
|
|
|
725
811
|
// for focused elements.
|
|
726
812
|
this.eventManager_.listen(window, 'keydown', this.onKeyDown_.bind(this));
|
|
727
813
|
|
|
728
|
-
this.
|
|
814
|
+
this.eventManager_.listen(
|
|
815
|
+
this.controlsContainer_, 'dblclick', () => this.toggleFullScreen());
|
|
816
|
+
|
|
817
|
+
this.eventManager_.listen(this.video_,
|
|
729
818
|
'play', this.onPlayStateChange_.bind(this));
|
|
730
|
-
this.
|
|
819
|
+
this.eventManager_.listen(this.video_,
|
|
731
820
|
'pause', this.onPlayStateChange_.bind(this));
|
|
732
821
|
|
|
733
822
|
// Since videos go into a paused state at the end, Chrome and Edge both fire
|
|
734
823
|
// the 'pause' event when a video ends. IE 11 only fires the 'ended' event.
|
|
735
|
-
this.
|
|
824
|
+
this.eventManager_.listen(this.video_,
|
|
736
825
|
'ended', this.onPlayStateChange_.bind(this));
|
|
737
826
|
|
|
738
|
-
|
|
739
|
-
this.seekBar_.addEventListener(
|
|
740
|
-
'mousedown', this.onSeekStart_.bind(this));
|
|
741
|
-
this.seekBar_.addEventListener(
|
|
742
|
-
'touchstart', this.onSeekStart_.bind(this), {passive: true});
|
|
743
|
-
this.seekBar_.addEventListener(
|
|
744
|
-
'input', this.onSeekInput_.bind(this));
|
|
745
|
-
this.seekBar_.addEventListener(
|
|
746
|
-
'touchend', this.onSeekEnd_.bind(this));
|
|
747
|
-
this.seekBar_.addEventListener(
|
|
748
|
-
'mouseup', this.onSeekEnd_.bind(this));
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
this.controlsContainer_.addEventListener(
|
|
752
|
-
'touchstart', this.onContainerTouch_.bind(this), {passive: false});
|
|
753
|
-
this.controlsContainer_.addEventListener(
|
|
754
|
-
'click', this.onContainerClick_.bind(this));
|
|
755
|
-
|
|
756
|
-
// Elements that should not propagate clicks (controls panel, menus)
|
|
757
|
-
const noPropagationElements = this.videoContainer_.getElementsByClassName(
|
|
758
|
-
'shaka-no-propagation');
|
|
759
|
-
for (let i = 0; i < noPropagationElements.length; i++) {
|
|
760
|
-
let element = noPropagationElements[i];
|
|
761
|
-
element.addEventListener(
|
|
762
|
-
'click', function(event) { event.stopPropagation(); });
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
// Keep showing controls if one of those elements is hovered
|
|
766
|
-
let showControlsElements = this.videoContainer_.getElementsByClassName(
|
|
767
|
-
'shaka-show-controls-on-mouse-over');
|
|
768
|
-
for (let i = 0; i < showControlsElements.length; i++) {
|
|
769
|
-
let element = showControlsElements[i];
|
|
770
|
-
element.addEventListener(
|
|
771
|
-
'mouseover', () => {
|
|
772
|
-
this.overrideCssShowControls_ = true;
|
|
773
|
-
});
|
|
774
|
-
|
|
775
|
-
element.addEventListener(
|
|
776
|
-
'mouseleave', () => {
|
|
777
|
-
this.overrideCssShowControls_ = false;
|
|
778
|
-
});
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
this.videoContainer_.addEventListener(
|
|
827
|
+
this.eventManager_.listen(this.videoContainer_,
|
|
782
828
|
'mousemove', this.onMouseMove_.bind(this));
|
|
783
|
-
this.
|
|
829
|
+
this.eventManager_.listen(this.videoContainer_,
|
|
784
830
|
'touchmove', this.onMouseMove_.bind(this), {passive: true});
|
|
785
|
-
this.
|
|
831
|
+
this.eventManager_.listen(this.videoContainer_,
|
|
786
832
|
'touchend', this.onMouseMove_.bind(this), {passive: true});
|
|
787
|
-
this.
|
|
833
|
+
this.eventManager_.listen(this.videoContainer_,
|
|
788
834
|
'mouseleave', this.onMouseLeave_.bind(this));
|
|
789
835
|
|
|
790
|
-
|
|
791
|
-
// on the video element. The code in onContainerClick_ ensures that.
|
|
792
|
-
// However, clicks on controls panel don't propagate to the container,
|
|
793
|
-
// so we have to explicitly hide the menus onclick here.
|
|
794
|
-
this.controlsButtonPanel_.addEventListener('click', () => {
|
|
795
|
-
this.hideSettingsMenusTimer_.tickNow();
|
|
796
|
-
});
|
|
797
|
-
|
|
798
|
-
this.castProxy_.addEventListener(
|
|
836
|
+
this.eventManager_.listen(this.castProxy_,
|
|
799
837
|
'caststatuschanged', (e) => {
|
|
800
838
|
this.onCastStatusChange_(e);
|
|
801
839
|
});
|
|
802
840
|
|
|
803
|
-
this.
|
|
804
|
-
|
|
805
|
-
this.localization_.addEventListener(
|
|
806
|
-
shaka.ui.Localization.LOCALE_UPDATED,
|
|
807
|
-
(e) => this.updateLocalizedStrings_());
|
|
808
|
-
|
|
809
|
-
this.localization_.addEventListener(
|
|
810
|
-
shaka.ui.Localization.LOCALE_CHANGED,
|
|
811
|
-
(e) => this.updateLocalizedStrings_());
|
|
812
|
-
};
|
|
813
|
-
|
|
841
|
+
this.eventManager_.listen(this.videoContainer_,
|
|
842
|
+
'keyup', this.onKeyUp_.bind(this));
|
|
814
843
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
// less/range_elements.less for a complete explanation.
|
|
821
|
-
// TODO: Factor this into a range-element component.
|
|
822
|
-
this.seekBarContainer_ = shaka.util.Dom.createHTMLElement('div');
|
|
823
|
-
this.seekBarContainer_.classList.add('shaka-seek-bar-container');
|
|
824
|
-
|
|
825
|
-
this.seekBar_ =
|
|
826
|
-
/** @type {!HTMLInputElement} */ (document.createElement('input'));
|
|
827
|
-
this.seekBar_.classList.add('shaka-seek-bar');
|
|
828
|
-
this.seekBar_.type = 'range';
|
|
829
|
-
// NOTE: step=any causes keyboard nav problems on IE 11.
|
|
830
|
-
this.seekBar_.setAttribute('step', 'any');
|
|
831
|
-
this.seekBar_.setAttribute('min', '0');
|
|
832
|
-
this.seekBar_.setAttribute('max', '1');
|
|
833
|
-
this.seekBar_.value = '0';
|
|
834
|
-
this.seekBar_.classList.add('shaka-no-propagation');
|
|
835
|
-
this.seekBar_.classList.add('shaka-show-controls-on-mouse-over');
|
|
836
|
-
|
|
837
|
-
this.seekBarContainer_.appendChild(this.seekBar_);
|
|
838
|
-
this.controlsContainer_.appendChild(this.seekBarContainer_);
|
|
844
|
+
if (screen.orientation) {
|
|
845
|
+
this.eventManager_.listen(screen.orientation, 'change', () => {
|
|
846
|
+
this.onScreenRotation_();
|
|
847
|
+
});
|
|
848
|
+
}
|
|
839
849
|
};
|
|
840
850
|
|
|
841
851
|
|
|
@@ -873,8 +883,15 @@ shaka.ui.Controls.prototype.onMouseMove_ = function(event) {
|
|
|
873
883
|
// Make sure we are not about to hide the settings menus and then force them
|
|
874
884
|
// open.
|
|
875
885
|
this.hideSettingsMenusTimer_.stop();
|
|
876
|
-
|
|
877
|
-
this.
|
|
886
|
+
|
|
887
|
+
if (!this.isOpaque_()) {
|
|
888
|
+
// Only update the time and seek range on mouse movement if it's the very
|
|
889
|
+
// first movement and we're about to show the controls. Otherwise the
|
|
890
|
+
// seek bar will be updated mich more rapidly during mouse movement. Do
|
|
891
|
+
// this right before making it visible.
|
|
892
|
+
this.updateTimeAndSeekRange_();
|
|
893
|
+
this.setControlsOpacity_(shaka.ui.Enums.Opacity.OPAQUE);
|
|
894
|
+
}
|
|
878
895
|
|
|
879
896
|
// Hide the cursor when the mouse stops moving.
|
|
880
897
|
// Only applies while the cursor is over the video container.
|
|
@@ -1007,63 +1024,6 @@ shaka.ui.Controls.prototype.onPlayStateChange_ = function() {
|
|
|
1007
1024
|
if (this.video_.ended && !this.video_.paused) {
|
|
1008
1025
|
this.video_.pause();
|
|
1009
1026
|
}
|
|
1010
|
-
|
|
1011
|
-
// Video is paused during seek, so don't show the play arrow while seeking:
|
|
1012
|
-
if (this.enabled_ && this.video_.paused && !this.isSeeking_) {
|
|
1013
|
-
this.playButton_.setAttribute('icon', 'play');
|
|
1014
|
-
this.playButton_.setAttribute(shaka.ui.Constants.ARIA_LABEL,
|
|
1015
|
-
this.localization_.resolve(shaka.ui.Locales.Ids.PLAY));
|
|
1016
|
-
} else {
|
|
1017
|
-
this.playButton_.setAttribute('icon', 'pause');
|
|
1018
|
-
this.playButton_.setAttribute(shaka.ui.Constants.ARIA_LABEL,
|
|
1019
|
-
this.localization_.resolve(shaka.ui.Locales.Ids.PAUSE));
|
|
1020
|
-
}
|
|
1021
|
-
};
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
/** @private */
|
|
1025
|
-
shaka.ui.Controls.prototype.onSeekStart_ = function() {
|
|
1026
|
-
if (!this.enabled_) return;
|
|
1027
|
-
|
|
1028
|
-
this.isSeeking_ = true;
|
|
1029
|
-
this.video_.pause();
|
|
1030
|
-
};
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
/** @private */
|
|
1034
|
-
shaka.ui.Controls.prototype.onSeekInput_ = function() {
|
|
1035
|
-
if (!this.enabled_) return;
|
|
1036
|
-
|
|
1037
|
-
if (!this.video_.duration) {
|
|
1038
|
-
// Can't seek yet. Ignore.
|
|
1039
|
-
return;
|
|
1040
|
-
}
|
|
1041
|
-
|
|
1042
|
-
// Update the UI right away.
|
|
1043
|
-
this.updateTimeAndSeekRange_();
|
|
1044
|
-
|
|
1045
|
-
// We want to wait until the user has stopped moving the seek bar for a
|
|
1046
|
-
// little bit to avoid the number of times we ask the player to seek.
|
|
1047
|
-
//
|
|
1048
|
-
// To do this, we will start a timer that will fire in a little bit, but if
|
|
1049
|
-
// we see another seek bar change, we will cancel that timer and re-start it.
|
|
1050
|
-
//
|
|
1051
|
-
// Calling |start| on an already pending timer will cancel the old request
|
|
1052
|
-
// and start the new one.
|
|
1053
|
-
this.seekTimer_.tickAfter(/* seconds= */ 0.125);
|
|
1054
|
-
};
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
/** @private */
|
|
1058
|
-
shaka.ui.Controls.prototype.onSeekEnd_ = function() {
|
|
1059
|
-
if (!this.enabled_) return;
|
|
1060
|
-
|
|
1061
|
-
// They just let go of the seek bar, so cancel the timer and manually
|
|
1062
|
-
// call the event so that we can respond immediately.
|
|
1063
|
-
this.seekTimer_.tickNow();
|
|
1064
|
-
|
|
1065
|
-
this.isSeeking_ = false;
|
|
1066
|
-
this.video_.play();
|
|
1067
1027
|
};
|
|
1068
1028
|
|
|
1069
1029
|
|
|
@@ -1128,15 +1088,12 @@ shaka.ui.Controls.prototype.onKeyUp_ = function(event) {
|
|
|
1128
1088
|
* @private
|
|
1129
1089
|
*/
|
|
1130
1090
|
shaka.ui.Controls.prototype.onBufferingStateChange_ = function() {
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
if (this.player_.isBuffering()) {
|
|
1134
|
-
this.bufferingSpinner_.setAttribute(
|
|
1135
|
-
'class', 'shaka-spinner-svg');
|
|
1136
|
-
} else {
|
|
1137
|
-
this.bufferingSpinner_.setAttribute(
|
|
1138
|
-
'class', 'shaka-spinner-svg shaka-hidden');
|
|
1091
|
+
if (!this.enabled_) {
|
|
1092
|
+
return;
|
|
1139
1093
|
}
|
|
1094
|
+
|
|
1095
|
+
shaka.ui.Utils.setDisplay(
|
|
1096
|
+
this.spinnerContainer_, this.player_.isBuffering());
|
|
1140
1097
|
};
|
|
1141
1098
|
|
|
1142
1099
|
|
|
@@ -1163,7 +1120,10 @@ shaka.ui.Controls.prototype.isOpaque_ = function() {
|
|
|
1163
1120
|
*/
|
|
1164
1121
|
shaka.ui.Controls.prototype.seek_ = function(currentTime, event) {
|
|
1165
1122
|
this.video_.currentTime = currentTime;
|
|
1166
|
-
this.
|
|
1123
|
+
if (this.isOpaque_()) {
|
|
1124
|
+
// Only update the time and esek range if it's visible.
|
|
1125
|
+
this.updateTimeAndSeekRange_();
|
|
1126
|
+
}
|
|
1167
1127
|
};
|
|
1168
1128
|
|
|
1169
1129
|
|
|
@@ -1172,87 +1132,17 @@ shaka.ui.Controls.prototype.seek_ = function(currentTime, event) {
|
|
|
1172
1132
|
* @private
|
|
1173
1133
|
*/
|
|
1174
1134
|
shaka.ui.Controls.prototype.updateTimeAndSeekRange_ = function() {
|
|
1175
|
-
// Suppress updates if the controls are hidden.
|
|
1176
|
-
if (!this.isOpaque_()) {
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
const Constants = shaka.ui.Constants;
|
|
1181
|
-
let displayTime = this.isSeeking_ ?
|
|
1182
|
-
Number(this.seekBar_.value) :
|
|
1183
|
-
Number(this.video_.currentTime);
|
|
1184
|
-
let bufferedLength = this.video_.buffered.length;
|
|
1185
|
-
let bufferedStart = bufferedLength ? this.video_.buffered.start(0) : 0;
|
|
1186
|
-
let bufferedEnd =
|
|
1187
|
-
bufferedLength ? this.video_.buffered.end(bufferedLength - 1) : 0;
|
|
1188
|
-
let seekRange = this.player_.seekRange();
|
|
1189
|
-
let seekRangeSize = seekRange.end - seekRange.start;
|
|
1190
|
-
|
|
1191
1135
|
if (this.seekBar_) {
|
|
1192
|
-
this.seekBar_.
|
|
1193
|
-
this.seekBar_.
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
if (this.player_.isLive()) {
|
|
1197
|
-
// The amount of time we are behind the live edge.
|
|
1198
|
-
let behindLive = Math.floor(seekRange.end - displayTime);
|
|
1199
|
-
displayTime = Math.max(0, behindLive);
|
|
1200
|
-
|
|
1201
|
-
if (!this.isSeeking_ && this.seekBar_) {
|
|
1202
|
-
this.seekBar_.value = seekRange.end - displayTime;
|
|
1203
|
-
}
|
|
1204
|
-
} else {
|
|
1205
|
-
if (!this.isSeeking_ && this.seekBar_) {
|
|
1206
|
-
this.seekBar_.value = displayTime;
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
if (this.seekBar_) {
|
|
1211
|
-
// Hide seekbar seek window is very small.
|
|
1212
|
-
const seekRange = this.player_.seekRange();
|
|
1213
|
-
const seekWindow = seekRange.end - seekRange.start;
|
|
1214
|
-
if (seekWindow < Constants.MIN_SEEK_WINDOW_TO_SHOW_SEEKBAR) {
|
|
1215
|
-
shaka.ui.Utils.setDisplay(this.seekBarContainer_, false);
|
|
1136
|
+
this.seekBar_.setValue(this.video_.currentTime);
|
|
1137
|
+
this.seekBar_.update();
|
|
1138
|
+
if (this.seekBar_.isShowing()) {
|
|
1216
1139
|
for (let menu of this.settingsMenus_) {
|
|
1217
|
-
menu.classList.
|
|
1140
|
+
menu.classList.remove('shaka-low-position');
|
|
1218
1141
|
}
|
|
1219
1142
|
} else {
|
|
1220
|
-
shaka.ui.Utils.setDisplay(this.seekBarContainer_, true);
|
|
1221
1143
|
for (let menu of this.settingsMenus_) {
|
|
1222
|
-
menu.classList.
|
|
1223
|
-
}
|
|
1224
|
-
|
|
1225
|
-
let gradient = ['to right'];
|
|
1226
|
-
if (bufferedLength == 0) {
|
|
1227
|
-
gradient.push('#000 0%');
|
|
1228
|
-
} else {
|
|
1229
|
-
const clampedBufferStart = Math.max(bufferedStart, seekRange.start);
|
|
1230
|
-
const clampedBufferEnd = Math.min(bufferedEnd, seekRange.end);
|
|
1231
|
-
|
|
1232
|
-
const bufferStartDistance = clampedBufferStart - seekRange.start;
|
|
1233
|
-
const bufferEndDistance = clampedBufferEnd - seekRange.start;
|
|
1234
|
-
const playheadDistance = displayTime - seekRange.start;
|
|
1235
|
-
|
|
1236
|
-
// NOTE: the fallback to zero eliminates NaN.
|
|
1237
|
-
const bufferStartFraction = (bufferStartDistance / seekRangeSize) || 0;
|
|
1238
|
-
const bufferEndFraction = (bufferEndDistance / seekRangeSize) || 0;
|
|
1239
|
-
const playheadFraction = (playheadDistance / seekRangeSize) || 0;
|
|
1240
|
-
|
|
1241
|
-
gradient.push(Constants.SEEK_BAR_BASE_COLOR + ' ' +
|
|
1242
|
-
(bufferStartFraction * 100) + '%');
|
|
1243
|
-
gradient.push(Constants.SEEK_BAR_PLAYED_COLOR + ' ' +
|
|
1244
|
-
(bufferStartFraction * 100) + '%');
|
|
1245
|
-
gradient.push(Constants.SEEK_BAR_PLAYED_COLOR + ' ' +
|
|
1246
|
-
(playheadFraction * 100) + '%');
|
|
1247
|
-
gradient.push(Constants.SEEK_BAR_BUFFERED_COLOR + ' ' +
|
|
1248
|
-
(playheadFraction * 100) + '%');
|
|
1249
|
-
gradient.push(Constants.SEEK_BAR_BUFFERED_COLOR + ' ' +
|
|
1250
|
-
(bufferEndFraction * 100) + '%');
|
|
1251
|
-
gradient.push(Constants.SEEK_BAR_BASE_COLOR + ' ' +
|
|
1252
|
-
(bufferEndFraction * 100) + '%');
|
|
1144
|
+
menu.classList.add('shaka-low-position');
|
|
1253
1145
|
}
|
|
1254
|
-
this.seekBarContainer_.style.background =
|
|
1255
|
-
'linear-gradient(' + gradient.join(',') + ')';
|
|
1256
1146
|
}
|
|
1257
1147
|
}
|
|
1258
1148
|
|
|
@@ -1353,8 +1243,9 @@ shaka.ui.Controls.prototype.keepFocusInMenu_ = function(event) {
|
|
|
1353
1243
|
|
|
1354
1244
|
|
|
1355
1245
|
/**
|
|
1356
|
-
*
|
|
1357
|
-
* is
|
|
1246
|
+
* For keyboard navigation, we use blue borders to highlight the active
|
|
1247
|
+
* element. If we detect that a mouse is being used, remove the blue border
|
|
1248
|
+
* from the active element.
|
|
1358
1249
|
* @private
|
|
1359
1250
|
*/
|
|
1360
1251
|
shaka.ui.Controls.prototype.onMouseDown_ = function() {
|