2022-03-14 11:16:54 +01:00
|
|
|
import videojs from 'video.js'
|
2022-03-14 14:28:20 +01:00
|
|
|
import { copyToClipboard } from '@root-helpers/utils'
|
|
|
|
import { buildVideoOrPlaylistEmbed } from '@root-helpers/video'
|
|
|
|
import { isIOS, isSafari } from '@root-helpers/web-browser'
|
2022-03-18 13:32:20 +01:00
|
|
|
import { buildVideoLink, decorateVideoLink, pick } from '@shared/core-utils'
|
2022-03-14 11:16:54 +01:00
|
|
|
import { isDefaultLocale } from '@shared/core-utils/i18n'
|
2022-03-14 14:28:20 +01:00
|
|
|
import { VideoJSPluginOptions } from '../../types'
|
|
|
|
import { CommonOptions, PeertubePlayerManagerOptions, PlayerMode } from '../../types/manager-options'
|
2022-03-14 11:16:54 +01:00
|
|
|
import { ControlBarOptionsBuilder } from './control-bar-options-builder'
|
|
|
|
import { HLSOptionsBuilder } from './hls-options-builder'
|
|
|
|
import { WebTorrentOptionsBuilder } from './webtorrent-options-builder'
|
|
|
|
|
|
|
|
export class ManagerOptionsBuilder {
|
|
|
|
|
|
|
|
constructor (
|
|
|
|
private mode: PlayerMode,
|
|
|
|
private options: PeertubePlayerManagerOptions,
|
|
|
|
private p2pMediaLoaderModule?: any
|
|
|
|
) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-10-11 08:37:14 +02:00
|
|
|
async getVideojsOptions (alreadyPlayed: boolean): Promise<videojs.PlayerOptions> {
|
2022-03-14 11:16:54 +01:00
|
|
|
const commonOptions = this.options.common
|
|
|
|
|
|
|
|
let autoplay = this.getAutoPlayValue(commonOptions.autoplay, alreadyPlayed)
|
|
|
|
const html5 = {
|
|
|
|
preloadTextTracks: false
|
|
|
|
}
|
|
|
|
|
|
|
|
const plugins: VideoJSPluginOptions = {
|
|
|
|
peertube: {
|
|
|
|
mode: this.mode,
|
|
|
|
autoplay, // Use peertube plugin autoplay because we could get the file by webtorrent
|
2022-04-05 14:03:52 +02:00
|
|
|
|
|
|
|
...pick(commonOptions, [
|
|
|
|
'videoViewUrl',
|
|
|
|
'authorizationHeader',
|
|
|
|
'startTime',
|
|
|
|
'videoDuration',
|
|
|
|
'subtitle',
|
|
|
|
'videoCaptions',
|
|
|
|
'stopTime',
|
|
|
|
'isLive',
|
|
|
|
'videoUUID'
|
|
|
|
])
|
2022-08-12 16:41:29 +02:00
|
|
|
},
|
|
|
|
metrics: {
|
|
|
|
mode: this.mode,
|
|
|
|
|
|
|
|
...pick(commonOptions, [
|
|
|
|
'metricsUrl',
|
|
|
|
'videoUUID'
|
|
|
|
])
|
2022-03-14 11:16:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (commonOptions.playlist) {
|
|
|
|
plugins.playlist = commonOptions.playlist
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.mode === 'p2p-media-loader') {
|
|
|
|
const hlsOptionsBuilder = new HLSOptionsBuilder(this.options, this.p2pMediaLoaderModule)
|
2022-10-11 08:37:14 +02:00
|
|
|
const options = await hlsOptionsBuilder.getPluginOptions()
|
2022-03-14 11:16:54 +01:00
|
|
|
|
2022-03-18 13:32:20 +01:00
|
|
|
Object.assign(plugins, pick(options, [ 'hlsjs', 'p2pMediaLoader' ]))
|
|
|
|
Object.assign(html5, options.html5)
|
2022-03-14 11:16:54 +01:00
|
|
|
} else if (this.mode === 'webtorrent') {
|
|
|
|
const webtorrentOptionsBuilder = new WebTorrentOptionsBuilder(this.options, this.getAutoPlayValue(autoplay, alreadyPlayed))
|
|
|
|
|
|
|
|
Object.assign(plugins, webtorrentOptionsBuilder.getPluginOptions())
|
|
|
|
|
|
|
|
// WebTorrent plugin handles autoplay, because we do some hackish stuff in there
|
|
|
|
autoplay = false
|
|
|
|
}
|
|
|
|
|
|
|
|
const controlBarOptionsBuilder = new ControlBarOptionsBuilder(this.options, this.mode)
|
|
|
|
|
|
|
|
const videojsOptions = {
|
|
|
|
html5,
|
|
|
|
|
|
|
|
// We don't use text track settings for now
|
|
|
|
textTrackSettings: false as any, // FIXME: typings
|
|
|
|
controls: commonOptions.controls !== undefined ? commonOptions.controls : true,
|
|
|
|
loop: commonOptions.loop !== undefined ? commonOptions.loop : false,
|
|
|
|
|
|
|
|
muted: commonOptions.muted !== undefined
|
|
|
|
? commonOptions.muted
|
|
|
|
: undefined, // Undefined so the player knows it has to check the local storage
|
|
|
|
|
|
|
|
autoplay: this.getAutoPlayValue(autoplay, alreadyPlayed),
|
|
|
|
|
|
|
|
poster: commonOptions.poster,
|
|
|
|
inactivityTimeout: commonOptions.inactivityTimeout,
|
|
|
|
playbackRates: [ 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2 ],
|
|
|
|
|
|
|
|
plugins,
|
|
|
|
|
|
|
|
controlBar: {
|
|
|
|
children: controlBarOptionsBuilder.getChildrenOptions() as any // FIXME: typings
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (commonOptions.language && !isDefaultLocale(commonOptions.language)) {
|
|
|
|
Object.assign(videojsOptions, { language: commonOptions.language })
|
|
|
|
}
|
|
|
|
|
|
|
|
return videojsOptions
|
|
|
|
}
|
|
|
|
|
2022-11-15 11:57:49 +01:00
|
|
|
private getAutoPlayValue (autoplay: videojs.Autoplay, alreadyPlayed: boolean) {
|
2022-03-14 11:16:54 +01:00
|
|
|
if (autoplay !== true) return autoplay
|
|
|
|
|
|
|
|
// On first play, disable autoplay to avoid issues
|
|
|
|
// But if the player already played videos, we can safely autoplay next ones
|
|
|
|
if (isIOS() || isSafari()) {
|
|
|
|
return alreadyPlayed ? 'play' : false
|
|
|
|
}
|
|
|
|
|
2022-11-15 11:57:49 +01:00
|
|
|
return this.options.common.forceAutoplay
|
|
|
|
? 'any'
|
|
|
|
: 'play'
|
2022-03-14 11:16:54 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
getContextMenuOptions (player: videojs.Player, commonOptions: CommonOptions) {
|
|
|
|
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({ shortUUID: commonOptions.videoShortUUID }))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
label: player.localize('Copy the video URL at the current time'),
|
|
|
|
listener: function (this: videojs.Player) {
|
|
|
|
const url = buildVideoLink({ shortUUID: commonOptions.videoShortUUID })
|
|
|
|
|
|
|
|
copyToClipboard(decorateVideoLink({ url, startTime: this.currentTime() }))
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
icon: 'code',
|
|
|
|
label: player.localize('Copy embed code'),
|
|
|
|
listener: () => {
|
2022-08-11 15:28:11 +02:00
|
|
|
copyToClipboard(buildVideoOrPlaylistEmbed({ embedUrl: commonOptions.embedUrl, embedTitle: commonOptions.embedTitle }))
|
2022-03-14 11:16:54 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
|
|
|
|
|
|
|
if (this.mode === 'webtorrent') {
|
|
|
|
items.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
|
|
|
|
}))
|
|
|
|
}
|
|
|
|
|
|
|
|
return { content }
|
|
|
|
}
|
|
|
|
}
|