Support storyboards in embed
This commit is contained in:
parent
52807a075f
commit
638a295021
3 changed files with 53 additions and 8 deletions
|
@ -1,6 +1,7 @@
|
||||||
import './embed.scss'
|
import './embed.scss'
|
||||||
import '../../assets/player/shared/dock/peertube-dock-component'
|
import '../../assets/player/shared/dock/peertube-dock-component'
|
||||||
import '../../assets/player/shared/dock/peertube-dock-plugin'
|
import '../../assets/player/shared/dock/peertube-dock-plugin'
|
||||||
|
import { PeerTubeServerError } from 'src/types'
|
||||||
import videojs from 'video.js'
|
import videojs from 'video.js'
|
||||||
import { peertubeTranslate } from '../../../../shared/core-utils/i18n'
|
import { peertubeTranslate } from '../../../../shared/core-utils/i18n'
|
||||||
import {
|
import {
|
||||||
|
@ -27,7 +28,6 @@ import {
|
||||||
VideoFetcher
|
VideoFetcher
|
||||||
} from './shared'
|
} from './shared'
|
||||||
import { PlayerHTML } from './shared/player-html'
|
import { PlayerHTML } from './shared/player-html'
|
||||||
import { PeerTubeServerError } from 'src/types'
|
|
||||||
|
|
||||||
export class PeerTubeEmbed {
|
export class PeerTubeEmbed {
|
||||||
player: videojs.Player
|
player: videojs.Player
|
||||||
|
@ -188,9 +188,13 @@ export class PeerTubeEmbed {
|
||||||
const { uuid, autoplayFromPreviousVideo, forceAutoplay } = options
|
const { uuid, autoplayFromPreviousVideo, forceAutoplay } = options
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (err) {
|
||||||
|
|
||||||
if (await this.handlePasswordError(err)) this.loadVideoAndBuildPlayer({ ...options })
|
if (await this.handlePasswordError(err)) this.loadVideoAndBuildPlayer({ ...options })
|
||||||
|
@ -200,11 +204,12 @@ export class PeerTubeEmbed {
|
||||||
|
|
||||||
private async buildVideoPlayer (options: {
|
private async buildVideoPlayer (options: {
|
||||||
videoResponse: Response
|
videoResponse: Response
|
||||||
|
storyboardsPromise: Promise<Response>
|
||||||
captionsPromise: Promise<Response>
|
captionsPromise: Promise<Response>
|
||||||
autoplayFromPreviousVideo: boolean
|
autoplayFromPreviousVideo: boolean
|
||||||
forceAutoplay: boolean
|
forceAutoplay: boolean
|
||||||
}) {
|
}) {
|
||||||
const { videoResponse, captionsPromise, autoplayFromPreviousVideo, forceAutoplay } = options
|
const { videoResponse, captionsPromise, storyboardsPromise, autoplayFromPreviousVideo, forceAutoplay } = options
|
||||||
|
|
||||||
this.resetPlayerElement()
|
this.resetPlayerElement()
|
||||||
|
|
||||||
|
@ -226,10 +231,17 @@ export class PeerTubeEmbed {
|
||||||
return { live, video: videoInfo, videoFileToken }
|
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,
|
videoInfoPromise,
|
||||||
this.translationsPromise,
|
this.translationsPromise,
|
||||||
captionsPromise,
|
captionsPromise,
|
||||||
|
storyboardsPromise,
|
||||||
this.PeertubePlayerManagerModulePromise
|
this.PeertubePlayerManagerModulePromise
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -244,6 +256,8 @@ export class PeerTubeEmbed {
|
||||||
translations,
|
translations,
|
||||||
serverConfig: this.config,
|
serverConfig: this.config,
|
||||||
|
|
||||||
|
storyboardsResponse,
|
||||||
|
|
||||||
authorizationHeader: () => this.http.getHeaderTokenValue(),
|
authorizationHeader: () => this.http.getHeaderTokenValue(),
|
||||||
videoFileToken: () => videoFileToken,
|
videoFileToken: () => videoFileToken,
|
||||||
videoPassword: () => this.videoPassword,
|
videoPassword: () => this.videoPassword,
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { peertubeTranslate } from '../../../../../shared/core-utils/i18n'
|
||||||
import {
|
import {
|
||||||
HTMLServerConfig,
|
HTMLServerConfig,
|
||||||
LiveVideo,
|
LiveVideo,
|
||||||
|
Storyboard,
|
||||||
Video,
|
Video,
|
||||||
VideoCaption,
|
VideoCaption,
|
||||||
VideoDetails,
|
VideoDetails,
|
||||||
|
@ -155,6 +156,9 @@ export class PlayerManagerOptions {
|
||||||
async getPlayerOptions (options: {
|
async getPlayerOptions (options: {
|
||||||
video: VideoDetails
|
video: VideoDetails
|
||||||
captionsResponse: Response
|
captionsResponse: Response
|
||||||
|
|
||||||
|
storyboardsResponse: Response
|
||||||
|
|
||||||
live?: LiveVideo
|
live?: LiveVideo
|
||||||
|
|
||||||
forceAutoplay: boolean
|
forceAutoplay: boolean
|
||||||
|
@ -187,11 +191,15 @@ export class PlayerManagerOptions {
|
||||||
forceAutoplay,
|
forceAutoplay,
|
||||||
playlistTracker,
|
playlistTracker,
|
||||||
live,
|
live,
|
||||||
|
storyboardsResponse,
|
||||||
authorizationHeader,
|
authorizationHeader,
|
||||||
serverConfig
|
serverConfig
|
||||||
} = options
|
} = options
|
||||||
|
|
||||||
const videoCaptions = await this.buildCaptions(captionsResponse, translations)
|
const [ videoCaptions, storyboard ] = await Promise.all([
|
||||||
|
this.buildCaptions(captionsResponse, translations),
|
||||||
|
this.buildStoryboard(storyboardsResponse)
|
||||||
|
])
|
||||||
|
|
||||||
const playerOptions: PeertubePlayerManagerOptions = {
|
const playerOptions: PeertubePlayerManagerOptions = {
|
||||||
common: {
|
common: {
|
||||||
|
@ -210,6 +218,8 @@ export class PlayerManagerOptions {
|
||||||
captions: videoCaptions.length !== 0,
|
captions: videoCaptions.length !== 0,
|
||||||
subtitle: this.subtitle,
|
subtitle: this.subtitle,
|
||||||
|
|
||||||
|
storyboard,
|
||||||
|
|
||||||
startTime: playlistTracker
|
startTime: playlistTracker
|
||||||
? playlistTracker.getCurrentElement().startTimestamp
|
? playlistTracker.getCurrentElement().startTimestamp
|
||||||
: this.startTime,
|
: 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: {
|
private buildPlaylistOptions (options: {
|
||||||
playlistTracker?: PlaylistTracker
|
playlistTracker?: PlaylistTracker
|
||||||
playNextPlaylistVideo?: () => any
|
playNextPlaylistVideo?: () => any
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { PeerTubeServerError } from '../../../types'
|
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 { logger } from '../../../root-helpers'
|
||||||
import { AuthHTTP } from './auth-http'
|
import { AuthHTTP } from './auth-http'
|
||||||
|
|
||||||
|
@ -36,8 +36,9 @@ export class VideoFetcher {
|
||||||
}
|
}
|
||||||
|
|
||||||
const captionsPromise = this.loadVideoCaptions({ videoId, videoPassword })
|
const captionsPromise = this.loadVideoCaptions({ videoId, videoPassword })
|
||||||
|
const storyboardsPromise = this.loadStoryboards(videoId)
|
||||||
|
|
||||||
return { captionsPromise, videoResponse }
|
return { captionsPromise, storyboardsPromise, videoResponse }
|
||||||
}
|
}
|
||||||
|
|
||||||
loadLive (video: VideoDetails) {
|
loadLive (video: VideoDetails) {
|
||||||
|
@ -71,6 +72,14 @@ export class VideoFetcher {
|
||||||
return window.location.origin + '/api/v1/videos/live/' + videoId
|
return window.location.origin + '/api/v1/videos/live/' + videoId
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadStoryboards (videoUUID: string): Promise<Response> {
|
||||||
|
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) {
|
private getVideoTokenUrl (id: string) {
|
||||||
return this.getVideoUrl(id) + '/token'
|
return this.getVideoUrl(id) + '/token'
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue