-// FIXME: something weird with our path definition in tsconfig and typings
-// @ts-ignore
-import * as videojs from 'video.js'
+import videojs from 'video.js'
import './videojs-components/settings-menu-button'
import {
PeerTubePluginOptions,
ResolutionUpdateData,
UserWatching,
- VideoJSCaption,
- VideoJSComponentInterface,
- videojsUntyped
+ VideoJSCaption
} from './peertube-videojs-typings'
import { isMobile, timeToInt } from './utils'
import {
saveVolumeInStore
} from './peertube-player-local-storage'
-const Plugin: VideoJSComponentInterface = videojs.getPlugin('plugin')
+const Plugin = videojs.getPlugin('plugin')
+
class PeerTubePlugin extends Plugin {
private readonly videoViewUrl: string
private readonly videoDuration: number
USER_WATCHING_VIDEO_INTERVAL: 5000 // Every 5 seconds, notify the user is watching the video
}
- private player: any
private videoCaptions: VideoJSCaption[]
private defaultSubtitle: string
private userWatchingVideoInterval: any
private lastResolutionChange: ResolutionUpdateData
- constructor (player: videojs.Player, options: PeerTubePluginOptions) {
- super(player, options)
+ private isLive: boolean
+
+ private menuOpened = false
+ private mouseInControlBar = false
+ private readonly savedInactivityTimeout: number
+
+ constructor (player: videojs.Player, options?: PeerTubePluginOptions) {
+ super(player)
this.videoViewUrl = options.videoViewUrl
this.videoDuration = options.videoDuration
this.videoCaptions = options.videoCaptions
+ this.isLive = options.isLive
- if (options.autoplay === true) this.player.addClass('vjs-has-autoplay')
+ this.savedInactivityTimeout = player.options_.inactivityTimeout
+
+ if (options.autoplay) this.player.addClass('vjs-has-autoplay')
this.player.on('autoplay-failure', () => {
this.player.removeClass('vjs-has-autoplay')
this.player.p2pMediaLoader().on('resolutionChange', (_: any, d: any) => this.handleResolutionChange(d))
}
- this.player.tech_.on('loadedqualitydata', () => {
+ this.player.tech(true).on('loadedqualitydata', () => {
setTimeout(() => {
// Replay a resolution change, now we loaded all quality data
if (this.lastResolutionChange) this.handleResolutionChange(this.lastResolutionChange)
}
this.player.textTracks().on('change', () => {
- const showing = this.player.textTracks().tracks_.find((t: { kind: string, mode: string }) => {
+ const showing = this.player.textTracks().tracks_.find(t => {
return t.kind === 'captions' && t.mode === 'showing'
})
if (this.userWatchingVideoInterval) clearInterval(this.userWatchingVideoInterval)
}
+ onMenuOpen () {
+ this.menuOpened = false
+ this.alterInactivity()
+ }
+
+ onMenuClosed () {
+ this.menuOpened = true
+ this.alterInactivity()
+ }
+
private initializePlayer () {
if (isMobile()) this.player.addClass('vjs-is-mobile')
this.initCaptions()
- this.alterInactivity()
+ this.listenControlBarMouse()
}
private runViewAdd () {
// After 30 seconds (or 3/4 of the video), add a view to the video
let minSecondsToView = 30
- if (this.videoDuration < minSecondsToView) minSecondsToView = (this.videoDuration * 3) / 4
+ if (!this.isLive && this.videoDuration < minSecondsToView) {
+ minSecondsToView = (this.videoDuration * 3) / 4
+ }
let secondsViewed = 0
this.videoViewInterval = setInterval(() => {
secondsViewed += 1
if (secondsViewed > minSecondsToView) {
- this.clearVideoViewInterval()
+ // Restart the loop if this is a live
+ if (this.isLive) {
+ secondsViewed = 0
+ } else {
+ this.clearVideoViewInterval()
+ }
this.addViewToVideo().catch(err => console.error(err))
}
this.trigger('resolutionChange', data)
}
- private alterInactivity () {
- let saveInactivityTimeout: number
+ private listenControlBarMouse () {
+ this.player.controlBar.on('mouseenter', () => {
+ this.mouseInControlBar = true
+ this.alterInactivity()
+ })
- const disableInactivity = () => {
- saveInactivityTimeout = this.player.options_.inactivityTimeout
- this.player.options_.inactivityTimeout = 0
- }
- const enableInactivity = () => {
- this.player.options_.inactivityTimeout = saveInactivityTimeout
+ this.player.controlBar.on('mouseleave', () => {
+ this.mouseInControlBar = false
+ this.alterInactivity()
+ })
+ }
+
+ private alterInactivity () {
+ if (this.menuOpened) {
+ this.player.options_.inactivityTimeout = this.savedInactivityTimeout
+ return
}
- const settingsDialog = this.player.children_.find((c: any) => c.name_ === 'SettingsDialog')
+ if (!this.mouseInControlBar && !this.isTouchEnabled()) {
+ this.player.options_.inactivityTimeout = 1
+ }
+ }
- this.player.controlBar.on('mouseenter', () => disableInactivity())
- settingsDialog.on('mouseenter', () => disableInactivity())
- this.player.controlBar.on('mouseleave', () => enableInactivity())
- settingsDialog.on('mouseleave', () => enableInactivity())
+ private isTouchEnabled () {
+ return ('ontouchstart' in window) ||
+ navigator.maxTouchPoints > 0 ||
+ navigator.msMaxTouchPoints > 0
}
private initCaptions () {
// Thanks: https://github.com/videojs/video.js/issues/4460#issuecomment-312861657
private initSmoothProgressBar () {
- const SeekBar = videojsUntyped.getComponent('SeekBar')
+ const SeekBar = videojs.getComponent('SeekBar') as any
SeekBar.prototype.getPercent = function getPercent () {
// Allows for smooth scrubbing, when player can't keep up.
// const time = (this.player_.scrubbing()) ?