Prevent hotkeys playback rate/seek with lives
This commit is contained in:
parent
b27bce21f0
commit
66b73484c7
|
@ -133,8 +133,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
this.loadRouteParams()
|
this.loadRouteParams()
|
||||||
this.loadRouteQuery()
|
this.loadRouteQuery()
|
||||||
|
|
||||||
this.initHotkeys()
|
|
||||||
|
|
||||||
this.theaterEnabled = getStoredTheater()
|
this.theaterEnabled = getStoredTheater()
|
||||||
|
|
||||||
this.hooks.runAction('action:video-watch.init', 'video-watch')
|
this.hooks.runAction('action:video-watch.init', 'video-watch')
|
||||||
|
@ -407,6 +405,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
if (res === false) return this.location.back()
|
if (res === false) return this.location.back()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.buildHotkeysHelp(video)
|
||||||
|
|
||||||
this.buildPlayer({ urlOptions, loggedInOrAnonymousUser, forceAutoplay })
|
this.buildPlayer({ urlOptions, loggedInOrAnonymousUser, forceAutoplay })
|
||||||
.catch(err => logger.error('Cannot build the player', err))
|
.catch(err => logger.error('Cannot build the player', err))
|
||||||
|
|
||||||
|
@ -787,18 +787,32 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
this.video.viewers = newViewers
|
this.video.viewers = newViewers
|
||||||
}
|
}
|
||||||
|
|
||||||
private initHotkeys () {
|
private buildHotkeysHelp (video: Video) {
|
||||||
|
if (this.hotkeys.length !== 0) {
|
||||||
|
this.hotkeysService.remove(this.hotkeys)
|
||||||
|
}
|
||||||
|
|
||||||
this.hotkeys = [
|
this.hotkeys = [
|
||||||
// These hotkeys are managed by the player
|
// These hotkeys are managed by the player
|
||||||
new Hotkey('f', e => e, undefined, $localize`Enter/exit fullscreen`),
|
new Hotkey('f', e => e, undefined, $localize`Enter/exit fullscreen`),
|
||||||
new Hotkey('space', e => e, undefined, $localize`Play/Pause the video`),
|
new Hotkey('space', e => e, undefined, $localize`Play/Pause the video`),
|
||||||
new Hotkey('m', e => e, undefined, $localize`Mute/unmute the video`),
|
new Hotkey('m', e => e, undefined, $localize`Mute/unmute the video`),
|
||||||
|
|
||||||
new Hotkey('0-9', e => e, undefined, $localize`Skip to a percentage of the video: 0 is 0% and 9 is 90%`),
|
|
||||||
|
|
||||||
new Hotkey('up', e => e, undefined, $localize`Increase the volume`),
|
new Hotkey('up', e => e, undefined, $localize`Increase the volume`),
|
||||||
new Hotkey('down', e => e, undefined, $localize`Decrease the volume`),
|
new Hotkey('down', e => e, undefined, $localize`Decrease the volume`),
|
||||||
|
|
||||||
|
new Hotkey('t', e => {
|
||||||
|
this.theaterEnabled = !this.theaterEnabled
|
||||||
|
return false
|
||||||
|
}, undefined, $localize`Toggle theater mode`)
|
||||||
|
]
|
||||||
|
|
||||||
|
if (!video.isLive) {
|
||||||
|
this.hotkeys = this.hotkeys.concat([
|
||||||
|
// These hotkeys are also managed by the player but only for VOD
|
||||||
|
|
||||||
|
new Hotkey('0-9', e => e, undefined, $localize`Skip to a percentage of the video: 0 is 0% and 9 is 90%`),
|
||||||
|
|
||||||
new Hotkey('right', e => e, undefined, $localize`Seek the video forward`),
|
new Hotkey('right', e => e, undefined, $localize`Seek the video forward`),
|
||||||
new Hotkey('left', e => e, undefined, $localize`Seek the video backward`),
|
new Hotkey('left', e => e, undefined, $localize`Seek the video backward`),
|
||||||
|
|
||||||
|
@ -806,13 +820,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
||||||
new Hotkey('<', e => e, undefined, $localize`Decrease playback rate`),
|
new Hotkey('<', e => e, undefined, $localize`Decrease playback rate`),
|
||||||
|
|
||||||
new Hotkey(',', e => e, undefined, $localize`Navigate in the video to the previous frame`),
|
new Hotkey(',', e => e, undefined, $localize`Navigate in the video to the previous frame`),
|
||||||
new Hotkey('.', e => e, undefined, $localize`Navigate in the video to the next frame`),
|
new Hotkey('.', e => e, undefined, $localize`Navigate in the video to the next frame`)
|
||||||
|
])
|
||||||
new Hotkey('t', e => {
|
}
|
||||||
this.theaterEnabled = !this.theaterEnabled
|
|
||||||
return false
|
|
||||||
}, undefined, $localize`Toggle theater mode`)
|
|
||||||
]
|
|
||||||
|
|
||||||
if (this.isUserLoggedIn()) {
|
if (this.isUserLoggedIn()) {
|
||||||
this.hotkeys = this.hotkeys.concat([
|
this.hotkeys = this.hotkeys.concat([
|
||||||
|
|
|
@ -123,7 +123,7 @@ export class PeertubePlayerManager {
|
||||||
self.addContextMenu(videojsOptionsBuilder, player, options.common)
|
self.addContextMenu(videojsOptionsBuilder, player, options.common)
|
||||||
|
|
||||||
if (isMobile()) player.peertubeMobile()
|
if (isMobile()) player.peertubeMobile()
|
||||||
if (options.common.enableHotkeys === true) player.peerTubeHotkeysPlugin()
|
if (options.common.enableHotkeys === true) player.peerTubeHotkeysPlugin({ isLive: options.common.isLive })
|
||||||
if (options.common.controlBar === false) player.controlBar.addClass('control-bar-hidden')
|
if (options.common.controlBar === false) player.controlBar.addClass('control-bar-hidden')
|
||||||
|
|
||||||
player.bezels()
|
player.bezels()
|
||||||
|
|
|
@ -4,6 +4,10 @@ type KeyHandler = { accept: (event: KeyboardEvent) => boolean, cb: (e: KeyboardE
|
||||||
|
|
||||||
const Plugin = videojs.getPlugin('plugin')
|
const Plugin = videojs.getPlugin('plugin')
|
||||||
|
|
||||||
|
export type HotkeysOptions = {
|
||||||
|
isLive: boolean
|
||||||
|
}
|
||||||
|
|
||||||
class PeerTubeHotkeysPlugin extends Plugin {
|
class PeerTubeHotkeysPlugin extends Plugin {
|
||||||
private static readonly VOLUME_STEP = 0.1
|
private static readonly VOLUME_STEP = 0.1
|
||||||
private static readonly SEEK_STEP = 5
|
private static readonly SEEK_STEP = 5
|
||||||
|
@ -12,9 +16,13 @@ class PeerTubeHotkeysPlugin extends Plugin {
|
||||||
|
|
||||||
private readonly handlers: KeyHandler[]
|
private readonly handlers: KeyHandler[]
|
||||||
|
|
||||||
constructor (player: videojs.Player, options: videojs.PlayerOptions) {
|
private readonly isLive: boolean
|
||||||
|
|
||||||
|
constructor (player: videojs.Player, options: videojs.PlayerOptions & HotkeysOptions) {
|
||||||
super(player, options)
|
super(player, options)
|
||||||
|
|
||||||
|
this.isLive = options.isLive
|
||||||
|
|
||||||
this.handlers = this.buildHandlers()
|
this.handlers = this.buildHandlers()
|
||||||
|
|
||||||
this.handleKeyFunction = (event: KeyboardEvent) => this.onKeyDown(event)
|
this.handleKeyFunction = (event: KeyboardEvent) => this.onKeyDown(event)
|
||||||
|
@ -68,28 +76,6 @@ class PeerTubeHotkeysPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// Rewind
|
|
||||||
{
|
|
||||||
accept: e => this.isNaked(e, 'ArrowLeft') || this.isNaked(e, 'MediaRewind'),
|
|
||||||
cb: e => {
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
const target = Math.max(0, this.player.currentTime() - PeerTubeHotkeysPlugin.SEEK_STEP)
|
|
||||||
this.player.currentTime(target)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Forward
|
|
||||||
{
|
|
||||||
accept: e => this.isNaked(e, 'ArrowRight') || this.isNaked(e, 'MediaForward'),
|
|
||||||
cb: e => {
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
const target = Math.min(this.player.duration(), this.player.currentTime() + PeerTubeHotkeysPlugin.SEEK_STEP)
|
|
||||||
this.player.currentTime(target)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
// Fullscreen
|
// Fullscreen
|
||||||
{
|
{
|
||||||
// f key or Ctrl + Enter
|
// f key or Ctrl + Enter
|
||||||
|
@ -116,6 +102,8 @@ class PeerTubeHotkeysPlugin extends Plugin {
|
||||||
{
|
{
|
||||||
accept: e => e.key === '>',
|
accept: e => e.key === '>',
|
||||||
cb: () => {
|
cb: () => {
|
||||||
|
if (this.isLive) return
|
||||||
|
|
||||||
const target = Math.min(this.player.playbackRate() + 0.1, 5)
|
const target = Math.min(this.player.playbackRate() + 0.1, 5)
|
||||||
|
|
||||||
this.player.playbackRate(parseFloat(target.toFixed(2)))
|
this.player.playbackRate(parseFloat(target.toFixed(2)))
|
||||||
|
@ -126,6 +114,8 @@ class PeerTubeHotkeysPlugin extends Plugin {
|
||||||
{
|
{
|
||||||
accept: e => e.key === '<',
|
accept: e => e.key === '<',
|
||||||
cb: () => {
|
cb: () => {
|
||||||
|
if (this.isLive) return
|
||||||
|
|
||||||
const target = Math.max(this.player.playbackRate() - 0.1, 0.10)
|
const target = Math.max(this.player.playbackRate() - 0.1, 0.10)
|
||||||
|
|
||||||
this.player.playbackRate(parseFloat(target.toFixed(2)))
|
this.player.playbackRate(parseFloat(target.toFixed(2)))
|
||||||
|
@ -136,6 +126,8 @@ class PeerTubeHotkeysPlugin extends Plugin {
|
||||||
{
|
{
|
||||||
accept: e => e.key === ',',
|
accept: e => e.key === ',',
|
||||||
cb: () => {
|
cb: () => {
|
||||||
|
if (this.isLive) return
|
||||||
|
|
||||||
this.player.pause()
|
this.player.pause()
|
||||||
|
|
||||||
// Calculate movement distance (assuming 30 fps)
|
// Calculate movement distance (assuming 30 fps)
|
||||||
|
@ -148,6 +140,8 @@ class PeerTubeHotkeysPlugin extends Plugin {
|
||||||
{
|
{
|
||||||
accept: e => e.key === '.',
|
accept: e => e.key === '.',
|
||||||
cb: () => {
|
cb: () => {
|
||||||
|
if (this.isLive) return
|
||||||
|
|
||||||
this.player.pause()
|
this.player.pause()
|
||||||
|
|
||||||
// Calculate movement distance (assuming 30 fps)
|
// Calculate movement distance (assuming 30 fps)
|
||||||
|
@ -157,11 +151,47 @@ class PeerTubeHotkeysPlugin extends Plugin {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if (this.isLive) return handlers
|
||||||
|
|
||||||
|
return handlers.concat(this.buildVODHandlers())
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildVODHandlers () {
|
||||||
|
const handlers: KeyHandler[] = [
|
||||||
|
// Rewind
|
||||||
|
{
|
||||||
|
accept: e => this.isNaked(e, 'ArrowLeft') || this.isNaked(e, 'MediaRewind'),
|
||||||
|
cb: e => {
|
||||||
|
if (this.isLive) return
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
const target = Math.max(0, this.player.currentTime() - PeerTubeHotkeysPlugin.SEEK_STEP)
|
||||||
|
this.player.currentTime(target)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// Forward
|
||||||
|
{
|
||||||
|
accept: e => this.isNaked(e, 'ArrowRight') || this.isNaked(e, 'MediaForward'),
|
||||||
|
cb: e => {
|
||||||
|
if (this.isLive) return
|
||||||
|
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
const target = Math.min(this.player.duration(), this.player.currentTime() + PeerTubeHotkeysPlugin.SEEK_STEP)
|
||||||
|
this.player.currentTime(target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
// 0-9 key handlers
|
// 0-9 key handlers
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
handlers.push({
|
handlers.push({
|
||||||
accept: e => this.isNakedOrShift(e, i + ''),
|
accept: e => this.isNakedOrShift(e, i + ''),
|
||||||
cb: e => {
|
cb: e => {
|
||||||
|
if (this.isLive) return
|
||||||
|
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
||||||
this.player.currentTime(this.player.duration() * i * 0.1)
|
this.player.currentTime(this.player.duration() * i * 0.1)
|
||||||
|
|
|
@ -3,6 +3,7 @@ import videojs from 'video.js'
|
||||||
import { Engine } from '@peertube/p2p-media-loader-hlsjs'
|
import { Engine } from '@peertube/p2p-media-loader-hlsjs'
|
||||||
import { VideoFile, VideoPlaylist, VideoPlaylistElement } from '@shared/models'
|
import { VideoFile, VideoPlaylist, VideoPlaylistElement } from '@shared/models'
|
||||||
import { PeerTubeDockPluginOptions } from '../shared/dock/peertube-dock-plugin'
|
import { PeerTubeDockPluginOptions } from '../shared/dock/peertube-dock-plugin'
|
||||||
|
import { HotkeysOptions } from '../shared/hotkeys/peertube-hotkeys-plugin'
|
||||||
import { Html5Hlsjs } from '../shared/p2p-media-loader/hls-plugin'
|
import { Html5Hlsjs } from '../shared/p2p-media-loader/hls-plugin'
|
||||||
import { P2pMediaLoaderPlugin } from '../shared/p2p-media-loader/p2p-media-loader-plugin'
|
import { P2pMediaLoaderPlugin } from '../shared/p2p-media-loader/p2p-media-loader-plugin'
|
||||||
import { RedundancyUrlManager } from '../shared/p2p-media-loader/redundancy-url-manager'
|
import { RedundancyUrlManager } from '../shared/p2p-media-loader/redundancy-url-manager'
|
||||||
|
@ -44,7 +45,7 @@ declare module 'video.js' {
|
||||||
|
|
||||||
bezels (): void
|
bezels (): void
|
||||||
peertubeMobile (): void
|
peertubeMobile (): void
|
||||||
peerTubeHotkeysPlugin (): void
|
peerTubeHotkeysPlugin (options?: HotkeysOptions): void
|
||||||
|
|
||||||
stats (options?: StatsCardOptions): StatsForNerdsPlugin
|
stats (options?: StatsCardOptions): StatsForNerdsPlugin
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user