From 59a643aa5cf6775d27dfcc147b19c4537292d53c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 15 Nov 2022 11:57:49 +0100 Subject: [PATCH] Force autoplay when live starts Using the mute --- .../+video-watch/video-watch.component.ts | 42 ++++++++++++----- .../manager-options-builder.ts | 8 +++- .../player/shared/peertube/peertube-plugin.ts | 2 +- .../shared/webtorrent/webtorrent-plugin.ts | 4 +- .../assets/player/types/manager-options.ts | 2 + .../player/types/peertube-videojs-typings.ts | 4 +- client/src/standalone/videos/embed.ts | 45 ++++++++++++++----- .../videos/shared/player-manager-options.ts | 4 ++ 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 { } onPlaylistVideoFound (videoId: string) { - this.loadVideo(videoId) + this.loadVideo({ videoId, forceAutoplay: false }) } onPlaylistNoVideoFound () { @@ -212,7 +212,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { private loadRouteParams () { this.paramsSub = this.route.params.subscribe(routeParams => { const videoId = routeParams['videoId'] - if (videoId) return this.loadVideo(videoId) + if (videoId) return this.loadVideo({ videoId, forceAutoplay: false }) const playlistId = routeParams['playlistId'] if (playlistId) return this.loadPlaylist(playlistId) @@ -240,7 +240,12 @@ export class VideoWatchComponent implements OnInit, OnDestroy { }) } - private loadVideo (videoId: string) { + private loadVideo (options: { + videoId: string + forceAutoplay: boolean + }) { + const { videoId, forceAutoplay } = options + if (this.isSameElement(this.video, videoId)) return if (this.player) this.player.pause() @@ -293,8 +298,15 @@ export class VideoWatchComponent implements OnInit, OnDestroy { peertubeLink: false } - this.onVideoFetched({ video, live, videoCaptions: captionsResult.data, videoFileToken, loggedInOrAnonymousUser, urlOptions }) - .catch(err => this.handleGlobalError(err)) + this.onVideoFetched({ + video, + live, + videoCaptions: captionsResult.data, + videoFileToken, + loggedInOrAnonymousUser, + urlOptions, + forceAutoplay + }).catch(err => this.handleGlobalError(err)) }, error: err => this.handleRequestError(err) @@ -370,8 +382,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy { urlOptions: URLOptions loggedInOrAnonymousUser: User + forceAutoplay: boolean }) { - const { video, live, videoCaptions, urlOptions, videoFileToken, loggedInOrAnonymousUser } = options + const { video, live, videoCaptions, urlOptions, videoFileToken, loggedInOrAnonymousUser, forceAutoplay } = options this.subscribeToLiveEventsIfNeeded(this.video, video) @@ -393,7 +406,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { if (res === false) return this.location.back() } - this.buildPlayer(urlOptions, loggedInOrAnonymousUser) + this.buildPlayer({ urlOptions, loggedInOrAnonymousUser, forceAutoplay }) .catch(err => logger.error('Cannot build the player', err)) this.setOpenGraphTags() @@ -406,7 +419,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy { this.hooks.runAction('action:video-watch.video.loaded', 'video-watch', hookOptions) } - private async buildPlayer (urlOptions: URLOptions, loggedInOrAnonymousUser: User) { + private async buildPlayer (options: { + urlOptions: URLOptions + loggedInOrAnonymousUser: User + forceAutoplay: boolean + }) { + const { urlOptions, loggedInOrAnonymousUser, forceAutoplay } = options + // Flush old player if needed this.flushPlayer() @@ -430,6 +449,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { videoFileToken: this.videoFileToken, urlOptions, loggedInOrAnonymousUser, + forceAutoplay, user: this.user } const { playerMode, playerOptions } = await this.hooks.wrapFun( @@ -581,9 +601,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy { urlOptions: CustomizationOptions & { playerMode: PlayerMode } loggedInOrAnonymousUser: User + forceAutoplay: boolean user?: AuthUser // Keep for plugins }) { - const { video, liveVideo, videoCaptions, videoFileToken, urlOptions, loggedInOrAnonymousUser } = params + const { video, liveVideo, videoCaptions, videoFileToken, urlOptions, loggedInOrAnonymousUser, forceAutoplay } = params const getStartTime = () => { const byUrl = urlOptions.startTime !== undefined @@ -615,6 +636,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { const options: PeertubePlayerManagerOptions = { common: { autoplay: this.isAutoplay(), + forceAutoplay, p2pEnabled: isP2PEnabled(video, this.serverConfig, loggedInOrAnonymousUser.p2pEnabled), hasNextVideo: () => this.hasNextVideo(), @@ -749,7 +771,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { // Reset to force refresh the video this.video = undefined - this.loadVideo(videoUUID) + this.loadVideo({ videoId: videoUUID, forceAutoplay: true }) } 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 { Object.assign(videojsOptions, { language: commonOptions.language }) } + console.log(videojsOptions) + return videojsOptions } - private getAutoPlayValue (autoplay: any, alreadyPlayed: boolean) { + private getAutoPlayValue (autoplay: videojs.Autoplay, alreadyPlayed: boolean) { if (autoplay !== true) return autoplay // On first play, disable autoplay to avoid issues @@ -117,7 +119,9 @@ export class ManagerOptionsBuilder { return alreadyPlayed ? 'play' : false } - return 'play' + return this.options.common.forceAutoplay + ? 'any' + : 'play' } 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 { this.videoCaptions = options.videoCaptions this.initialInactivityTimeout = this.player.options_.inactivityTimeout - if (options.autoplay) this.player.addClass('vjs-has-autoplay') + if (options.autoplay !== false) this.player.addClass('vjs-has-autoplay') this.player.on('autoplay-failure', () => { 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 { private readonly playerElement: HTMLVideoElement - private readonly autoplay: boolean = false + private readonly autoplay: boolean | string = false private readonly startTime: number = 0 private readonly savePlayerSrcFunction: videojs.Player['src'] private readonly videoDuration: number @@ -449,7 +449,7 @@ class WebTorrentPlugin extends Plugin { return } - if (this.autoplay) { + if (this.autoplay !== false) { this.player.posterImage.hide() 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 { onPlayerElementChange: (element: HTMLVideoElement) => void autoplay: boolean + forceAutoplay: boolean + p2pEnabled: boolean 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 = { type PeerTubePluginOptions = { mode: PlayerMode - autoplay: boolean + autoplay: videojs.Autoplay videoDuration: number videoViewUrl: string @@ -143,7 +143,7 @@ type PeerTubeP2PInfoButtonOptions = { type WebtorrentPluginOptions = { playerElement: HTMLVideoElement - autoplay: boolean + autoplay: videojs.Autoplay videoDuration: number 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' import { TranslationsManager } from '../../assets/player/translations-manager' import { getParamString, logger, videoRequiresAuth } from '../../root-helpers' import { PeerTubeEmbedApi } from './embed-api' -import { AuthHTTP, LiveManager, PeerTubePlugin, PlayerManagerOptions, PlaylistFetcher, PlaylistTracker, Translations, VideoFetcher } from './shared' +import { + AuthHTTP, + LiveManager, + PeerTubePlugin, + PlayerManagerOptions, + PlaylistFetcher, + PlaylistTracker, + Translations, + VideoFetcher +} from './shared' import { PlayerHTML } from './shared/player-html' export class PeerTubeEmbed { @@ -81,7 +90,7 @@ export class PeerTubeEmbed { if (!videoId) return - return this.loadVideoAndBuildPlayer(videoId) + return this.loadVideoAndBuildPlayer({ uuid: videoId, forceAutoplay: false }) } private async initPlaylist () { @@ -138,7 +147,7 @@ export class PeerTubeEmbed { this.playlistTracker.setCurrentElement(next) - return this.loadVideoAndBuildPlayer(next.video.uuid) + return this.loadVideoAndBuildPlayer({ uuid: next.video.uuid, forceAutoplay: false }) } async playPreviousPlaylistVideo () { @@ -150,7 +159,7 @@ export class PeerTubeEmbed { this.playlistTracker.setCurrentElement(previous) - await this.loadVideoAndBuildPlayer(previous.video.uuid) + await this.loadVideoAndBuildPlayer({ uuid: previous.video.uuid, forceAutoplay: false }) } getCurrentPlaylistPosition () { @@ -159,17 +168,28 @@ export class PeerTubeEmbed { // --------------------------------------------------------------------------- - private async loadVideoAndBuildPlayer (uuid: string) { + private async loadVideoAndBuildPlayer (options: { + uuid: string + forceAutoplay: boolean + }) { + const { uuid, forceAutoplay } = options + try { const { videoResponse, captionsPromise } = await this.videoFetcher.loadVideo(uuid) - return this.buildVideoPlayer(videoResponse, captionsPromise) + return this.buildVideoPlayer({ videoResponse, captionsPromise, forceAutoplay }) } catch (err) { this.playerHTML.displayError(err.message, await this.translationsPromise) } } - private async buildVideoPlayer (videoResponse: Response, captionsPromise: Promise) { + private async buildVideoPlayer (options: { + videoResponse: Response + captionsPromise: Promise + forceAutoplay: boolean + }) { + const { videoResponse, captionsPromise, forceAutoplay } = options + const alreadyHadPlayer = this.resetPlayerElement() const videoInfoPromise = videoResponse.json() @@ -201,7 +221,7 @@ export class PeerTubeEmbed { const PlayerManager: typeof PeertubePlayerManager = PeertubePlayerManagerModule.PeertubePlayerManager - const options = await this.playerManagerOptions.getPlayerOptions({ + const playerOptions = await this.playerManagerOptions.getPlayerOptions({ video, captionsResponse, alreadyHadPlayer, @@ -211,16 +231,17 @@ export class PeerTubeEmbed { authorizationHeader: () => this.http.getHeaderTokenValue(), videoFileToken: () => videoFileToken, - onVideoUpdate: (uuid: string) => this.loadVideoAndBuildPlayer(uuid), + onVideoUpdate: (uuid: string) => this.loadVideoAndBuildPlayer({ uuid, forceAutoplay: false }), playlistTracker: this.playlistTracker, playNextPlaylistVideo: () => this.playNextPlaylistVideo(), playPreviousPlaylistVideo: () => this.playPreviousPlaylistVideo(), - live + live, + forceAutoplay }) - this.player = await PlayerManager.initialize(this.playerManagerOptions.getMode(), options, (player: videojs.Player) => { + this.player = await PlayerManager.initialize(this.playerManagerOptions.getMode(), playerOptions, (player: videojs.Player) => { this.player = player }) @@ -256,7 +277,7 @@ export class PeerTubeEmbed { video, onPublishedVideo: () => { this.liveManager.stopListeningForChanges(video) - this.loadVideoAndBuildPlayer(video.uuid) + this.loadVideoAndBuildPlayer({ uuid: video.uuid, forceAutoplay: true }) } }) 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 { captionsResponse: Response live?: LiveVideo + forceAutoplay: boolean + authorizationHeader: () => string videoFileToken: () => string @@ -175,6 +177,7 @@ export class PlayerManagerOptions { alreadyHadPlayer, videoFileToken, translations, + forceAutoplay, playlistTracker, live, authorizationHeader, @@ -187,6 +190,7 @@ export class PlayerManagerOptions { common: { // Autoplay in playlist mode autoplay: alreadyHadPlayer ? true : this.autoplay, + forceAutoplay, controls: this.controls, controlBar: this.controlBar, -- 2.41.0