import 'videojs-hotkeys/videojs.hotkeys'
import 'videojs-dock'
-import 'videojs-contextmenu-ui'
+import 'videojs-contextmenu-pt'
import 'videojs-contrib-quality-levels'
import './upnext/end-card'
import './upnext/upnext-plugin'
+import './stats/stats-card'
+import './stats/stats-plugin'
import './bezels/bezels-plugin'
import './peertube-plugin'
import './videojs-components/next-previous-video-button'
videoViewUrl: string
embedUrl: string
+ embedTitle: string
isLive: boolean
videoCaptions: VideoJSCaption[]
+ videoUUID: string
+
userWatching?: UserWatching
serverUrl: string
export class PeertubePlayerManager {
private static playerElementClassName: string
private static onPlayerChange: (player: videojs.Player) => void
-
private static alreadyPlayed = false
static initState () {
PeertubePlayerManager.alreadyPlayed = true
})
- self.addContextMenu(mode, player, options.common.embedUrl)
+ self.addContextMenu(mode, player, options.common.embedUrl, options.common.embedTitle)
player.bezels()
+ player.stats({
+ videoUUID: options.common.videoUUID,
+ videoIsLive: options.common.isLive,
+ mode
+ })
return res(player)
})
videojs(newVideoElement, videojsOptions, function (this: videojs.Player) {
const player = this
- self.addContextMenu(mode, player, options.common.embedUrl)
+ self.addContextMenu(mode, player, options.common.embedUrl, options.common.embedTitle)
PeertubePlayerManager.onPlayerChange(player)
})
const isHLS = mode === 'p2p-media-loader'
let autoplay = this.getAutoPlayValue(commonOptions.autoplay)
- let html5 = {}
+ let html5 = {
+ preloadTextTracks: false
+ }
const plugins: VideoJSPluginOptions = {
peertube: {
mode,
- autoplay, // Use peertube plugin autoplay because we get the file by webtorrent
+ autoplay, // Use peertube plugin autoplay because we could get the file by webtorrent
videoViewUrl: commonOptions.videoViewUrl,
videoDuration: commonOptions.videoDuration,
userWatching: commonOptions.userWatching,
subtitle: commonOptions.subtitle,
videoCaptions: commonOptions.videoCaptions,
stopTime: commonOptions.stopTime,
- isLive: commonOptions.isLive
+ isLive: commonOptions.isLive,
+ videoUUID: commonOptions.videoUUID
}
}
if (isHLS) {
const { hlsjs } = PeertubePlayerManager.addP2PMediaLoaderOptions(plugins, options, p2pMediaLoaderModule)
- html5 = hlsjs.html5
+ Object.assign(html5, hlsjs.html5)
}
if (mode === 'webtorrent') {
poster: commonOptions.poster,
inactivityTimeout: commonOptions.inactivityTimeout,
- playbackRates: [ 0.5, 0.75, 1, 1.25, 1.5, 2 ],
+ playbackRates: [ 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2 ],
plugins,
return children
}
- private static addContextMenu (mode: PlayerMode, player: videojs.Player, videoEmbedUrl: string) {
- const content = [
- {
- label: player.localize('Copy the video URL'),
- listener: function () {
- copyToClipboard(buildVideoLink())
- }
- },
- {
- label: player.localize('Copy the video URL at the current time'),
- listener: function (this: videojs.Player) {
- copyToClipboard(buildVideoLink({ startTime: this.currentTime() }))
- }
- },
- {
- label: player.localize('Copy embed code'),
- listener: () => {
- copyToClipboard(buildVideoOrPlaylistEmbed(videoEmbedUrl))
+ private static addContextMenu (mode: PlayerMode, player: videojs.Player, videoEmbedUrl: string, videoEmbedTitle: string) {
+ const content = () => {
+ const isLoopEnabled = player.options_['loop']
+ const items = [
+ {
+ icon: 'repeat',
+ label: player.localize('Play in loop') + (isLoopEnabled ? '<span class="vjs-icon-tick-white"></span>' : ''),
+ listener: function () {
+ player.options_['loop'] = !isLoopEnabled
+ }
+ },
+ {
+ label: player.localize('Copy the video URL'),
+ listener: function () {
+ copyToClipboard(buildVideoLink())
+ }
+ },
+ {
+ label: player.localize('Copy the video URL at the current time'),
+ listener: function (this: videojs.Player) {
+ copyToClipboard(buildVideoLink({ startTime: this.currentTime() }))
+ }
+ },
+ {
+ icon: 'code',
+ label: player.localize('Copy embed code'),
+ listener: () => {
+ copyToClipboard(buildVideoOrPlaylistEmbed(videoEmbedUrl, videoEmbedTitle))
+ }
}
+ ]
+
+ if (mode === 'webtorrent') {
+ items.push({
+ label: player.localize('Copy magnet URI'),
+ listener: function (this: videojs.Player) {
+ copyToClipboard(this.webtorrent().getCurrentVideoFile().magnetUri)
+ }
+ })
}
- ]
- if (mode === 'webtorrent') {
- content.push({
- label: player.localize('Copy magnet URI'),
- listener: function (this: videojs.Player) {
- copyToClipboard(this.webtorrent().getCurrentVideoFile().magnetUri)
+ items.push({
+ icon: 'info',
+ label: player.localize('Stats for nerds'),
+ listener: () => {
+ player.stats().show()
}
})
+
+ return items.map(i => ({
+ ...i,
+ label: `<span class="vjs-icon-${i.icon || 'link-2'}"></span>` + i.label
+ }))
}
+ // adding the menu
player.contextmenuUI({ content })
}
private static addHotkeysOptions (plugins: VideoJSPluginOptions) {
+ const isNaked = (event: KeyboardEvent, key: string) =>
+ (!event.ctrlKey && !event.altKey && !event.metaKey && !event.shiftKey && event.key === key)
+
Object.assign(plugins, {
hotkeys: {
skipInitialFocus: true,
enableVolumeScroll: false,
enableModifiersForNumbers: false,
- fullscreenKey: function (event: KeyboardEvent) {
- // fullscreen with the f key or Ctrl+Enter
- return event.key === 'f' || (event.ctrlKey && event.key === 'Enter')
+ rewindKey: function (event: KeyboardEvent) {
+ return isNaked(event, 'ArrowLeft')
},
- seekStep: function (event: KeyboardEvent) {
- // mimic VLC seek behavior, and default to 5 (original value is 5).
- if (event.ctrlKey && event.altKey) {
- return 5 * 60
- } else if (event.ctrlKey) {
- return 60
- } else if (event.altKey) {
- return 10
- } else {
- return 5
- }
+ forwardKey: function (event: KeyboardEvent) {
+ return isNaked(event, 'ArrowRight')
+ },
+
+ fullscreenKey: function (event: KeyboardEvent) {
+ // fullscreen with the f key or Ctrl+Enter
+ return isNaked(event, 'f') || (!event.altKey && event.ctrlKey && event.key === 'Enter')
},
customKeys: {
increasePlaybackRateKey: {
key: function (event: KeyboardEvent) {
- return event.key === '>'
+ return isNaked(event, '>')
},
handler: function (player: videojs.Player) {
const newValue = Math.min(player.playbackRate() + 0.1, 5)
},
decreasePlaybackRateKey: {
key: function (event: KeyboardEvent) {
- return event.key === '<'
+ return isNaked(event, '<')
},
handler: function (player: videojs.Player) {
const newValue = Math.max(player.playbackRate() - 0.1, 0.10)
},
frameByFrame: {
key: function (event: KeyboardEvent) {
- return event.key === '.'
+ return isNaked(event, '.')
},
handler: function (player: videojs.Player) {
player.pause()