summaryrefslogtreecommitdiffstats
path: root/assets/js/player.js
diff options
context:
space:
mode:
Diffstat (limited to 'assets/js/player.js')
-rw-r--r--assets/js/player.js110
1 files changed, 106 insertions, 4 deletions
diff --git a/assets/js/player.js b/assets/js/player.js
index 5d045391..a461c53d 100644
--- a/assets/js/player.js
+++ b/assets/js/player.js
@@ -14,11 +14,18 @@ var options = {
'durationDisplay',
'progressControl',
'remainingTimeDisplay',
+ 'Spacer',
'captionsButton',
'qualitySelector',
'playbackRateMenuButton',
'fullscreenToggle'
]
+ },
+ html5: {
+ preloadTextTracks: false,
+ hls: {
+ overrideNative: true
+ }
}
}
@@ -67,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) {
@@ -92,6 +148,17 @@ player.on('error', function (event) {
}
});
+// Enable VR video support
+if (!video_data.params.listen && video_data.vr && video_data.params.vr_mode) {
+ player.crossOrigin("anonymous")
+ switch (video_data.projection_type) {
+ case "EQUIRECTANGULAR":
+ player.vr({projection: "equirectangular"});
+ default: // Should only be "MESH" but we'll use this as a fallback.
+ player.vr({projection: "EAC"});
+ }
+}
+
// Add markers
if (video_data.params.video_start > 0 || video_data.params.video_end > 0) {
var markers = [{ time: video_data.params.video_start, text: 'Start' }];
@@ -425,17 +492,17 @@ window.addEventListener('keydown', e => {
case 'ArrowRight':
case 'MediaFastForward':
- action = skip_seconds.bind(this, 5);
+ action = skip_seconds.bind(this, 5 * player.playbackRate());
break;
case 'ArrowLeft':
case 'MediaTrackPrevious':
- action = skip_seconds.bind(this, -5);
+ action = skip_seconds.bind(this, -5 * player.playbackRate());
break;
case 'l':
- action = skip_seconds.bind(this, 10);
+ action = skip_seconds.bind(this, 10 * player.playbackRate());
break;
case 'j':
- action = skip_seconds.bind(this, -10);
+ action = skip_seconds.bind(this, -10 * player.playbackRate());
break;
case '0':
@@ -542,3 +609,38 @@ window.addEventListener('keydown', e => {
if (player.share) {
player.share(shareOptions);
}
+
+// show the preferred caption by default
+if (player_data.preferred_caption_found) {
+ player.ready(() => {
+ player.textTracks()[1].mode = 'showing';
+ });
+}
+
+// Safari audio double duration fix
+if (navigator.vendor == "Apple Computer, Inc." && video_data.params.listen) {
+ player.on('loadedmetadata', function () {
+ player.on('timeupdate', function () {
+ if (player.remainingTime() < player.duration() / 2) {
+ player.currentTime(player.duration() + 1);
+ }
+ });
+ });
+}
+
+// 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)
+};