Add volume control using scroll wheel from myzel, with flow errors fixed (#1638)
* created function * removed console logs * made volume change on mousewheel functional * improved code * added precise volume control * updated behavior * fixed error * fix flow errors Co-authored-by: myzel394 <50424412+Myzel394@users.noreply.github.com>
This commit is contained in:
parent
c146ccc432
commit
8aaa820e2f
2 changed files with 100 additions and 14 deletions
|
@ -6,6 +6,8 @@ import isUserTyping from 'util/detect-typing';
|
|||
|
||||
const SEEK_STEP_5 = 5;
|
||||
const SEEK_STEP = 10; // time to seek in seconds
|
||||
const VOLUME_CHANGE_ON_SCROLL = 0.05;
|
||||
const PRECISE_VOLUME_CHANGE_ON_SCROLL = 0.01;
|
||||
|
||||
// check if active (clicked) element is part of video div, used for keyboard shortcuts (volume etc)
|
||||
function activeElementIsPartOfVideoElement() {
|
||||
|
@ -14,24 +16,24 @@ function activeElementIsPartOfVideoElement() {
|
|||
return videoElementParent.contains(activeElement);
|
||||
}
|
||||
|
||||
function volumeUp(event, playerRef) {
|
||||
function volumeUp(event, playerRef, checkIsActive = true, amount = 0.05) {
|
||||
// dont run if video element is not active element (otherwise runs when scrolling using keypad)
|
||||
const videoElementIsActive = activeElementIsPartOfVideoElement();
|
||||
const player = playerRef.current;
|
||||
if (!player || !videoElementIsActive) return;
|
||||
if (!player || (checkIsActive && !videoElementIsActive)) return;
|
||||
event.preventDefault();
|
||||
player.volume(player.volume() + 0.05);
|
||||
player.volume(player.volume() + amount);
|
||||
OVERLAY.showVolumeverlay(player, Math.round(player.volume() * 100));
|
||||
player.userActive(true);
|
||||
}
|
||||
|
||||
function volumeDown(event, playerRef) {
|
||||
function volumeDown(event, playerRef, checkIsActive = true, amount = 0.05) {
|
||||
// dont run if video element is not active element (otherwise runs when scrolling using keypad)
|
||||
const videoElementIsActive = activeElementIsPartOfVideoElement();
|
||||
const player = playerRef.current;
|
||||
if (!player || !videoElementIsActive) return;
|
||||
if (!player || (checkIsActive && !videoElementIsActive)) return;
|
||||
event.preventDefault();
|
||||
player.volume(player.volume() - 0.05);
|
||||
player.volume(player.volume() - amount);
|
||||
OVERLAY.showVolumeverlay(player, Math.round(player.volume() * 100));
|
||||
player.userActive(true);
|
||||
}
|
||||
|
@ -94,7 +96,7 @@ function changePlaybackSpeed(shouldSpeedUp: boolean, playerRef) {
|
|||
}
|
||||
}
|
||||
|
||||
const VideoJsKeyboardShorcuts = ({
|
||||
const VideoJsShorcuts = ({
|
||||
playNext,
|
||||
playPrevious,
|
||||
toggleVideoTheaterMode,
|
||||
|
@ -163,15 +165,65 @@ const VideoJsKeyboardShorcuts = ({
|
|||
if (e.keyCode === KEYCODES.NINE) seekVideo(90 / 100, playerRef, containerRef, true);
|
||||
}
|
||||
|
||||
var curried_function = function (playerRef: any, containerRef: any) {
|
||||
const handleVideoScrollWheel = (event, playerRef, containerRef) => {
|
||||
// Handle precise volume control when scrolling over the video player while holding down the "SHIFT"-key
|
||||
const player = playerRef.current;
|
||||
const videoNode = containerRef.current && containerRef.current.querySelector('video');
|
||||
|
||||
if (!videoNode || !player || isUserTyping() || !event.shiftKey) return;
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
const delta = event.deltaY;
|
||||
|
||||
if (delta > 0) {
|
||||
volumeDown(event, playerRef, false, PRECISE_VOLUME_CHANGE_ON_SCROLL);
|
||||
} else if (delta < 0) {
|
||||
volumeUp(event, playerRef, false, PRECISE_VOLUME_CHANGE_ON_SCROLL);
|
||||
}
|
||||
};
|
||||
|
||||
const handleVolumeBarScrollWheel = (event, volumeElement, playerRef, containerRef) => {
|
||||
// Handle generic and precise volume control when scrolling over the volume bar
|
||||
const player = playerRef.current;
|
||||
const videoNode = containerRef.current && containerRef.current.querySelector('video');
|
||||
|
||||
if (!volumeElement || !player || !videoNode || isUserTyping()) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
|
||||
const delta = event.deltaY;
|
||||
const changeAmount = event.shiftKey ? PRECISE_VOLUME_CHANGE_ON_SCROLL : VOLUME_CHANGE_ON_SCROLL;
|
||||
|
||||
if (delta > 0) {
|
||||
volumeDown(event, playerRef, false, changeAmount);
|
||||
} else if (delta < 0) {
|
||||
volumeUp(event, playerRef, false, changeAmount);
|
||||
}
|
||||
};
|
||||
|
||||
const createKeyDownShortcutsHandler = function (playerRef: any, containerRef: any) {
|
||||
return function curried_func(e: any) {
|
||||
handleKeyDown(e, playerRef, containerRef);
|
||||
};
|
||||
};
|
||||
const createVideoScrollShortcutsHandler = function (playerRef: any, containerRef: any) {
|
||||
return function curried_func(e: any) {
|
||||
handleVideoScrollWheel(e, playerRef, containerRef);
|
||||
};
|
||||
};
|
||||
const createVolumePanelScrollShortcutsHandler = function (volumeElement: any, playerRef: any, containerRef: any) {
|
||||
return function curried_func(e: any) {
|
||||
handleVolumeBarScrollWheel(e, volumeElement, playerRef, containerRef);
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
curried_function,
|
||||
createKeyDownShortcutsHandler,
|
||||
createVideoScrollShortcutsHandler,
|
||||
createVolumePanelScrollShortcutsHandler,
|
||||
};
|
||||
};
|
||||
|
||||
export default VideoJsKeyboardShorcuts;
|
||||
export default VideoJsShorcuts;
|
|
@ -15,7 +15,7 @@ import events from './videojs-events';
|
|||
import eventTracking from 'videojs-event-tracking';
|
||||
import functions from './videojs-functions';
|
||||
import hlsQualitySelector from './plugins/videojs-hls-quality-selector/plugin';
|
||||
import keyboardShorcuts from './videojs-keyboard-shortcuts';
|
||||
import keyboardShorcuts from './videojs-shortcuts';
|
||||
import LbryVolumeBarClass from './lbry-volume-bar';
|
||||
import Chromecast from './chromecast';
|
||||
import playerjs from 'player.js';
|
||||
|
@ -103,6 +103,8 @@ type Props = {
|
|||
activeLivestreamForChannel: any,
|
||||
doToast: ({ message: string, linkText: string, linkTarget: string }) => void,
|
||||
};
|
||||
const VIDEOJS_CONTROL_BAR_CLASS = 'ControlBar';
|
||||
const VIDEOJS_VOLUME_PANEL_CLASS = 'VolumePanel';
|
||||
|
||||
const IS_IOS = platform.isIOS();
|
||||
const IS_MOBILE = platform.isMobile();
|
||||
|
@ -176,13 +178,22 @@ export default React.memo<Props>(function VideoJs(props: Props) {
|
|||
const tapToUnmuteRef = useRef();
|
||||
const tapToRetryRef = useRef();
|
||||
const playerServerRef = useRef();
|
||||
const volumePanelRef = useRef();
|
||||
|
||||
const keyDownHandlerRef = useRef();
|
||||
const videoScrollHandlerRef = useRef();
|
||||
const volumePanelScrollHandlerRef = useRef();
|
||||
|
||||
const { url: livestreamVideoUrl } = activeLivestreamForChannel || {};
|
||||
const overrideNativeVhs = !platform.isIPhone();
|
||||
const showQualitySelector = (!isLivestreamClaim && overrideNativeVhs) || livestreamVideoUrl;
|
||||
|
||||
// initiate keyboard shortcuts
|
||||
const { curried_function } = keyboardShorcuts({
|
||||
const {
|
||||
createKeyDownShortcutsHandler,
|
||||
createVideoScrollShortcutsHandler,
|
||||
createVolumePanelScrollShortcutsHandler,
|
||||
} = keyboardShorcuts({
|
||||
isMobile,
|
||||
isLivestreamClaim,
|
||||
toggleVideoTheaterMode,
|
||||
|
@ -370,7 +381,23 @@ export default React.memo<Props>(function VideoJs(props: Props) {
|
|||
// Set reference in component state
|
||||
playerRef.current = vjsPlayer;
|
||||
|
||||
window.addEventListener('keydown', curried_function(playerRef, containerRef));
|
||||
// volume control div, used for changing volume when scrolled over
|
||||
volumePanelRef.current = playerRef.current
|
||||
.getChild(VIDEOJS_CONTROL_BAR_CLASS)
|
||||
.getChild(VIDEOJS_VOLUME_PANEL_CLASS)
|
||||
.el();
|
||||
|
||||
const keyDownHandler = createKeyDownShortcutsHandler(playerRef, containerRef);
|
||||
const videoScrollHandler = createVideoScrollShortcutsHandler(playerRef, containerRef);
|
||||
const volumePanelHandler = createVolumePanelScrollShortcutsHandler(volumePanelRef, playerRef, containerRef);
|
||||
window.addEventListener('keydown', keyDownHandler);
|
||||
const containerDiv = containerRef.current;
|
||||
containerDiv && containerDiv.addEventListener('wheel', videoScrollHandler);
|
||||
if (volumePanelRef.current) volumePanelRef.current.addEventListener('wheel', volumePanelHandler);
|
||||
|
||||
keyDownHandlerRef.current = keyDownHandler;
|
||||
videoScrollHandlerRef.current = videoScrollHandler;
|
||||
volumePanelScrollHandlerRef.current = volumePanelHandler;
|
||||
|
||||
const controlBar = document.querySelector('.vjs-control-bar');
|
||||
if (controlBar) {
|
||||
|
@ -441,7 +468,14 @@ export default React.memo<Props>(function VideoJs(props: Props) {
|
|||
|
||||
// Cleanup
|
||||
return () => {
|
||||
window.removeEventListener('keydown', curried_function);
|
||||
window.removeEventListener('keydown', keyDownHandlerRef.current);
|
||||
const containerDiv = containerRef.current;
|
||||
// $FlowFixMe
|
||||
containerDiv && containerDiv.removeEventListener('wheel', videoScrollHandlerRef.current);
|
||||
|
||||
if (volumePanelRef.current) {
|
||||
volumePanelRef.current.removeEventListener('wheel', volumePanelScrollHandlerRef.current);
|
||||
}
|
||||
|
||||
const player = playerRef.current;
|
||||
if (player) {
|
||||
|
|
Loading…
Reference in a new issue