From 7169c7a5902696a42419b67a9c8e091e7f06c95d Mon Sep 17 00:00:00 2001 From: Joey Parrish Date: Thu, 10 Aug 2017 09:17:16 -0700 Subject: [PATCH] Offer native browser controls in demo UI This makes it easier to test and reproduce issues with native controls. Issue #951 Change-Id: I77aa56e735ecfc934d4d79b35e0c1af727421406 --- demo/common/controls.js | 64 +++++++++++++++++++++++++++++++++-- demo/configuration_section.js | 24 +++++++++++++ demo/index.html | 4 +++ demo/main.js | 12 +++++++ 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/demo/common/controls.js b/demo/common/controls.js index 4f9bc75fe0..966a3e067e 100644 --- a/demo/common/controls.js +++ b/demo/common/controls.js @@ -23,6 +23,9 @@ * @suppress {missingProvide} */ function ShakaControls() { + /** @private {boolean} */ + this.enabled_ = true; + /** @private {shaka.cast.CastProxy} */ this.castProxy_ = null; @@ -167,7 +170,7 @@ ShakaControls.prototype.init = function(castProxy, onError, notifyCastStatus) { this.videoContainer_.addEventListener( 'touchstart', this.onContainerTouch_.bind(this)); this.videoContainer_.addEventListener( - 'click', this.onPlayPauseClick_.bind(this)); + 'click', this.onContainerClick_.bind(this)); // Clicks in the controls should not propagate up to the video container. this.controls_.addEventListener( @@ -225,6 +228,28 @@ ShakaControls.prototype.loadComplete = function() { }; +/** + * Enable or disable the custom controls. + * Disabling custom controls enables native controls. + * + * @param {boolean} enabled + */ +ShakaControls.prototype.setEnabled = function(enabled) { + this.enabled_ = enabled; + if (enabled) { + this.controls_.parentElement.style.display = 'inherit'; + this.video_.controls = false; + } else { + this.controls_.parentElement.style.display = 'none'; + this.video_.controls = true; + } + + // The effects of play state changes are inhibited while showing native + // browser controls. Recalculate that state now. + this.onPlayStateChange_(); +}; + + /** * Hiding the cursor when the mouse stops moving seems to be the only decent UX * in fullscreen mode. Since we can't use pure CSS for that, we use events both @@ -321,8 +346,21 @@ ShakaControls.prototype.onContainerTouch_ = function(event) { }; +/** + * @param {!Event} event + * @private + */ +ShakaControls.prototype.onContainerClick_ = function(event) { + if (!this.enabled_) return; + + this.onPlayPauseClick_(); +}; + + /** @private */ ShakaControls.prototype.onPlayPauseClick_ = function() { + if (!this.enabled_) return; + if (!this.video_.duration) { // Can't play yet. Ignore. return; @@ -342,7 +380,7 @@ ShakaControls.prototype.onPlayPauseClick_ = function() { /** @private */ ShakaControls.prototype.onPlayStateChange_ = function() { // Video is paused during seek, so don't show the play arrow while seeking: - if (this.video_.paused && !this.isSeeking_) { + if (this.enabled_ && this.video_.paused && !this.isSeeking_) { this.playPauseButton_.textContent = 'play_arrow'; this.giantPlayButtonContainer_.style.display = 'inline'; } else { @@ -354,6 +392,8 @@ ShakaControls.prototype.onPlayStateChange_ = function() { /** @private */ ShakaControls.prototype.onSeekStart_ = function() { + if (!this.enabled_) return; + this.isSeeking_ = true; this.video_.pause(); }; @@ -361,6 +401,8 @@ ShakaControls.prototype.onSeekStart_ = function() { /** @private */ ShakaControls.prototype.onSeekInput_ = function() { + if (!this.enabled_) return; + if (!this.video_.duration) { // Can't seek yet. Ignore. return; @@ -387,6 +429,8 @@ ShakaControls.prototype.onSeekInputTimeout_ = function() { /** @private */ ShakaControls.prototype.onSeekEnd_ = function() { + if (!this.enabled_) return; + if (this.seekTimeoutId_ != null) { // They just let go of the seek bar, so end the timer early. window.clearTimeout(this.seekTimeoutId_); @@ -400,6 +444,8 @@ ShakaControls.prototype.onSeekEnd_ = function() { /** @private */ ShakaControls.prototype.onMuteClick_ = function() { + if (!this.enabled_) return; + this.video_.muted = !this.video_.muted; }; @@ -435,6 +481,8 @@ ShakaControls.prototype.onVolumeInput_ = function() { /** @private */ ShakaControls.prototype.onCaptionClick_ = function() { + if (!this.enabled_) return; + this.player_.setTextTrackVisibility(!this.player_.isTextTrackVisible()); }; @@ -459,6 +507,8 @@ ShakaControls.prototype.onCaptionStateChange_ = function() { /** @private */ ShakaControls.prototype.onFullscreenClick_ = function() { + if (!this.enabled_) return; + if (document.fullscreenElement) { document.exitFullscreen(); } else { @@ -469,6 +519,8 @@ ShakaControls.prototype.onFullscreenClick_ = function() { /** @private */ ShakaControls.prototype.onCurrentTimeClick_ = function() { + if (!this.enabled_) return; + // Jump to LIVE if the user clicks on the current time. if (this.player_.isLive()) { this.video_.currentTime = this.seekBar_.max; @@ -481,6 +533,8 @@ ShakaControls.prototype.onCurrentTimeClick_ = function() { * @private */ ShakaControls.prototype.onRewindClick_ = function() { + if (!this.enabled_) return; + if (!this.video_.duration) { return; } @@ -496,6 +550,8 @@ ShakaControls.prototype.onRewindClick_ = function() { * @private */ ShakaControls.prototype.onFastForwardClick_ = function() { + if (!this.enabled_) return; + if (!this.video_.duration) { return; } @@ -508,6 +564,8 @@ ShakaControls.prototype.onFastForwardClick_ = function() { /** @private */ ShakaControls.prototype.onCastClick_ = function() { + if (!this.enabled_) return; + if (this.castProxy_.isCasting()) { this.castProxy_.suggestDisconnect(); } else { @@ -575,6 +633,8 @@ ShakaControls.prototype.showTrickPlay = function(show) { * @private */ ShakaControls.prototype.isOpaque_ = function() { + if (!this.enabled_) return false; + var parentElement = this.controls_.parentElement; // The controls are opaque if either: // 1. We have explicitly made them so in JavaScript diff --git a/demo/configuration_section.js b/demo/configuration_section.js index 558eb7581c..f682a53b90 100644 --- a/demo/configuration_section.js +++ b/demo/configuration_section.js @@ -37,6 +37,8 @@ shakaDemo.setupConfiguration_ = function() { 'input', shakaDemo.onConfigInput_); document.getElementById('preferredTextLanguage').addEventListener( 'input', shakaDemo.onConfigInput_); + document.getElementById('showNative').addEventListener( + 'change', shakaDemo.onNativeChange_); document.getElementById('showTrickPlay').addEventListener( 'change', shakaDemo.onTrickPlayChange_); document.getElementById('enableAdaptation').addEventListener( @@ -144,6 +146,28 @@ shakaDemo.onAdaptationChange_ = function(event) { }; +/** + * @param {!Event} event + * @private + */ +shakaDemo.onNativeChange_ = function(event) { + var showTrickPlay = document.getElementById('showTrickPlay'); + + if (event.target.checked) { + showTrickPlay.checked = false; + showTrickPlay.disabled = true; + shakaDemo.controls_.showTrickPlay(false); + shakaDemo.controls_.setEnabled(false); + } else { + showTrickPlay.disabled = false; + shakaDemo.controls_.setEnabled(true); + } + + // Change the hash, to mirror this. + shakaDemo.hashShouldChange_(); +}; + + /** * @param {!Event} event * @private diff --git a/demo/index.html b/demo/index.html index 808372a954..61349bd845 100644 --- a/demo/index.html +++ b/demo/index.html @@ -133,6 +133,10 @@

Shaka Player

+
+ + +
diff --git a/demo/main.js b/demo/main.js index 49c9684fab..45db754122 100644 --- a/demo/main.js +++ b/demo/main.js @@ -356,6 +356,15 @@ shakaDemo.postBrowserCheckParams_ = function(params) { shakaDemo.onTrickPlayChange_(fakeEvent); } + if ('nativecontrols' in params) { + var showNative = document.getElementById('showNative'); + showNative.checked = true; + // Call onNativeChange_ manually, because setting checked + // programatically doesn't fire a 'change' event. + var fakeEvent = /** @type {!Event} */({target: showNative}); + shakaDemo.onNativeChange_(fakeEvent); + } + // Allow the hash to be changed, and give it an initial change. shakaDemo.hashCanChange_ = true; shakaDemo.hashShouldChange_(); @@ -458,6 +467,9 @@ shakaDemo.hashShouldChange_ = function() { if (document.getElementById('showTrickPlay').checked) { params.push('trickplay'); } + if (document.getElementById('showNative').checked) { + params.push('nativecontrols'); + } if (shaka.log) { var logLevelList = document.getElementById('logLevelList'); var logLevel = logLevelList[logLevelList.selectedIndex].value;