From 638a2950215af1f11be8e8bdd136ca12e5176c32 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 5 Jun 2023 11:13:38 +0200 Subject: [PATCH] Support storyboards in embed --- client/src/standalone/videos/embed.ts | 24 +++++++++++++++---- .../videos/shared/player-manager-options.ts | 24 ++++++++++++++++++- .../standalone/videos/shared/video-fetcher.ts | 13 ++++++++-- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index cffda2cc7..6e37ce193 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts @@ -1,6 +1,7 @@ import './embed.scss' import '../../assets/player/shared/dock/peertube-dock-component' import '../../assets/player/shared/dock/peertube-dock-plugin' +import { PeerTubeServerError } from 'src/types' import videojs from 'video.js' import { peertubeTranslate } from '../../../../shared/core-utils/i18n' import { @@ -27,7 +28,6 @@ import { VideoFetcher } from './shared' import { PlayerHTML } from './shared/player-html' -import { PeerTubeServerError } from 'src/types' export class PeerTubeEmbed { player: videojs.Player @@ -188,9 +188,13 @@ export class PeerTubeEmbed { const { uuid, autoplayFromPreviousVideo, forceAutoplay } = options try { - const { videoResponse, captionsPromise } = await this.videoFetcher.loadVideo({ videoId: uuid, videoPassword: this.videoPassword }) + const { + videoResponse, + captionsPromise, + storyboardsPromise + } = await this.videoFetcher.loadVideo({ videoId: uuid, videoPassword: this.videoPassword }) - return this.buildVideoPlayer({ videoResponse, captionsPromise, autoplayFromPreviousVideo, forceAutoplay }) + return this.buildVideoPlayer({ videoResponse, captionsPromise, storyboardsPromise, autoplayFromPreviousVideo, forceAutoplay }) } catch (err) { if (await this.handlePasswordError(err)) this.loadVideoAndBuildPlayer({ ...options }) @@ -200,11 +204,12 @@ export class PeerTubeEmbed { private async buildVideoPlayer (options: { videoResponse: Response + storyboardsPromise: Promise captionsPromise: Promise autoplayFromPreviousVideo: boolean forceAutoplay: boolean }) { - const { videoResponse, captionsPromise, autoplayFromPreviousVideo, forceAutoplay } = options + const { videoResponse, captionsPromise, storyboardsPromise, autoplayFromPreviousVideo, forceAutoplay } = options this.resetPlayerElement() @@ -226,10 +231,17 @@ export class PeerTubeEmbed { return { live, video: videoInfo, videoFileToken } }) - const [ { video, live, videoFileToken }, translations, captionsResponse, PeertubePlayerManagerModule ] = await Promise.all([ + const [ + { video, live, videoFileToken }, + translations, + captionsResponse, + storyboardsResponse, + PeertubePlayerManagerModule + ] = await Promise.all([ videoInfoPromise, this.translationsPromise, captionsPromise, + storyboardsPromise, this.PeertubePlayerManagerModulePromise ]) @@ -244,6 +256,8 @@ export class PeerTubeEmbed { translations, serverConfig: this.config, + storyboardsResponse, + authorizationHeader: () => this.http.getHeaderTokenValue(), videoFileToken: () => videoFileToken, videoPassword: () => this.videoPassword, diff --git a/client/src/standalone/videos/shared/player-manager-options.ts b/client/src/standalone/videos/shared/player-manager-options.ts index 587516410..3c7521bc2 100644 --- a/client/src/standalone/videos/shared/player-manager-options.ts +++ b/client/src/standalone/videos/shared/player-manager-options.ts @@ -2,6 +2,7 @@ import { peertubeTranslate } from '../../../../../shared/core-utils/i18n' import { HTMLServerConfig, LiveVideo, + Storyboard, Video, VideoCaption, VideoDetails, @@ -155,6 +156,9 @@ export class PlayerManagerOptions { async getPlayerOptions (options: { video: VideoDetails captionsResponse: Response + + storyboardsResponse: Response + live?: LiveVideo forceAutoplay: boolean @@ -187,11 +191,15 @@ export class PlayerManagerOptions { forceAutoplay, playlistTracker, live, + storyboardsResponse, authorizationHeader, serverConfig } = options - const videoCaptions = await this.buildCaptions(captionsResponse, translations) + const [ videoCaptions, storyboard ] = await Promise.all([ + this.buildCaptions(captionsResponse, translations), + this.buildStoryboard(storyboardsResponse) + ]) const playerOptions: PeertubePlayerManagerOptions = { common: { @@ -210,6 +218,8 @@ export class PlayerManagerOptions { captions: videoCaptions.length !== 0, subtitle: this.subtitle, + storyboard, + startTime: playlistTracker ? playlistTracker.getCurrentElement().startTimestamp : this.startTime, @@ -286,6 +296,18 @@ export class PlayerManagerOptions { } } + private async buildStoryboard (storyboardsResponse: Response) { + const { storyboards } = await storyboardsResponse.json() as { storyboards: Storyboard[] } + if (!storyboards || storyboards.length === 0) return undefined + + return { + url: window.location.origin + storyboards[0].storyboardPath, + height: storyboards[0].spriteHeight, + width: storyboards[0].spriteWidth, + interval: storyboards[0].spriteDuration + } + } + private buildPlaylistOptions (options: { playlistTracker?: PlaylistTracker playNextPlaylistVideo?: () => any diff --git a/client/src/standalone/videos/shared/video-fetcher.ts b/client/src/standalone/videos/shared/video-fetcher.ts index 76ba0a3ed..d52730b83 100644 --- a/client/src/standalone/videos/shared/video-fetcher.ts +++ b/client/src/standalone/videos/shared/video-fetcher.ts @@ -1,5 +1,5 @@ import { PeerTubeServerError } from '../../../types' -import { HttpStatusCode, LiveVideo, VideoDetails, VideoToken } from '../../../../../shared/models' +import { HttpStatusCode, LiveVideo, Storyboard, VideoDetails, VideoToken } from '../../../../../shared/models' import { logger } from '../../../root-helpers' import { AuthHTTP } from './auth-http' @@ -36,8 +36,9 @@ export class VideoFetcher { } const captionsPromise = this.loadVideoCaptions({ videoId, videoPassword }) + const storyboardsPromise = this.loadStoryboards(videoId) - return { captionsPromise, videoResponse } + return { captionsPromise, storyboardsPromise, videoResponse } } loadLive (video: VideoDetails) { @@ -71,6 +72,14 @@ export class VideoFetcher { return window.location.origin + '/api/v1/videos/live/' + videoId } + private loadStoryboards (videoUUID: string): Promise { + return this.http.fetch(this.getStoryboardsUrl(videoUUID), { optionalAuth: true }) + } + + private getStoryboardsUrl (videoId: string) { + return window.location.origin + '/api/v1/videos/' + videoId + '/storyboards' + } + private getVideoTokenUrl (id: string) { return this.getVideoUrl(id) + '/token' }