aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/assets/player
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/assets/player')
-rw-r--r--client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts10
-rw-r--r--client/src/assets/player/peertube-player-manager.ts45
-rw-r--r--client/src/assets/player/peertube-plugin.ts6
3 files changed, 55 insertions, 6 deletions
diff --git a/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts b/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts
index f9a2707fb..022a9c16f 100644
--- a/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts
+++ b/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts
@@ -51,17 +51,25 @@ class P2pMediaLoaderPlugin extends Plugin {
51 src: options.src 51 src: options.src
52 }) 52 })
53 53
54 player.on('play', () => {
55 player.addClass('vjs-has-big-play-button-clicked')
56 })
57
54 player.ready(() => this.initialize()) 58 player.ready(() => this.initialize())
55 } 59 }
56 60
57 dispose () { 61 dispose () {
62 if (this.hlsjs) this.hlsjs.destroy()
63 if (this.p2pEngine) this.p2pEngine.destroy()
64
58 clearInterval(this.networkInfoInterval) 65 clearInterval(this.networkInfoInterval)
59 } 66 }
60 67
61 private initialize () { 68 private initialize () {
62 initHlsJsPlayer(this.hlsjs) 69 initHlsJsPlayer(this.hlsjs)
63 70
64 this.p2pEngine = this.player.tech_.options_.hlsjsConfig.loader.getEngine() 71 const tech = this.player.tech_
72 this.p2pEngine = tech.options_.hlsjsConfig.loader.getEngine()
65 73
66 // Avoid using constants to not import hls.hs 74 // Avoid using constants to not import hls.hs
67 // https://github.com/video-dev/hls.js/blob/master/src/events.js#L37 75 // https://github.com/video-dev/hls.js/blob/master/src/events.js#L37
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
42export type CommonOptions = { 42export 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
72export type PeertubePlayerManagerOptions = { 73export type PeertubePlayerManagerOptions = {
73 common: CommonOptions, 74 common: CommonOptions,
74 webtorrent?: WebtorrentOptions, 75 webtorrent: WebtorrentOptions,
75 p2pMediaLoader?: P2PMediaLoaderOptions 76 p2pMediaLoader?: P2PMediaLoaderOptions
76} 77}
77 78
78export class PeertubePlayerManager { 79export 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,
diff --git a/client/src/assets/player/peertube-plugin.ts b/client/src/assets/player/peertube-plugin.ts
index aacbf5f6e..7ea4a06d4 100644
--- a/client/src/assets/player/peertube-plugin.ts
+++ b/client/src/assets/player/peertube-plugin.ts
@@ -47,7 +47,11 @@ class PeerTubePlugin extends Plugin {
47 this.videoDuration = options.videoDuration 47 this.videoDuration = options.videoDuration
48 this.videoCaptions = options.videoCaptions 48 this.videoCaptions = options.videoCaptions
49 49
50 if (this.autoplay === true) this.player.addClass('vjs-has-autoplay') 50 if (options.autoplay === true) this.player.addClass('vjs-has-autoplay')
51
52 this.player.on('autoplay-failure', () => {
53 this.player.removeClass('vjs-has-autoplay')
54 })
51 55
52 this.player.ready(() => { 56 this.player.ready(() => {
53 const playerOptions = this.player.options_ 57 const playerOptions = this.player.options_