Force autoplay when live starts

Using the mute
This commit is contained in:
Chocobozzz 2022-11-15 11:57:49 +01:00
parent c241947630
commit 59a643aa5c
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
8 changed files with 82 additions and 29 deletions

View File

@ -180,7 +180,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
} }
onPlaylistVideoFound (videoId: string) { onPlaylistVideoFound (videoId: string) {
this.loadVideo(videoId) this.loadVideo({ videoId, forceAutoplay: false })
} }
onPlaylistNoVideoFound () { onPlaylistNoVideoFound () {
@ -212,7 +212,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
private loadRouteParams () { private loadRouteParams () {
this.paramsSub = this.route.params.subscribe(routeParams => { this.paramsSub = this.route.params.subscribe(routeParams => {
const videoId = routeParams['videoId'] const videoId = routeParams['videoId']
if (videoId) return this.loadVideo(videoId) if (videoId) return this.loadVideo({ videoId, forceAutoplay: false })
const playlistId = routeParams['playlistId'] const playlistId = routeParams['playlistId']
if (playlistId) return this.loadPlaylist(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.isSameElement(this.video, videoId)) return
if (this.player) this.player.pause() if (this.player) this.player.pause()
@ -293,8 +298,15 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
peertubeLink: false peertubeLink: false
} }
this.onVideoFetched({ video, live, videoCaptions: captionsResult.data, videoFileToken, loggedInOrAnonymousUser, urlOptions }) this.onVideoFetched({
.catch(err => this.handleGlobalError(err)) video,
live,
videoCaptions: captionsResult.data,
videoFileToken,
loggedInOrAnonymousUser,
urlOptions,
forceAutoplay
}).catch(err => this.handleGlobalError(err))
}, },
error: err => this.handleRequestError(err) error: err => this.handleRequestError(err)
@ -370,8 +382,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
urlOptions: URLOptions urlOptions: URLOptions
loggedInOrAnonymousUser: User 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) this.subscribeToLiveEventsIfNeeded(this.video, video)
@ -393,7 +406,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
if (res === false) return this.location.back() 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)) .catch(err => logger.error('Cannot build the player', err))
this.setOpenGraphTags() this.setOpenGraphTags()
@ -406,7 +419,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.hooks.runAction('action:video-watch.video.loaded', 'video-watch', hookOptions) 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 // Flush old player if needed
this.flushPlayer() this.flushPlayer()
@ -430,6 +449,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
videoFileToken: this.videoFileToken, videoFileToken: this.videoFileToken,
urlOptions, urlOptions,
loggedInOrAnonymousUser, loggedInOrAnonymousUser,
forceAutoplay,
user: this.user user: this.user
} }
const { playerMode, playerOptions } = await this.hooks.wrapFun( const { playerMode, playerOptions } = await this.hooks.wrapFun(
@ -581,9 +601,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
urlOptions: CustomizationOptions & { playerMode: PlayerMode } urlOptions: CustomizationOptions & { playerMode: PlayerMode }
loggedInOrAnonymousUser: User loggedInOrAnonymousUser: User
forceAutoplay: boolean
user?: AuthUser // Keep for plugins 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 getStartTime = () => {
const byUrl = urlOptions.startTime !== undefined const byUrl = urlOptions.startTime !== undefined
@ -615,6 +636,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
const options: PeertubePlayerManagerOptions = { const options: PeertubePlayerManagerOptions = {
common: { common: {
autoplay: this.isAutoplay(), autoplay: this.isAutoplay(),
forceAutoplay,
p2pEnabled: isP2PEnabled(video, this.serverConfig, loggedInOrAnonymousUser.p2pEnabled), p2pEnabled: isP2PEnabled(video, this.serverConfig, loggedInOrAnonymousUser.p2pEnabled),
hasNextVideo: () => this.hasNextVideo(), hasNextVideo: () => this.hasNextVideo(),
@ -749,7 +771,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
// Reset to force refresh the video // Reset to force refresh the video
this.video = undefined this.video = undefined
this.loadVideo(videoUUID) this.loadVideo({ videoId: videoUUID, forceAutoplay: true })
} }
private handleLiveViewsChange (newViewers: number) { private handleLiveViewsChange (newViewers: number) {

View File

@ -105,10 +105,12 @@ export class ManagerOptionsBuilder {
Object.assign(videojsOptions, { language: commonOptions.language }) Object.assign(videojsOptions, { language: commonOptions.language })
} }
console.log(videojsOptions)
return videojsOptions return videojsOptions
} }
private getAutoPlayValue (autoplay: any, alreadyPlayed: boolean) { private getAutoPlayValue (autoplay: videojs.Autoplay, alreadyPlayed: boolean) {
if (autoplay !== true) return autoplay if (autoplay !== true) return autoplay
// On first play, disable autoplay to avoid issues // On first play, disable autoplay to avoid issues
@ -117,7 +119,9 @@ export class ManagerOptionsBuilder {
return alreadyPlayed ? 'play' : false return alreadyPlayed ? 'play' : false
} }
return 'play' return this.options.common.forceAutoplay
? 'any'
: 'play'
} }
getContextMenuOptions (player: videojs.Player, commonOptions: CommonOptions) { getContextMenuOptions (player: videojs.Player, commonOptions: CommonOptions) {

View File

@ -52,7 +52,7 @@ class PeerTubePlugin extends Plugin {
this.videoCaptions = options.videoCaptions this.videoCaptions = options.videoCaptions
this.initialInactivityTimeout = this.player.options_.inactivityTimeout 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.on('autoplay-failure', () => {
this.player.removeClass('vjs-has-autoplay') this.player.removeClass('vjs-has-autoplay')

View File

@ -25,7 +25,7 @@ class WebTorrentPlugin extends Plugin {
private readonly playerElement: HTMLVideoElement private readonly playerElement: HTMLVideoElement
private readonly autoplay: boolean = false private readonly autoplay: boolean | string = false
private readonly startTime: number = 0 private readonly startTime: number = 0
private readonly savePlayerSrcFunction: videojs.Player['src'] private readonly savePlayerSrcFunction: videojs.Player['src']
private readonly videoDuration: number private readonly videoDuration: number
@ -449,7 +449,7 @@ class WebTorrentPlugin extends Plugin {
return return
} }
if (this.autoplay) { if (this.autoplay !== false) {
this.player.posterImage.hide() this.player.posterImage.hide()
return this.updateVideoFile(undefined, { forcePlay: true, seek: this.startTime }) return this.updateVideoFile(undefined, { forcePlay: true, seek: this.startTime })

View File

@ -36,6 +36,8 @@ export interface CommonOptions extends CustomizationOptions {
onPlayerElementChange: (element: HTMLVideoElement) => void onPlayerElementChange: (element: HTMLVideoElement) => void
autoplay: boolean autoplay: boolean
forceAutoplay: boolean
p2pEnabled: boolean p2pEnabled: boolean
nextVideo?: () => void nextVideo?: () => void

View File

@ -91,7 +91,7 @@ type VideoJSCaption = {
type PeerTubePluginOptions = { type PeerTubePluginOptions = {
mode: PlayerMode mode: PlayerMode
autoplay: boolean autoplay: videojs.Autoplay
videoDuration: number videoDuration: number
videoViewUrl: string videoViewUrl: string
@ -143,7 +143,7 @@ type PeerTubeP2PInfoButtonOptions = {
type WebtorrentPluginOptions = { type WebtorrentPluginOptions = {
playerElement: HTMLVideoElement playerElement: HTMLVideoElement
autoplay: boolean autoplay: videojs.Autoplay
videoDuration: number videoDuration: number
videoFiles: VideoFile[] videoFiles: VideoFile[]

View File

@ -8,7 +8,16 @@ import { PeertubePlayerManager } from '../../assets/player'
import { TranslationsManager } from '../../assets/player/translations-manager' import { TranslationsManager } from '../../assets/player/translations-manager'
import { getParamString, logger, videoRequiresAuth } from '../../root-helpers' import { getParamString, logger, videoRequiresAuth } from '../../root-helpers'
import { PeerTubeEmbedApi } from './embed-api' 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' import { PlayerHTML } from './shared/player-html'
export class PeerTubeEmbed { export class PeerTubeEmbed {
@ -81,7 +90,7 @@ export class PeerTubeEmbed {
if (!videoId) return if (!videoId) return
return this.loadVideoAndBuildPlayer(videoId) return this.loadVideoAndBuildPlayer({ uuid: videoId, forceAutoplay: false })
} }
private async initPlaylist () { private async initPlaylist () {
@ -138,7 +147,7 @@ export class PeerTubeEmbed {
this.playlistTracker.setCurrentElement(next) this.playlistTracker.setCurrentElement(next)
return this.loadVideoAndBuildPlayer(next.video.uuid) return this.loadVideoAndBuildPlayer({ uuid: next.video.uuid, forceAutoplay: false })
} }
async playPreviousPlaylistVideo () { async playPreviousPlaylistVideo () {
@ -150,7 +159,7 @@ export class PeerTubeEmbed {
this.playlistTracker.setCurrentElement(previous) this.playlistTracker.setCurrentElement(previous)
await this.loadVideoAndBuildPlayer(previous.video.uuid) await this.loadVideoAndBuildPlayer({ uuid: previous.video.uuid, forceAutoplay: false })
} }
getCurrentPlaylistPosition () { 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 { try {
const { videoResponse, captionsPromise } = await this.videoFetcher.loadVideo(uuid) const { videoResponse, captionsPromise } = await this.videoFetcher.loadVideo(uuid)
return this.buildVideoPlayer(videoResponse, captionsPromise) return this.buildVideoPlayer({ videoResponse, captionsPromise, forceAutoplay })
} catch (err) { } catch (err) {
this.playerHTML.displayError(err.message, await this.translationsPromise) this.playerHTML.displayError(err.message, await this.translationsPromise)
} }
} }
private async buildVideoPlayer (videoResponse: Response, captionsPromise: Promise<Response>) { private async buildVideoPlayer (options: {
videoResponse: Response
captionsPromise: Promise<Response>
forceAutoplay: boolean
}) {
const { videoResponse, captionsPromise, forceAutoplay } = options
const alreadyHadPlayer = this.resetPlayerElement() const alreadyHadPlayer = this.resetPlayerElement()
const videoInfoPromise = videoResponse.json() const videoInfoPromise = videoResponse.json()
@ -201,7 +221,7 @@ export class PeerTubeEmbed {
const PlayerManager: typeof PeertubePlayerManager = PeertubePlayerManagerModule.PeertubePlayerManager const PlayerManager: typeof PeertubePlayerManager = PeertubePlayerManagerModule.PeertubePlayerManager
const options = await this.playerManagerOptions.getPlayerOptions({ const playerOptions = await this.playerManagerOptions.getPlayerOptions({
video, video,
captionsResponse, captionsResponse,
alreadyHadPlayer, alreadyHadPlayer,
@ -211,16 +231,17 @@ export class PeerTubeEmbed {
authorizationHeader: () => this.http.getHeaderTokenValue(), authorizationHeader: () => this.http.getHeaderTokenValue(),
videoFileToken: () => videoFileToken, videoFileToken: () => videoFileToken,
onVideoUpdate: (uuid: string) => this.loadVideoAndBuildPlayer(uuid), onVideoUpdate: (uuid: string) => this.loadVideoAndBuildPlayer({ uuid, forceAutoplay: false }),
playlistTracker: this.playlistTracker, playlistTracker: this.playlistTracker,
playNextPlaylistVideo: () => this.playNextPlaylistVideo(), playNextPlaylistVideo: () => this.playNextPlaylistVideo(),
playPreviousPlaylistVideo: () => this.playPreviousPlaylistVideo(), 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 this.player = player
}) })
@ -256,7 +277,7 @@ export class PeerTubeEmbed {
video, video,
onPublishedVideo: () => { onPublishedVideo: () => {
this.liveManager.stopListeningForChanges(video) this.liveManager.stopListeningForChanges(video)
this.loadVideoAndBuildPlayer(video.uuid) this.loadVideoAndBuildPlayer({ uuid: video.uuid, forceAutoplay: true })
} }
}) })

View File

@ -155,6 +155,8 @@ export class PlayerManagerOptions {
captionsResponse: Response captionsResponse: Response
live?: LiveVideo live?: LiveVideo
forceAutoplay: boolean
authorizationHeader: () => string authorizationHeader: () => string
videoFileToken: () => string videoFileToken: () => string
@ -175,6 +177,7 @@ export class PlayerManagerOptions {
alreadyHadPlayer, alreadyHadPlayer,
videoFileToken, videoFileToken,
translations, translations,
forceAutoplay,
playlistTracker, playlistTracker,
live, live,
authorizationHeader, authorizationHeader,
@ -187,6 +190,7 @@ export class PlayerManagerOptions {
common: { common: {
// Autoplay in playlist mode // Autoplay in playlist mode
autoplay: alreadyHadPlayer ? true : this.autoplay, autoplay: alreadyHadPlayer ? true : this.autoplay,
forceAutoplay,
controls: this.controls, controls: this.controls,
controlBar: this.controlBar, controlBar: this.controlBar,