diff options
Diffstat (limited to 'client/src/assets/player/peertube-player-manager.ts')
-rw-r--r-- | client/src/assets/player/peertube-player-manager.ts | 45 |
1 files changed, 41 insertions, 4 deletions
diff --git a/client/src/assets/player/peertube-player-manager.ts b/client/src/assets/player/peertube-player-manager.ts index 3fdba6fdf..0ba9bcb11 100644 --- a/client/src/assets/player/peertube-player-manager.ts +++ b/client/src/assets/player/peertube-player-manager.ts | |||
@@ -41,6 +41,7 @@ export type P2PMediaLoaderOptions = { | |||
41 | 41 | ||
42 | export type CommonOptions = { | 42 | export type CommonOptions = { |
43 | playerElement: HTMLVideoElement | 43 | playerElement: HTMLVideoElement |
44 | onPlayerElementChange: (element: HTMLVideoElement) => void | ||
44 | 45 | ||
45 | autoplay: boolean | 46 | autoplay: boolean |
46 | videoDuration: number | 47 | videoDuration: number |
@@ -71,13 +72,14 @@ export type CommonOptions = { | |||
71 | 72 | ||
72 | export type PeertubePlayerManagerOptions = { | 73 | export type PeertubePlayerManagerOptions = { |
73 | common: CommonOptions, | 74 | common: CommonOptions, |
74 | webtorrent?: WebtorrentOptions, | 75 | webtorrent: WebtorrentOptions, |
75 | p2pMediaLoader?: P2PMediaLoaderOptions | 76 | p2pMediaLoader?: P2PMediaLoaderOptions |
76 | } | 77 | } |
77 | 78 | ||
78 | export class PeertubePlayerManager { | 79 | export class PeertubePlayerManager { |
79 | 80 | ||
80 | private static videojsLocaleCache: { [ path: string ]: any } = {} | 81 | private static videojsLocaleCache: { [ path: string ]: any } = {} |
82 | private static playerElementClassName: string | ||
81 | 83 | ||
82 | static getServerTranslations (serverUrl: string, locale: string) { | 84 | static getServerTranslations (serverUrl: string, locale: string) { |
83 | const path = PeertubePlayerManager.getLocalePath(serverUrl, locale) | 85 | const path = PeertubePlayerManager.getLocalePath(serverUrl, locale) |
@@ -95,6 +97,8 @@ export class PeertubePlayerManager { | |||
95 | static async initialize (mode: PlayerMode, options: PeertubePlayerManagerOptions) { | 97 | static async initialize (mode: PlayerMode, options: PeertubePlayerManagerOptions) { |
96 | let p2pMediaLoader: any | 98 | let p2pMediaLoader: any |
97 | 99 | ||
100 | this.playerElementClassName = options.common.playerElement.className | ||
101 | |||
98 | if (mode === 'webtorrent') await import('./webtorrent/webtorrent-plugin') | 102 | if (mode === 'webtorrent') await import('./webtorrent/webtorrent-plugin') |
99 | if (mode === 'p2p-media-loader') { | 103 | if (mode === 'p2p-media-loader') { |
100 | [ p2pMediaLoader ] = await Promise.all([ | 104 | [ p2pMediaLoader ] = await Promise.all([ |
@@ -112,6 +116,13 @@ export class PeertubePlayerManager { | |||
112 | videojs(options.common.playerElement, videojsOptions, function (this: any) { | 116 | videojs(options.common.playerElement, videojsOptions, function (this: any) { |
113 | const player = this | 117 | const player = this |
114 | 118 | ||
119 | player.tech_.on('error', () => { | ||
120 | // Fallback to webtorrent? | ||
121 | if (mode === 'p2p-media-loader') { | ||
122 | self.fallbackToWebTorrent(player, options) | ||
123 | } | ||
124 | }) | ||
125 | |||
115 | self.addContextMenu(mode, player, options.common.embedUrl) | 126 | self.addContextMenu(mode, player, options.common.embedUrl) |
116 | 127 | ||
117 | return res(player) | 128 | return res(player) |
@@ -119,6 +130,32 @@ export class PeertubePlayerManager { | |||
119 | }) | 130 | }) |
120 | } | 131 | } |
121 | 132 | ||
133 | private static async fallbackToWebTorrent (player: any, options: PeertubePlayerManagerOptions) { | ||
134 | const newVideoElement = document.createElement('video') | ||
135 | newVideoElement.className = this.playerElementClassName | ||
136 | |||
137 | // VideoJS wraps our video element inside a div | ||
138 | const currentParentPlayerElement = options.common.playerElement.parentNode | ||
139 | currentParentPlayerElement.parentNode.insertBefore(newVideoElement, currentParentPlayerElement) | ||
140 | |||
141 | options.common.playerElement = newVideoElement | ||
142 | options.common.onPlayerElementChange(newVideoElement) | ||
143 | |||
144 | player.dispose() | ||
145 | |||
146 | await import('./webtorrent/webtorrent-plugin') | ||
147 | |||
148 | const mode = 'webtorrent' | ||
149 | const videojsOptions = this.getVideojsOptions(mode, options) | ||
150 | |||
151 | const self = this | ||
152 | videojs(newVideoElement, videojsOptions, function (this: any) { | ||
153 | const player = this | ||
154 | |||
155 | self.addContextMenu(mode, player, options.common.embedUrl) | ||
156 | }) | ||
157 | } | ||
158 | |||
122 | private static loadLocaleInVideoJS (serverUrl: string, locale: string) { | 159 | private static loadLocaleInVideoJS (serverUrl: string, locale: string) { |
123 | const path = PeertubePlayerManager.getLocalePath(serverUrl, locale) | 160 | const path = PeertubePlayerManager.getLocalePath(serverUrl, locale) |
124 | // It is the default locale, nothing to translate | 161 | // It is the default locale, nothing to translate |
@@ -166,7 +203,7 @@ export class PeertubePlayerManager { | |||
166 | } | 203 | } |
167 | } | 204 | } |
168 | 205 | ||
169 | if (p2pMediaLoaderOptions) { | 206 | if (mode === 'p2p-media-loader') { |
170 | const p2pMediaLoader: P2PMediaLoaderPluginOptions = { | 207 | const p2pMediaLoader: P2PMediaLoaderPluginOptions = { |
171 | redundancyBaseUrls: options.p2pMediaLoader.redundancyBaseUrls, | 208 | redundancyBaseUrls: options.p2pMediaLoader.redundancyBaseUrls, |
172 | type: 'application/x-mpegURL', | 209 | type: 'application/x-mpegURL', |
@@ -209,7 +246,7 @@ export class PeertubePlayerManager { | |||
209 | html5 = streamrootHls.html5 | 246 | html5 = streamrootHls.html5 |
210 | } | 247 | } |
211 | 248 | ||
212 | if (webtorrentOptions) { | 249 | if (mode === 'webtorrent') { |
213 | const webtorrent = { | 250 | const webtorrent = { |
214 | autoplay, | 251 | autoplay, |
215 | videoDuration: commonOptions.videoDuration, | 252 | videoDuration: commonOptions.videoDuration, |
@@ -235,7 +272,7 @@ export class PeertubePlayerManager { | |||
235 | : undefined, // Undefined so the player knows it has to check the local storage | 272 | : undefined, // Undefined so the player knows it has to check the local storage |
236 | 273 | ||
237 | poster: commonOptions.poster, | 274 | poster: commonOptions.poster, |
238 | autoplay, | 275 | autoplay: autoplay === true ? 'any' : autoplay, // Use 'any' instead of true to get notifier by videojs if autoplay fails |
239 | inactivityTimeout: commonOptions.inactivityTimeout, | 276 | inactivityTimeout: commonOptions.inactivityTimeout, |
240 | playbackRates: [ 0.5, 0.75, 1, 1.25, 1.5, 2 ], | 277 | playbackRates: [ 0.5, 0.75, 1, 1.25, 1.5, 2 ], |
241 | plugins, | 278 | plugins, |