diff options
Diffstat (limited to 'assets/js')
| -rw-r--r-- | assets/js/player.js | 67 | ||||
| -rw-r--r-- | assets/js/videojs-mobile-ui.min.js | 7 |
2 files changed, 74 insertions, 0 deletions
diff --git a/assets/js/player.js b/assets/js/player.js index 1c6e336c..a6d0c8c1 100644 --- a/assets/js/player.js +++ b/assets/js/player.js @@ -14,6 +14,7 @@ var options = { 'durationDisplay', 'progressControl', 'remainingTimeDisplay', + 'Spacer', 'captionsButton', 'qualitySelector', 'playbackRateMenuButton', @@ -73,6 +74,55 @@ if (location.pathname.startsWith('/embed/')) { }); } +// Detect mobile users and initalize mobileUi for better UX +// Detection code taken from https://stackoverflow.com/a/20293441 + +function isMobile() { + try{ document.createEvent("TouchEvent"); return true; } + catch(e){ return false; } +} + +if (isMobile()) { + player.mobileUi(); + + buttons = ["playToggle", "volumePanel", "captionsButton"]; + + if (video_data.params.quality !== 'dash') { + buttons.push("qualitySelector") + } + + // Create new control bar object for operation buttons + const ControlBar = videojs.getComponent("controlBar"); + let operations_bar = new ControlBar(player, { + children: [], + playbackRates: [0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0] + }); + buttons.slice(1).forEach(child => operations_bar.addChild(child)) + + // Remove operation buttons from primary control bar + primary_control_bar = player.getChild("controlBar"); + buttons.forEach(child => primary_control_bar.removeChild(child)); + + operations_bar_element = operations_bar.el(); + operations_bar_element.className += " mobile-operations-bar" + player.addChild(operations_bar) + + // Playback menu doesn't work when its initalized outside of the primary control bar + playback_element = document.getElementsByClassName("vjs-playback-rate")[0] + operations_bar_element.append(playback_element) + + // The share and http source selector element can't be fetched till the players ready. + player.one("playing", () => { + share_element = document.getElementsByClassName("vjs-share-control")[0] + operations_bar_element.append(share_element) + + if (video_data.params.quality === 'dash') { + http_source_selector = document.getElementsByClassName("vjs-http-source-selector vjs-menu-button")[0] + operations_bar_element.append(http_source_selector) + } + }) +} + player.on('error', function (event) { if (player.error().code === 2 || player.error().code === 4) { setTimeout(function (event) { @@ -566,3 +616,20 @@ if (navigator.vendor == "Apple Computer, Inc." && video_data.params.listen) { }); }); } + +// Watch on Invidious link +if (window.location.pathname.startsWith("/embed/")) { + const Button = videojs.getComponent('Button'); + let watch_on_invidious_button = new Button(player); + + // Create hyperlink for current instance + redirect_element = document.createElement("a"); + redirect_element.setAttribute("href", `http://${window.location.host}/watch?v=${window.location.pathname.replace("/embed/","")}`) + redirect_element.appendChild(document.createTextNode("Invidious")) + + watch_on_invidious_button.el().appendChild(redirect_element) + watch_on_invidious_button.addClass("watch-on-invidious") + + cb = player.getChild('ControlBar') + cb.addChild(watch_on_invidious_button) +}; diff --git a/assets/js/videojs-mobile-ui.min.js b/assets/js/videojs-mobile-ui.min.js new file mode 100644 index 00000000..e624fbe2 --- /dev/null +++ b/assets/js/videojs-mobile-ui.min.js @@ -0,0 +1,7 @@ +/** + * videojs-mobile-ui + * @version 0.5.2 + * @copyright 2021 mister-ben <git@misterben.me> + * @license MIT + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("video.js"),require("global/window")):"function"==typeof define&&define.amd?define(["video.js","global/window"],t):e.videojsMobileUi=t(e.videojs,e.window)}(this,function(e,t){"use strict";e=e&&e.hasOwnProperty("default")?e.default:e,t=t&&t.hasOwnProperty("default")?t.default:t;var n=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},o=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},i=e.getComponent("Component"),r=e.dom||e,a=function(e){function i(t,r){n(this,i);var a=o(this,e.call(this,t,r));return a.seekSeconds=r.seekSeconds,a.tapTimeout=r.tapTimeout,a.addChild("playToggle",{}),t.on(["playing","userinactive"],function(e){a.removeClass("show-play-toggle")}),0===a.player_.options_.inactivityTimeout&&(a.player_.options_.inactivityTimeout=5e3),a.enable(),a}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(i,e),i.prototype.createEl=function(){return r.createEl("div",{className:"vjs-touch-overlay",tabIndex:-1})},i.prototype.handleTap=function(e){var n=this;e.target===this.el_&&(e.preventDefault(),this.firstTapCaptured?(this.firstTapCaptured=!1,this.timeout&&t.clearTimeout(this.timeout),this.handleDoubleTap(e)):(this.firstTapCaptured=!0,this.timeout=t.setTimeout(function(){n.firstTapCaptured=!1,n.handleSingleTap(e)},this.tapTimeout)))},i.prototype.handleSingleTap=function(e){this.removeClass("skip"),this.toggleClass("show-play-toggle")},i.prototype.handleDoubleTap=function(e){var n=this,o=this.el_.getBoundingClientRect(),i=e.changedTouches[0].clientX-o.left;if(i<.4*o.width)this.player_.currentTime(Math.max(0,this.player_.currentTime()-this.seekSeconds)),this.addClass("reverse");else{if(!(i>o.width-.4*o.width))return;this.player_.currentTime(Math.min(this.player_.duration(),this.player_.currentTime()+this.seekSeconds)),this.removeClass("reverse")}this.removeClass("show-play-toggle"),this.removeClass("skip"),t.requestAnimationFrame(function(){n.addClass("skip")})},i.prototype.enable=function(){this.firstTapCaptured=!1,this.on("touchend",this.handleTap)},i.prototype.disable=function(){this.off("touchend",this.handleTap)},i}(i);i.registerComponent("TouchOverlay",a);var s={fullscreen:{enterOnRotate:!0,exitOnRotate:!0,lockOnRotate:!0,iOS:!1},touchControls:{seekSeconds:10,tapTimeout:300,disableOnEnd:!1}},l=t.screen,u=function(n,o){n.addClass("vjs-mobile-ui"),(o.touchControls.disableOnEnd||"function"==typeof n.endscreen)&&n.addClass("vjs-mobile-ui-disable-end"),o.fullscreen.iOS&&e.browser.IS_IOS&&e.browser.IOS_VERSION>9&&!n.el_.ownerDocument.querySelector(".bc-iframe")&&(n.tech_.el_.setAttribute("playsinline","playsinline"),n.tech_.supportsFullScreen=function(){return!1});var i=void 0,r=e.VERSION.split("."),a=parseInt(r[0],10),s=parseInt(r[1],10);i=a<7||7===a&&s<7?Array.prototype.indexOf.call(n.el_.children,n.getChild("ControlBar").el_):n.children_.indexOf(n.getChild("ControlBar")),n.addChild("TouchOverlay",o.touchControls,i);var u=!1,c=function(){var i="number"==typeof t.orientation?t.orientation:l&&l.orientation&&l.orientation.angle?t.orientation:(e.log("angle unknown"),0);90!==i&&270!==i&&-90!==i||!o.enterOnRotate||!1===n.paused()&&(n.requestFullscreen(),o.fullscreen.lockOnRotate&&l.orientation&&l.orientation.lock&&l.orientation.lock("landscape").then(function(){u=!0}).catch(function(){e.log("orientation lock not allowed")})),0!==i&&180!==i||!o.exitOnRotate||n.isFullscreen()&&n.exitFullscreen()};e.browser.IS_IOS?t.addEventListener("orientationchange",c):l.orientation&&(l.orientation.onchange=c),n.on("ended",function(e){!0===u&&(l.orientation.unlock(),u=!1)})},c=function(){var t=this,n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(n.forceForTesting||e.browser.IS_ANDROID||e.browser.IS_IOS)&&this.ready(function(){u(t,e.mergeOptions(s,n))})};return(e.registerPlugin||e.plugin)("mobileUi",c),c.VERSION="0.5.2",c});
\ No newline at end of file |
