Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use listener for hotkey support instead of VideoJS hotkeys #326

Merged
merged 1 commit into from
Jan 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 3 additions & 74 deletions src/components/MediaPlayer/MediaPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ const MediaPlayer = ({ enableFileDownload = false, enablePIP = false }) => {
clearCanvasMessageTimer();
} else {
// Create a timer to advance to the next Canvas when autoplay is turned
// on when inaccessible message is been displayed
// on when inaccessible message is been displayed
createCanvasMessageTimer();
}
}
Expand All @@ -102,7 +102,7 @@ const MediaPlayer = ({ enableFileDownload = false, enablePIP = false }) => {
/**
* Initialize the next Canvas to be viewed in the player instance
* @param {Number} canvasId index of the Canvas to be loaded into the player
* @param {Boolean} fromStart flag to indicate how to start new player instance
* @param {Boolean} fromStart flag to indicate how to start new player instance
*/
const initCanvas = (canvasId, fromStart) => {
clearCanvasMessageTimer();
Expand Down Expand Up @@ -256,7 +256,7 @@ const MediaPlayer = ({ enableFileDownload = false, enablePIP = false }) => {
* Switch player when navigating across canvases
* @param {Number} index canvas index to be loaded into the player
* @param {Boolean} fromStart flag to indicate set player start time to zero or not
* @param {String} focusElement element to be focused within the player when using
* @param {String} focusElement element to be focused within the player when using
* next or previous buttons with keyboard
*/
const switchPlayer = (index, fromStart, focusElement = '') => {
Expand Down Expand Up @@ -319,77 +319,6 @@ const MediaPlayer = ({ enableFileDownload = false, enablePIP = false }) => {
? playerConfig.sources[srcIndex]
: playerConfig.sources,
tracks: playerConfig.tracks,
userActions: {
hotkeys: function (event) {
// event.which key code values found at: https://css-tricks.com/snippets/javascript/javascript-keycodes/

// Space and k toggle play/pause
if (event.which === 32 || event.which === 75) {
// Prevent default browser actions so that page does not react when hotkeys are used.
// e.g. pressing space will pause/play without scrolling the page down.
event.preventDefault();

if (this.paused()) {
this.play();
} else {
this.pause();
}
}

// Adapted from https://github.com/videojs/video.js/blob/bad086dad68d3ff16dbe12e434c15e1ee7ac2875/src/js/control-bar/mute-toggle.js#L56
// m toggles mute
if (event.which === 77) {
event.preventDefault();
const vol = this.volume();
const lastVolume = this.lastVolume_();

if (vol === 0) {
const volumeToSet = lastVolume < 0.1 ? 0.1 : lastVolume;

this.volume(volumeToSet);
this.muted(false);
} else {
this.muted(this.muted() ? false : true);
}
}

// f toggles fullscreen
// Fullscreen should only be available for videos
if (event.which === 70 && !this.isAudio()) {
event.preventDefault();

if (!this.isFullscreen()) {
this.requestFullscreen();
} else {
this.exitFullscreen();
}
}

// Right arrow seeks 5 seconds ahead
if (event.which === 39) {
event.preventDefault();
this.currentTime(this.currentTime() + 5);
}

// Left arrow seeks 5 seconds back
if (event.which === 37) {
event.preventDefault();
this.currentTime(this.currentTime() - 5);
}

// Up arrow raises volume by 0.1
if (event.which === 38) {
event.preventDefault();
this.volume(this.volume() + 0.1);
}

// Down arrow lowers volume by 0.1
if (event.which === 40) {
event.preventDefault();
this.volume(this.volume() - 0.1);
}
}
},
// Omit captions in the HLS manifest from loading
html5: {
nativeTextTracks: true,
Expand Down
9 changes: 3 additions & 6 deletions src/components/MediaPlayer/VideoJS/VideoJSPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
getCanvasId,
getCanvasIndex,
} from '@Services/iiif-parser';
import { checkSrcRange, getMediaFragment } from '@Services/utility-helpers';
import { checkSrcRange, getMediaFragment, playerHotKeys } from '@Services/utility-helpers';

/** VideoJS custom components */
import VideoJSProgress from './components/js/VideoJSProgress';
Expand Down Expand Up @@ -153,6 +153,7 @@ function VideoJSPlayer({
return () => {
if (currentPlayerRef.current != null) {
currentPlayerRef.current.dispose();
document.removeEventListener('keydown', playerHotKeys);
setMounted(false);
setIsReady(false);
}
Expand All @@ -168,11 +169,6 @@ function VideoJSPlayer({
player.on('ready', function () {
console.log('Player ready');

// Focus the player for hotkeys to work
if (playerFocusElement == '') {
player.focus();
}

// Add class for volume panel in audio player to make it always visible
if (!isVideo) {
player.getChild('controlBar').getChild('VolumePanel').addClass('vjs-slider-active');
Expand Down Expand Up @@ -272,6 +268,7 @@ function VideoJSPlayer({
player.on('timeupdate', () => {
handleTimeUpdate();
});
document.addEventListener('keydown', playerHotKeys);
}
}, [player]);

Expand Down
83 changes: 83 additions & 0 deletions src/services/utility-helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,86 @@ export function autoScroll(currentItem, containerRef) {
containerRef.current.scrollTop = scrollHeight > inViewHeight
? scrollHeight - containerRef.current.clientHeight / 2 : 0;
};

export function playerHotKeys() {
let player = document.getElementById('iiif-media-player');
let playerInst = player?.player;
var inputs = ['input', 'textarea'];
var activeElement = document.activeElement;

/** Trigger player hotkeys when focus is not on an input, textarea, or navigation tab */
if(activeElement && (inputs.indexOf(activeElement.tagName.toLowerCase()) !== -1 || activeElement.role === "tab")) {
return;
} else {
var pressedKey = event.which
// event.which key code values found at: https://css-tricks.com/snippets/javascript/javascript-keycodes/
switch(pressedKey) {
// Space and k toggle play/pause
case 32:
case 75:
// Prevent default browser actions so that page does not react when hotkeys are used.
// e.g. pressing space will pause/play without scrolling the page down.
event.preventDefault();
if (playerInst.paused()) {
playerInst.play();
} else {
playerInst.pause();
}
break;
// f toggles fullscreen
case 70:
event.preventDefault();
// Fullscreen should only be available for videos
if (!playerInst.isAudio()) {
if (!playerInst.isFullscreen()) {
playerInst.requestFullscreen();
} else {
playerInst.exitFullscreen();
}
}
break;
// Adapted from https://github.com/videojs/video.js/blob/bad086dad68d3ff16dbe12e434c15e1ee7ac2875/src/js/control-bar/mute-toggle.js#L56
// m toggles mute
case 77:
event.preventDefault();

const vol = playerInst.volume();
const lastVolume = playerInst.lastVolume_();

if (vol === 0) {
const volumeToSet = lastVolume < 0.1 ? 0.1 : lastVolume;

playerInst.volume(volumeToSet);
playerInst.muted(false);
} else {
playerInst.muted(playerInst.muted() ? false : true);
}
break;
// Left arrow seeks 5 seconds back
case 37:
event.preventDefault();
playerInst.currentTime(playerInst.currentTime() - 5);
break;
// Right arrow seeks 5 seconds ahead
case 39:
event.preventDefault();
playerInst.currentTime(playerInst.currentTime() + 5);
break;
// Up arrow raises volume by 0.1
case 38:
event.preventDefault();
if (playerInst.muted()) {
playerInst.muted(false)
}
playerInst.volume(playerInst.volume() + 0.1);
break;
// Down arrow lowers volume by 0.1
case 40:
event.preventDefault();
playerInst.volume(playerInst.volume() - 0.1);
break;
default:
return;
}
}
}