import { environment } from '../../../environments/environment'
import { VideoCaptionService } from '@app/shared/video-caption'
import { MarkdownService } from '@app/shared/renderer'
-import { P2PMediaLoaderOptions, PeertubePlayerManager, PlayerMode, WebtorrentOptions } from '../../../assets/player/peertube-player-manager'
+import {
+ P2PMediaLoaderOptions,
+ PeertubePlayerManager,
+ PeertubePlayerManagerOptions,
+ PlayerMode,
+ WebtorrentOptions
+} from '../../../assets/player/peertube-player-manager'
@Component({
selector: 'my-video-watch',
src: environment.apiUrl + c.captionPath
}))
- const options = {
+ const options: PeertubePlayerManagerOptions = {
common: {
autoplay: this.isAutoplay(),
+
playerElement: this.playerElement,
+ onPlayerElementChange: (element: HTMLVideoElement) => this.playerElement = element,
+
videoDuration: this.video.duration,
enableHotkeys: true,
inactivityTimeout: 2500,
serverUrl: environment.apiUrl,
videoCaptions: playerCaptions
+ },
+
+ webtorrent: {
+ videoFiles: this.video.files
}
}
const hlsPlaylist = this.video.getHlsPlaylist()
if (hlsPlaylist) {
mode = 'p2p-media-loader'
+
const p2pMediaLoader = {
playlistUrl: hlsPlaylist.playlistUrl,
segmentsSha256Url: hlsPlaylist.segmentsSha256Url,
Object.assign(options, { p2pMediaLoader })
} else {
mode = 'webtorrent'
- const webtorrent = {
- videoFiles: this.video.files
- } as WebtorrentOptions
-
- Object.assign(options, { webtorrent })
}
this.zone.runOutsideAngular(async () => {
export type CommonOptions = {
playerElement: HTMLVideoElement
+ onPlayerElementChange: (element: HTMLVideoElement) => void
autoplay: boolean
videoDuration: number
export type PeertubePlayerManagerOptions = {
common: CommonOptions,
- webtorrent?: WebtorrentOptions,
+ webtorrent: WebtorrentOptions,
p2pMediaLoader?: P2PMediaLoaderOptions
}
export class PeertubePlayerManager {
private static videojsLocaleCache: { [ path: string ]: any } = {}
+ private static playerElementClassName: string
static getServerTranslations (serverUrl: string, locale: string) {
const path = PeertubePlayerManager.getLocalePath(serverUrl, locale)
static async initialize (mode: PlayerMode, options: PeertubePlayerManagerOptions) {
let p2pMediaLoader: any
+ this.playerElementClassName = options.common.playerElement.className
+
if (mode === 'webtorrent') await import('./webtorrent/webtorrent-plugin')
if (mode === 'p2p-media-loader') {
[ p2pMediaLoader ] = await Promise.all([
videojs(options.common.playerElement, videojsOptions, function (this: any) {
const player = this
+ player.tech_.on('error', () => {
+ // Fallback to webtorrent?
+ if (mode === 'p2p-media-loader') {
+ self.fallbackToWebTorrent(player, options)
+ }
+ })
+
self.addContextMenu(mode, player, options.common.embedUrl)
return res(player)
})
}
+ private static async fallbackToWebTorrent (player: any, options: PeertubePlayerManagerOptions) {
+ const newVideoElement = document.createElement('video')
+ newVideoElement.className = this.playerElementClassName
+
+ // VideoJS wraps our video element inside a div
+ const currentParentPlayerElement = options.common.playerElement.parentNode
+ currentParentPlayerElement.parentNode.insertBefore(newVideoElement, currentParentPlayerElement)
+
+ options.common.playerElement = newVideoElement
+ options.common.onPlayerElementChange(newVideoElement)
+
+ player.dispose()
+
+ await import('./webtorrent/webtorrent-plugin')
+
+ const mode = 'webtorrent'
+ const videojsOptions = this.getVideojsOptions(mode, options)
+
+ const self = this
+ videojs(newVideoElement, videojsOptions, function (this: any) {
+ const player = this
+
+ self.addContextMenu(mode, player, options.common.embedUrl)
+ })
+ }
+
private static loadLocaleInVideoJS (serverUrl: string, locale: string) {
const path = PeertubePlayerManager.getLocalePath(serverUrl, locale)
// It is the default locale, nothing to translate
}
}
- if (p2pMediaLoaderOptions) {
+ if (mode === 'p2p-media-loader') {
const p2pMediaLoader: P2PMediaLoaderPluginOptions = {
redundancyBaseUrls: options.p2pMediaLoader.redundancyBaseUrls,
type: 'application/x-mpegURL',
html5 = streamrootHls.html5
}
- if (webtorrentOptions) {
+ if (mode === 'webtorrent') {
const webtorrent = {
autoplay,
videoDuration: commonOptions.videoDuration,
: undefined, // Undefined so the player knows it has to check the local storage
poster: commonOptions.poster,
- autoplay,
+ autoplay: autoplay === true ? 'any' : autoplay, // Use 'any' instead of true to get notifier by videojs if autoplay fails
inactivityTimeout: commonOptions.inactivityTimeout,
playbackRates: [ 0.5, 0.75, 1, 1.25, 1.5, 2 ],
plugins,
videoCaptions,
inactivityTimeout: 1500,
videoViewUrl: this.getVideoUrl(videoId) + '/views',
+
playerElement: this.videoElement,
+ onPlayerElementChange: (element: HTMLVideoElement) => this.videoElement = element,
+
videoDuration: videoInfo.duration,
enableHotkeys: true,
peertubeLink: true,
serverUrl: window.location.origin,
language: navigator.language,
embedUrl: window.location.origin + videoInfo.embedPath
+ },
+
+ webtorrent: {
+ videoFiles: videoInfo.files
}
}
videoFiles: videoInfo.files
} as P2PMediaLoaderOptions
})
- } else {
- Object.assign(options, {
- webtorrent: {
- videoFiles: videoInfo.files
- }
- })
}
this.player = await PeertubePlayerManager.initialize(this.mode, options)