aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-11-15 11:57:49 +0100
committerChocobozzz <me@florianbigard.com>2022-11-15 11:57:49 +0100
commit59a643aa5cf6775d27dfcc147b19c4537292d53c (patch)
tree74bc87e2f0f5581306c8ea9dd1f8acf05833a74a
parentc2419476302b20e9fe3708d7a0a889ae18c95c1b (diff)
downloadPeerTube-59a643aa5cf6775d27dfcc147b19c4537292d53c.tar.gz
PeerTube-59a643aa5cf6775d27dfcc147b19c4537292d53c.tar.zst
PeerTube-59a643aa5cf6775d27dfcc147b19c4537292d53c.zip
Force autoplay when live starts
Using the mute
-rw-r--r--client/src/app/+videos/+video-watch/video-watch.component.ts42
-rw-r--r--client/src/assets/player/shared/manager-options/manager-options-builder.ts8
-rw-r--r--client/src/assets/player/shared/peertube/peertube-plugin.ts2
-rw-r--r--client/src/assets/player/shared/webtorrent/webtorrent-plugin.ts4
-rw-r--r--client/src/assets/player/types/manager-options.ts2
-rw-r--r--client/src/assets/player/types/peertube-videojs-typings.ts4
-rw-r--r--client/src/standalone/videos/embed.ts45
-rw-r--r--client/src/standalone/videos/shared/player-manager-options.ts4
8 files changed, 82 insertions, 29 deletions
diff --git a/client/src/app/+videos/+video-watch/video-watch.component.ts b/client/src/app/+videos/+video-watch/video-watch.component.ts
index 983a27e11..94853423b 100644
--- a/client/src/app/+videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/+videos/+video-watch/video-watch.component.ts
@@ -180,7 +180,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
180 } 180 }
181 181
182 onPlaylistVideoFound (videoId: string) { 182 onPlaylistVideoFound (videoId: string) {
183 this.loadVideo(videoId) 183 this.loadVideo({ videoId, forceAutoplay: false })
184 } 184 }
185 185
186 onPlaylistNoVideoFound () { 186 onPlaylistNoVideoFound () {
@@ -212,7 +212,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
212 private loadRouteParams () { 212 private loadRouteParams () {
213 this.paramsSub = this.route.params.subscribe(routeParams => { 213 this.paramsSub = this.route.params.subscribe(routeParams => {
214 const videoId = routeParams['videoId'] 214 const videoId = routeParams['videoId']
215 if (videoId) return this.loadVideo(videoId) 215 if (videoId) return this.loadVideo({ videoId, forceAutoplay: false })
216 216
217 const playlistId = routeParams['playlistId'] 217 const playlistId = routeParams['playlistId']
218 if (playlistId) return this.loadPlaylist(playlistId) 218 if (playlistId) return this.loadPlaylist(playlistId)
@@ -240,7 +240,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
240 }) 240 })
241 } 241 }
242 242
243 private loadVideo (videoId: string) { 243 private loadVideo (options: {
244 videoId: string
245 forceAutoplay: boolean
246 }) {
247 const { videoId, forceAutoplay } = options
248
244 if (this.isSameElement(this.video, videoId)) return 249 if (this.isSameElement(this.video, videoId)) return
245 250
246 if (this.player) this.player.pause() 251 if (this.player) this.player.pause()
@@ -293,8 +298,15 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
293 peertubeLink: false 298 peertubeLink: false
294 } 299 }
295 300
296 this.onVideoFetched({ video, live, videoCaptions: captionsResult.data, videoFileToken, loggedInOrAnonymousUser, urlOptions }) 301 this.onVideoFetched({
297 .catch(err => this.handleGlobalError(err)) 302 video,
303 live,
304 videoCaptions: captionsResult.data,
305 videoFileToken,
306 loggedInOrAnonymousUser,
307 urlOptions,
308 forceAutoplay
309 }).catch(err => this.handleGlobalError(err))
298 }, 310 },
299 311
300 error: err => this.handleRequestError(err) 312 error: err => this.handleRequestError(err)
@@ -370,8 +382,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
370 382
371 urlOptions: URLOptions 383 urlOptions: URLOptions
372 loggedInOrAnonymousUser: User 384 loggedInOrAnonymousUser: User
385 forceAutoplay: boolean
373 }) { 386 }) {
374 const { video, live, videoCaptions, urlOptions, videoFileToken, loggedInOrAnonymousUser } = options 387 const { video, live, videoCaptions, urlOptions, videoFileToken, loggedInOrAnonymousUser, forceAutoplay } = options
375 388
376 this.subscribeToLiveEventsIfNeeded(this.video, video) 389 this.subscribeToLiveEventsIfNeeded(this.video, video)
377 390
@@ -393,7 +406,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
393 if (res === false) return this.location.back() 406 if (res === false) return this.location.back()
394 } 407 }
395 408
396 this.buildPlayer(urlOptions, loggedInOrAnonymousUser) 409 this.buildPlayer({ urlOptions, loggedInOrAnonymousUser, forceAutoplay })
397 .catch(err => logger.error('Cannot build the player', err)) 410 .catch(err => logger.error('Cannot build the player', err))
398 411
399 this.setOpenGraphTags() 412 this.setOpenGraphTags()
@@ -406,7 +419,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
406 this.hooks.runAction('action:video-watch.video.loaded', 'video-watch', hookOptions) 419 this.hooks.runAction('action:video-watch.video.loaded', 'video-watch', hookOptions)
407 } 420 }
408 421
409 private async buildPlayer (urlOptions: URLOptions, loggedInOrAnonymousUser: User) { 422 private async buildPlayer (options: {
423 urlOptions: URLOptions
424 loggedInOrAnonymousUser: User
425 forceAutoplay: boolean
426 }) {
427 const { urlOptions, loggedInOrAnonymousUser, forceAutoplay } = options
428
410 // Flush old player if needed 429 // Flush old player if needed
411 this.flushPlayer() 430 this.flushPlayer()
412 431
@@ -430,6 +449,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
430 videoFileToken: this.videoFileToken, 449 videoFileToken: this.videoFileToken,
431 urlOptions, 450 urlOptions,
432 loggedInOrAnonymousUser, 451 loggedInOrAnonymousUser,
452 forceAutoplay,
433 user: this.user 453 user: this.user
434 } 454 }
435 const { playerMode, playerOptions } = await this.hooks.wrapFun( 455 const { playerMode, playerOptions } = await this.hooks.wrapFun(
@@ -581,9 +601,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
581 urlOptions: CustomizationOptions & { playerMode: PlayerMode } 601 urlOptions: CustomizationOptions & { playerMode: PlayerMode }
582 602
583 loggedInOrAnonymousUser: User 603 loggedInOrAnonymousUser: User
604 forceAutoplay: boolean
584 user?: AuthUser // Keep for plugins 605 user?: AuthUser // Keep for plugins
585 }) { 606 }) {
586 const { video, liveVideo, videoCaptions, videoFileToken, urlOptions, loggedInOrAnonymousUser } = params 607 const { video, liveVideo, videoCaptions, videoFileToken, urlOptions, loggedInOrAnonymousUser, forceAutoplay } = params
587 608
588 const getStartTime = () => { 609 const getStartTime = () => {
589 const byUrl = urlOptions.startTime !== undefined 610 const byUrl = urlOptions.startTime !== undefined
@@ -615,6 +636,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
615 const options: PeertubePlayerManagerOptions = { 636 const options: PeertubePlayerManagerOptions = {
616 common: { 637 common: {
617 autoplay: this.isAutoplay(), 638 autoplay: this.isAutoplay(),
639 forceAutoplay,
618 p2pEnabled: isP2PEnabled(video, this.serverConfig, loggedInOrAnonymousUser.p2pEnabled), 640 p2pEnabled: isP2PEnabled(video, this.serverConfig, loggedInOrAnonymousUser.p2pEnabled),
619 641
620 hasNextVideo: () => this.hasNextVideo(), 642 hasNextVideo: () => this.hasNextVideo(),
@@ -749,7 +771,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
749 771
750 // Reset to force refresh the video 772 // Reset to force refresh the video
751 this.video = undefined 773 this.video = undefined
752 this.loadVideo(videoUUID) 774 this.loadVideo({ videoId: videoUUID, forceAutoplay: true })
753 } 775 }
754 776
755 private handleLiveViewsChange (newViewers: number) { 777 private handleLiveViewsChange (newViewers: number) {
diff --git a/client/src/assets/player/shared/manager-options/manager-options-builder.ts b/client/src/assets/player/shared/manager-options/manager-options-builder.ts
index 2d96c9410..4d227eb2a 100644
--- a/client/src/assets/player/shared/manager-options/manager-options-builder.ts
+++ b/client/src/assets/player/shared/manager-options/manager-options-builder.ts
@@ -105,10 +105,12 @@ export class ManagerOptionsBuilder {
105 Object.assign(videojsOptions, { language: commonOptions.language }) 105 Object.assign(videojsOptions, { language: commonOptions.language })
106 } 106 }
107 107
108 console.log(videojsOptions)
109
108 return videojsOptions 110 return videojsOptions
109 } 111 }
110 112
111 private getAutoPlayValue (autoplay: any, alreadyPlayed: boolean) { 113 private getAutoPlayValue (autoplay: videojs.Autoplay, alreadyPlayed: boolean) {
112 if (autoplay !== true) return autoplay 114 if (autoplay !== true) return autoplay
113 115
114 // On first play, disable autoplay to avoid issues 116 // On first play, disable autoplay to avoid issues
@@ -117,7 +119,9 @@ export class ManagerOptionsBuilder {
117 return alreadyPlayed ? 'play' : false 119 return alreadyPlayed ? 'play' : false
118 } 120 }
119 121
120 return 'play' 122 return this.options.common.forceAutoplay
123 ? 'any'
124 : 'play'
121 } 125 }
122 126
123 getContextMenuOptions (player: videojs.Player, commonOptions: CommonOptions) { 127 getContextMenuOptions (player: videojs.Player, commonOptions: CommonOptions) {
diff --git a/client/src/assets/player/shared/peertube/peertube-plugin.ts b/client/src/assets/player/shared/peertube/peertube-plugin.ts
index 56de66998..ec8fbb320 100644
--- a/client/src/assets/player/shared/peertube/peertube-plugin.ts
+++ b/client/src/assets/player/shared/peertube/peertube-plugin.ts
@@ -52,7 +52,7 @@ class PeerTubePlugin extends Plugin {
52 this.videoCaptions = options.videoCaptions 52 this.videoCaptions = options.videoCaptions
53 this.initialInactivityTimeout = this.player.options_.inactivityTimeout 53 this.initialInactivityTimeout = this.player.options_.inactivityTimeout
54 54
55 if (options.autoplay) this.player.addClass('vjs-has-autoplay') 55 if (options.autoplay !== false) this.player.addClass('vjs-has-autoplay')
56 56
57 this.player.on('autoplay-failure', () => { 57 this.player.on('autoplay-failure', () => {
58 this.player.removeClass('vjs-has-autoplay') 58 this.player.removeClass('vjs-has-autoplay')
diff --git a/client/src/assets/player/shared/webtorrent/webtorrent-plugin.ts b/client/src/assets/player/shared/webtorrent/webtorrent-plugin.ts
index 658b7c867..46d009410 100644
--- a/client/src/assets/player/shared/webtorrent/webtorrent-plugin.ts
+++ b/client/src/assets/player/shared/webtorrent/webtorrent-plugin.ts
@@ -25,7 +25,7 @@ class WebTorrentPlugin extends Plugin {
25 25
26 private readonly playerElement: HTMLVideoElement 26 private readonly playerElement: HTMLVideoElement
27 27
28 private readonly autoplay: boolean = false 28 private readonly autoplay: boolean | string = false
29 private readonly startTime: number = 0 29 private readonly startTime: number = 0
30 private readonly savePlayerSrcFunction: videojs.Player['src'] 30 private readonly savePlayerSrcFunction: videojs.Player['src']
31 private readonly videoDuration: number 31 private readonly videoDuration: number
@@ -449,7 +449,7 @@ class WebTorrentPlugin extends Plugin {
449 return 449 return
450 } 450 }
451 451
452 if (this.autoplay) { 452 if (this.autoplay !== false) {
453 this.player.posterImage.hide() 453 this.player.posterImage.hide()
454 454
455 return this.updateVideoFile(undefined, { forcePlay: true, seek: this.startTime }) 455 return this.updateVideoFile(undefined, { forcePlay: true, seek: this.startTime })
diff --git a/client/src/assets/player/types/manager-options.ts b/client/src/assets/player/types/manager-options.ts
index 9da8fedf8..3057a5adb 100644
--- a/client/src/assets/player/types/manager-options.ts
+++ b/client/src/assets/player/types/manager-options.ts
@@ -36,6 +36,8 @@ export interface CommonOptions extends CustomizationOptions {
36 onPlayerElementChange: (element: HTMLVideoElement) => void 36 onPlayerElementChange: (element: HTMLVideoElement) => void
37 37
38 autoplay: boolean 38 autoplay: boolean
39 forceAutoplay: boolean
40
39 p2pEnabled: boolean 41 p2pEnabled: boolean
40 42
41 nextVideo?: () => void 43 nextVideo?: () => void
diff --git a/client/src/assets/player/types/peertube-videojs-typings.ts b/client/src/assets/player/types/peertube-videojs-typings.ts
index f02673a66..3d9d5270e 100644
--- a/client/src/assets/player/types/peertube-videojs-typings.ts
+++ b/client/src/assets/player/types/peertube-videojs-typings.ts
@@ -91,7 +91,7 @@ type VideoJSCaption = {
91type PeerTubePluginOptions = { 91type PeerTubePluginOptions = {
92 mode: PlayerMode 92 mode: PlayerMode
93 93
94 autoplay: boolean 94 autoplay: videojs.Autoplay
95 videoDuration: number 95 videoDuration: number
96 96
97 videoViewUrl: string 97 videoViewUrl: string
@@ -143,7 +143,7 @@ type PeerTubeP2PInfoButtonOptions = {
143type WebtorrentPluginOptions = { 143type WebtorrentPluginOptions = {
144 playerElement: HTMLVideoElement 144 playerElement: HTMLVideoElement
145 145
146 autoplay: boolean 146 autoplay: videojs.Autoplay
147 videoDuration: number 147 videoDuration: number
148 148
149 videoFiles: VideoFile[] 149 videoFiles: VideoFile[]
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts
index 2b826b9a2..5bb3b43c2 100644
--- a/client/src/standalone/videos/embed.ts
+++ b/client/src/standalone/videos/embed.ts
@@ -8,7 +8,16 @@ import { PeertubePlayerManager } from '../../assets/player'
8import { TranslationsManager } from '../../assets/player/translations-manager' 8import { TranslationsManager } from '../../assets/player/translations-manager'
9import { getParamString, logger, videoRequiresAuth } from '../../root-helpers' 9import { getParamString, logger, videoRequiresAuth } from '../../root-helpers'
10import { PeerTubeEmbedApi } from './embed-api' 10import { PeerTubeEmbedApi } from './embed-api'
11import { AuthHTTP, LiveManager, PeerTubePlugin, PlayerManagerOptions, PlaylistFetcher, PlaylistTracker, Translations, VideoFetcher } from './shared' 11import {
12 AuthHTTP,
13 LiveManager,
14 PeerTubePlugin,
15 PlayerManagerOptions,
16 PlaylistFetcher,
17 PlaylistTracker,
18 Translations,
19 VideoFetcher
20} from './shared'
12import { PlayerHTML } from './shared/player-html' 21import { PlayerHTML } from './shared/player-html'
13 22
14export class PeerTubeEmbed { 23export class PeerTubeEmbed {
@@ -81,7 +90,7 @@ export class PeerTubeEmbed {
81 90
82 if (!videoId) return 91 if (!videoId) return
83 92
84 return this.loadVideoAndBuildPlayer(videoId) 93 return this.loadVideoAndBuildPlayer({ uuid: videoId, forceAutoplay: false })
85 } 94 }
86 95
87 private async initPlaylist () { 96 private async initPlaylist () {
@@ -138,7 +147,7 @@ export class PeerTubeEmbed {
138 147
139 this.playlistTracker.setCurrentElement(next) 148 this.playlistTracker.setCurrentElement(next)
140 149
141 return this.loadVideoAndBuildPlayer(next.video.uuid) 150 return this.loadVideoAndBuildPlayer({ uuid: next.video.uuid, forceAutoplay: false })
142 } 151 }
143 152
144 async playPreviousPlaylistVideo () { 153 async playPreviousPlaylistVideo () {
@@ -150,7 +159,7 @@ export class PeerTubeEmbed {
150 159
151 this.playlistTracker.setCurrentElement(previous) 160 this.playlistTracker.setCurrentElement(previous)
152 161
153 await this.loadVideoAndBuildPlayer(previous.video.uuid) 162 await this.loadVideoAndBuildPlayer({ uuid: previous.video.uuid, forceAutoplay: false })
154 } 163 }
155 164
156 getCurrentPlaylistPosition () { 165 getCurrentPlaylistPosition () {
@@ -159,17 +168,28 @@ export class PeerTubeEmbed {
159 168
160 // --------------------------------------------------------------------------- 169 // ---------------------------------------------------------------------------
161 170
162 private async loadVideoAndBuildPlayer (uuid: string) { 171 private async loadVideoAndBuildPlayer (options: {
172 uuid: string
173 forceAutoplay: boolean
174 }) {
175 const { uuid, forceAutoplay } = options
176
163 try { 177 try {
164 const { videoResponse, captionsPromise } = await this.videoFetcher.loadVideo(uuid) 178 const { videoResponse, captionsPromise } = await this.videoFetcher.loadVideo(uuid)
165 179
166 return this.buildVideoPlayer(videoResponse, captionsPromise) 180 return this.buildVideoPlayer({ videoResponse, captionsPromise, forceAutoplay })
167 } catch (err) { 181 } catch (err) {
168 this.playerHTML.displayError(err.message, await this.translationsPromise) 182 this.playerHTML.displayError(err.message, await this.translationsPromise)
169 } 183 }
170 } 184 }
171 185
172 private async buildVideoPlayer (videoResponse: Response, captionsPromise: Promise<Response>) { 186 private async buildVideoPlayer (options: {
187 videoResponse: Response
188 captionsPromise: Promise<Response>
189 forceAutoplay: boolean
190 }) {
191 const { videoResponse, captionsPromise, forceAutoplay } = options
192
173 const alreadyHadPlayer = this.resetPlayerElement() 193 const alreadyHadPlayer = this.resetPlayerElement()
174 194
175 const videoInfoPromise = videoResponse.json() 195 const videoInfoPromise = videoResponse.json()
@@ -201,7 +221,7 @@ export class PeerTubeEmbed {
201 221
202 const PlayerManager: typeof PeertubePlayerManager = PeertubePlayerManagerModule.PeertubePlayerManager 222 const PlayerManager: typeof PeertubePlayerManager = PeertubePlayerManagerModule.PeertubePlayerManager
203 223
204 const options = await this.playerManagerOptions.getPlayerOptions({ 224 const playerOptions = await this.playerManagerOptions.getPlayerOptions({
205 video, 225 video,
206 captionsResponse, 226 captionsResponse,
207 alreadyHadPlayer, 227 alreadyHadPlayer,
@@ -211,16 +231,17 @@ export class PeerTubeEmbed {
211 authorizationHeader: () => this.http.getHeaderTokenValue(), 231 authorizationHeader: () => this.http.getHeaderTokenValue(),
212 videoFileToken: () => videoFileToken, 232 videoFileToken: () => videoFileToken,
213 233
214 onVideoUpdate: (uuid: string) => this.loadVideoAndBuildPlayer(uuid), 234 onVideoUpdate: (uuid: string) => this.loadVideoAndBuildPlayer({ uuid, forceAutoplay: false }),
215 235
216 playlistTracker: this.playlistTracker, 236 playlistTracker: this.playlistTracker,
217 playNextPlaylistVideo: () => this.playNextPlaylistVideo(), 237 playNextPlaylistVideo: () => this.playNextPlaylistVideo(),
218 playPreviousPlaylistVideo: () => this.playPreviousPlaylistVideo(), 238 playPreviousPlaylistVideo: () => this.playPreviousPlaylistVideo(),
219 239
220 live 240 live,
241 forceAutoplay
221 }) 242 })
222 243
223 this.player = await PlayerManager.initialize(this.playerManagerOptions.getMode(), options, (player: videojs.Player) => { 244 this.player = await PlayerManager.initialize(this.playerManagerOptions.getMode(), playerOptions, (player: videojs.Player) => {
224 this.player = player 245 this.player = player
225 }) 246 })
226 247
@@ -256,7 +277,7 @@ export class PeerTubeEmbed {
256 video, 277 video,
257 onPublishedVideo: () => { 278 onPublishedVideo: () => {
258 this.liveManager.stopListeningForChanges(video) 279 this.liveManager.stopListeningForChanges(video)
259 this.loadVideoAndBuildPlayer(video.uuid) 280 this.loadVideoAndBuildPlayer({ uuid: video.uuid, forceAutoplay: true })
260 } 281 }
261 }) 282 })
262 283
diff --git a/client/src/standalone/videos/shared/player-manager-options.ts b/client/src/standalone/videos/shared/player-manager-options.ts
index 87a84975b..9ec012369 100644
--- a/client/src/standalone/videos/shared/player-manager-options.ts
+++ b/client/src/standalone/videos/shared/player-manager-options.ts
@@ -155,6 +155,8 @@ export class PlayerManagerOptions {
155 captionsResponse: Response 155 captionsResponse: Response
156 live?: LiveVideo 156 live?: LiveVideo
157 157
158 forceAutoplay: boolean
159
158 authorizationHeader: () => string 160 authorizationHeader: () => string
159 videoFileToken: () => string 161 videoFileToken: () => string
160 162
@@ -175,6 +177,7 @@ export class PlayerManagerOptions {
175 alreadyHadPlayer, 177 alreadyHadPlayer,
176 videoFileToken, 178 videoFileToken,
177 translations, 179 translations,
180 forceAutoplay,
178 playlistTracker, 181 playlistTracker,
179 live, 182 live,
180 authorizationHeader, 183 authorizationHeader,
@@ -187,6 +190,7 @@ export class PlayerManagerOptions {
187 common: { 190 common: {
188 // Autoplay in playlist mode 191 // Autoplay in playlist mode
189 autoplay: alreadyHadPlayer ? true : this.autoplay, 192 autoplay: alreadyHadPlayer ? true : this.autoplay,
193 forceAutoplay,
190 194
191 controls: this.controls, 195 controls: this.controls,
192 controlBar: this.controlBar, 196 controlBar: this.controlBar,