diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts
index 366e9bb57..2216bdd4a 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/+videos/+video-watch/video-watch.component.ts
@@ -795,6 +795,19 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
src: environment.apiUrl + c.captionPath
}))
+ const playlistOptions = this.playlist
+ ? {
+ createComponent: false,
+
+ playlist: this.playlist,
+
+ getCurrentPosition: () => this.playlistPosition,
+
+ embedUrl: this.playlist.embedUrl,
+ embedTitle: this.playlist.displayName
+ }
+ : undefined
+
const options: PeertubePlayerManagerOptions = {
common: {
autoplay: this.isAutoplay(),
@@ -839,7 +852,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
videoCaptions: playerCaptions,
- videoUUID: video.uuid
+ videoUUID: video.uuid,
+
+ playlist: playlistOptions
},
webtorrent: {
diff --git a/client/src/assets/player/peertube-player-manager.ts b/client/src/assets/player/peertube-player-manager.ts
index ed82e0496..689e70fb5 100644
--- a/client/src/assets/player/peertube-player-manager.ts
+++ b/client/src/assets/player/peertube-player-manager.ts
@@ -35,7 +35,7 @@ import {
VideoJSPluginOptions
} from './peertube-videojs-typings'
import { TranslationsManager } from './translations-manager'
-import { buildVideoOrPlaylistEmbed, buildVideoLink, getRtcConfig, isSafari, isIOS } from './utils'
+import { buildVideoOrPlaylistEmbed, buildVideoLink, getRtcConfig, isSafari, isIOS, buildPlaylistLink } from './utils'
import { copyToClipboard } from '../../root-helpers/utils'
// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
@@ -87,6 +87,8 @@ export interface CommonOptions extends CustomizationOptions {
hasPreviousVideo?: () => boolean
playlist?: PlaylistPluginOptions
+ playlistEmbedUrl?: string
+ playlistEmbedTitle?: string
videoDuration: number
enableHotkeys: boolean
@@ -167,7 +169,13 @@ export class PeertubePlayerManager {
PeertubePlayerManager.alreadyPlayed = true
})
- self.addContextMenu(mode, player, options.common.embedUrl, options.common.embedTitle)
+ self.addContextMenu({
+ mode,
+ player,
+ videoEmbedUrl: options.common.embedUrl,
+ videoEmbedTitle: options.common.embedTitle,
+ playlist: options.common.playlist
+ })
player.bezels()
@@ -205,7 +213,13 @@ export class PeertubePlayerManager {
videojs(newVideoElement, videojsOptions, function (this: videojs.Player) {
const player = this
- self.addContextMenu(mode, player, options.common.embedUrl, options.common.embedTitle)
+ self.addContextMenu({
+ mode,
+ player,
+ videoEmbedUrl: options.common.embedUrl,
+ videoEmbedTitle: options.common.embedTitle,
+ playlist: options.common.playlist
+ })
PeertubePlayerManager.onPlayerChange(player)
})
@@ -239,7 +253,7 @@ export class PeertubePlayerManager {
}
}
- if (commonOptions.playlist) {
+ if (commonOptions.playlist?.createComponent === true) {
plugins.playlist = commonOptions.playlist
}
@@ -497,37 +511,71 @@ export class PeertubePlayerManager {
return children
}
- private static addContextMenu (mode: PlayerMode, player: videojs.Player, videoEmbedUrl: string, videoEmbedTitle: string) {
+ private static addContextMenu (options: {
+ mode: PlayerMode
+ player: videojs.Player
+ videoEmbedUrl: string
+ videoEmbedTitle: string
+ playlist?: PlaylistPluginOptions
+ }) {
+ const { mode, player, videoEmbedUrl, videoEmbedTitle, playlist } = options
+
const content = () => {
- const isLoopEnabled = player.options_['loop']
- const items = [
- {
- icon: 'repeat',
- label: player.localize('Play in loop') + (isLoopEnabled ? '' : ''),
- listener: function () {
- player.options_['loop'] = !isLoopEnabled
+ let items: { icon?: string, label: string, listener: Function }[] = []
+
+ if (!playlist) {
+ const isLoopEnabled = player.options_['loop']
+ items = items.concat([
+ {
+ icon: 'repeat',
+ label: player.localize('Play in loop') + (isLoopEnabled ? '' : ''),
+ 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() }))
+ }
}
- },
- {
- 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))
+ ])
+ } else {
+ items = items.concat([
+ {
+ label: player.localize('Copy the playlist URL'),
+ listener: function () {
+ copyToClipboard(buildPlaylistLink())
+ }
+ },
+ {
+ label: player.localize('Copy the playlist URL at current video position'),
+ listener: function (this: videojs.Player) {
+ copyToClipboard(buildPlaylistLink({ playlistPosition: playlist.getCurrentPosition() }))
+ }
+ },
+ {
+ label: player.localize('Copy the playlist embed code'),
+ listener: function (this: videojs.Player) {
+ copyToClipboard(buildVideoOrPlaylistEmbed(playlist.embedUrl, playlist.embedTitle))
+ }
}
+ ])
+ }
+
+ items = items.concat({
+ icon: 'code',
+ label: player.localize('Copy video embed code'),
+ listener: () => {
+ copyToClipboard(buildVideoOrPlaylistEmbed(videoEmbedUrl, videoEmbedTitle))
}
- ]
+ })
if (mode === 'webtorrent') {
items.push({
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts
index 4a6c80247..a48ff2cd0 100644
--- a/client/src/assets/player/peertube-videojs-typings.ts
+++ b/client/src/assets/player/peertube-videojs-typings.ts
@@ -113,13 +113,18 @@ type PeerTubePluginOptions = {
}
type PlaylistPluginOptions = {
- elements: VideoPlaylistElement[]
+ createComponent: boolean
+
+ elements?: VideoPlaylistElement[]
playlist: VideoPlaylist
getCurrentPosition: () => number
- onItemClicked: (element: VideoPlaylistElement) => void
+ embedUrl: string
+ embedTitle: string
+
+ onItemClicked?: (element: VideoPlaylistElement) => void
}
type NextPreviousVideoButtonOptions = {
diff --git a/client/src/assets/player/utils.ts b/client/src/assets/player/utils.ts
index d7451fa1d..136b69b4f 100644
--- a/client/src/assets/player/utils.ts
+++ b/client/src/assets/player/utils.ts
@@ -94,9 +94,8 @@ function buildVideoLink (options: {
function buildPlaylistLink (options: {
baseUrl?: string
-
- playlistPosition: number
-}) {
+ playlistPosition?: number
+} = {}) {
const { baseUrl } = options
const url = baseUrl
@@ -106,6 +105,7 @@ function buildPlaylistLink (options: {
const params = generateParams(window.location.search)
if (options.playlistPosition) params.set('playlistPosition', '' + options.playlistPosition)
+ else params.delete('playlistPosition')
return buildUrl(url, params)
}
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts
index 103014bb0..9e5b2a655 100644
--- a/client/src/standalone/videos/embed.ts
+++ b/client/src/standalone/videos/embed.ts
@@ -492,6 +492,8 @@ export class PeerTubeEmbed {
const playlistPlugin = this.currentPlaylistElement
? {
+ createComponent: true,
+
elements: this.playlistElements,
playlist: this.playlist,
@@ -502,7 +504,10 @@ export class PeerTubeEmbed {
this.loadVideoAndBuildPlayer(this.currentPlaylistElement.video.uuid)
.catch(err => console.error(err))
- }
+ },
+
+ embedTitle: this.playlist.displayName,
+ embedUrl: window.location.origin + this.playlist.embedPath
}
: undefined
diff --git a/scripts/i18n/create-custom-files.ts b/scripts/i18n/create-custom-files.ts
index d4d5b44f0..111bcbf4c 100755
--- a/scripts/i18n/create-custom-files.ts
+++ b/scripts/i18n/create-custom-files.ts
@@ -29,14 +29,18 @@ const playerKeys = {
'Watching this video may reveal your IP address to others.': 'Watching this video may reveal your IP address to others.',
'Copy the video URL': 'Copy the video URL',
'Copy the video URL at the current time': 'Copy the video URL at the current time',
- 'Copy embed code': 'Copy embed code',
+ 'Copy video embed code': 'Copy video embed code',
'Copy magnet URI': 'Copy magnet URI',
'Total downloaded: ': 'Total downloaded: ',
'Total uploaded: ': 'Total uploaded: ',
'From servers: ': 'From servers: ',
'From peers: ': 'From peers: ',
'Normal mode': 'Normal mode',
- 'Theater mode': 'Theater mode'
+ 'Play in loop': 'Play in loop',
+ 'Theater mode': 'Theater mode',
+ 'Copy the playlist URL': 'Copy the playlist URL',
+ 'Copy the playlist URL at current video position': 'Copy the playlist URL at current video position',
+ 'Copy the playlist embed code': 'Copy the playlist embed code'
}
Object.assign(playerKeys, videojs)