diff options
Diffstat (limited to 'client/src/assets/player')
-rw-r--r-- | client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts | 10 | ||||
-rw-r--r-- | client/src/assets/player/peertube-player-manager.ts | 45 | ||||
-rw-r--r-- | client/src/assets/player/peertube-plugin.ts | 6 |
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 | ||
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, |
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_ |