return fetch(this.getPlaylistUrl(playlistId))
}
- loadPlaylistElements (playlistId: string): Promise<Response> {
- return fetch(this.getPlaylistUrl(playlistId) + '/videos')
+ loadPlaylistElements (playlistId: string, start = 0): Promise<Response> {
+ const url = new URL(this.getPlaylistUrl(playlistId) + '/videos')
+ url.search = new URLSearchParams({ start: '' + start, count: '100' }).toString()
+
+ return fetch(url.toString())
}
loadConfig (): Promise<ServerConfig> {
const errorText = document.getElementById('error-content')
errorText.innerHTML = translatedText
+
+ this.wrapperElement.style.display = 'none'
}
videoNotFound (translations?: Translations) {
return params.has(name) ? params.get(name) : defaultValue
}
+ async playNextVideo () {
+ const next = this.getNextPlaylistElement()
+ if (!next) {
+ console.log('Next element not found in playlist.')
+ return
+ }
+
+ this.currentPlaylistElement = next
+
+ return this.loadVideoAndBuildPlayer(this.currentPlaylistElement.video.uuid)
+ }
+
+ async playPreviousVideo () {
+ const previous = this.getPreviousPlaylistElement()
+ if (!previous) {
+ console.log('Previous element not found in playlist.')
+ return
+ }
+
+ this.currentPlaylistElement = previous
+
+ await this.loadVideoAndBuildPlayer(this.currentPlaylistElement.video.uuid)
+ }
+
+ getCurrentPosition () {
+ if (!this.currentPlaylistElement) return -1
+
+ return this.currentPlaylistElement.position
+ }
+
async init () {
try {
this.userTokens = Tokens.load()
}
}
+ private async loadAllPlaylistVideos (playlistId: string, baseResult: ResultList<VideoPlaylistElement>) {
+ let elements = baseResult.data
+ let total = baseResult.total
+ let i = 0
+
+ while (total > elements.length && i < 10) {
+ const result = await this.loadPlaylistElements(playlistId, elements.length)
+
+ const json = await result.json() as ResultList<VideoPlaylistElement>
+ total = json.total
+
+ elements = elements.concat(json.data)
+ i++
+ }
+
+ if (i === 10) {
+ console.error('Cannot fetch all playlists elements, there are too many!')
+ }
+
+ return elements
+ }
+
private async loadPlaylist (playlistId: string) {
const playlistPromise = this.loadPlaylistInfo(playlistId)
const playlistElementsPromise = this.loadPlaylistElements(playlistId)
cancelText: peertubeTranslate('Cancel', translations),
suspendedText: peertubeTranslate('Autoplay is suspended', translations),
getTitle: () => this.nextVideoTitle(),
- next: () => this.autoplayNext(),
+ next: () => this.playNextVideo(),
condition: () => !!this.getNextPlaylistElement(),
suspended: () => false
})
}
- private async autoplayNext () {
- const next = this.getNextPlaylistElement()
- if (!next) {
- console.log('Next element not found in playlist.')
- return
- }
-
- this.currentPlaylistElement = next
-
- const res = await this.loadVideo(this.currentPlaylistElement.video.uuid)
+ private async loadVideoAndBuildPlayer (uuid: string) {
+ const res = await this.loadVideo(uuid)
if (res === undefined) return
return this.buildVideoPlayer(res.videoResponse, res.captionsPromise)
return next
}
+ private getPreviousPlaylistElement (position?: number): VideoPlaylistElement {
+ if (!position) position = this.currentPlaylistElement.position - 1
+
+ if (position < 1) {
+ return undefined
+ }
+
+ const prev = this.playlistElements.find(e => e.position === position)
+
+ if (!prev || !prev.video) {
+ return this.getNextPlaylistElement(position - 1)
+ }
+
+ return prev
+ }
+
private async buildVideoPlayer (videoResponse: Response, captionsPromise: Promise<Response>) {
let alreadyHadPlayer = false
return videoInfo
})
- const [ videoInfo, serverTranslations, captionsResponse, config, PeertubePlayerManagerModule ] = await Promise.all([
+ const [ videoInfoTmp, serverTranslations, captionsResponse, config, PeertubePlayerManagerModule ] = await Promise.all([
videoInfoPromise,
this.translationsPromise,
captionsPromise,
this.PeertubePlayerManagerModulePromise
])
+ const videoInfo: VideoDetails = videoInfoTmp
+
const PeertubePlayerManager = PeertubePlayerManagerModule.PeertubePlayerManager
const videoCaptions = await this.buildCaptions(serverTranslations, captionsResponse)
this.loadParams(videoInfo)
+ const playlistPlugin = this.currentPlaylistElement
+ ? {
+ elements: this.playlistElements,
+ playlist: this.playlist,
+
+ getCurrentPosition: () => this.currentPlaylistElement.position,
+
+ onItemClicked: (videoPlaylistElement: VideoPlaylistElement) => {
+ this.currentPlaylistElement = videoPlaylistElement
+
+ this.loadVideoAndBuildPlayer(this.currentPlaylistElement.video.uuid)
+ .catch(err => console.error(err))
+ }
+ }
+ : undefined
+
const options: PeertubePlayerManagerOptions = {
common: {
// Autoplay in playlist mode
controls: this.controls,
muted: this.muted,
loop: this.loop,
+
captions: videoCaptions.length !== 0,
- startTime: this.startTime,
- stopTime: this.stopTime,
subtitle: this.subtitle,
- nextVideo: () => this.autoplayNext(),
+ startTime: this.playlist ? this.currentPlaylistElement.startTimestamp : this.startTime,
+ stopTime: this.playlist ? this.currentPlaylistElement.stopTimestamp : this.stopTime,
+
+ nextVideo: this.playlist ? () => this.playNextVideo() : undefined,
+ hasNextVideo: this.playlist ? () => !!this.getNextPlaylistElement() : undefined,
+
+ previousVideo: this.playlist ? () => this.playPreviousVideo() : undefined,
+ hasPreviousVideo: this.playlist ? () => !!this.getPreviousPlaylistElement() : undefined,
+
+ playlist: playlistPlugin,
videoCaptions,
inactivityTimeout: 2500,
if (this.isPlaylistEmbed()) {
await this.buildPlaylistManager()
+
+ this.player.playlist().updateSelected()
+
+ this.player.on('stopped', () => {
+ this.playNextVideo()
+ })
}
}
this.playlist = await res.playlistResponse.json()
const playlistElementResult = await res.videosResponse.json()
- this.playlistElements = playlistElementResult.data
+ this.playlistElements = await this.loadAllPlaylistVideos(playlistId, playlistElementResult)
+
+ const params = new URL(window.location.toString()).searchParams
+ const playlistPositionParam = this.getParamString(params, 'playlistPosition')
+
+ let position = 1
+
+ if (playlistPositionParam) {
+ position = parseInt(playlistPositionParam + '', 10)
+ }
+
+ this.currentPlaylistElement = this.playlistElements.find(e => e.position === position)
+ if (!this.currentPlaylistElement || !this.currentPlaylistElement.video) {
+ console.error('Current playlist element is not valid.', this.currentPlaylistElement)
+ this.currentPlaylistElement = this.getNextPlaylistElement()
+ }
+
+ if (!this.currentPlaylistElement) {
+ console.error('This playlist does not have any valid element.')
+ const serverTranslations = await this.translationsPromise
+ this.playlistFetchError(serverTranslations)
+ return
+ }
- this.currentPlaylistElement = this.playlistElements[0]
videoId = this.currentPlaylistElement.video.uuid
} else {
videoId = this.getResourceId()
}
- const res = await this.loadVideo(videoId)
- if (res === undefined) return
-
- return this.buildVideoPlayer(res.videoResponse, res.captionsPromise)
+ return this.loadVideoAndBuildPlayer(videoId)
}
private handleError (err: Error, translations?: { [ id: string ]: string }) {