Resume videos for non-logged in users (#3885)

* client: resume videos for non-logged in users

closes #3866

* fix build for embeded

* Update client/src/app/app.component.ts

* fix review comments
pull/3909/head
kontrollanten 2021-03-31 11:26:32 +02:00 committed by GitHub
parent d794137057
commit 58b9ce3080
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 8 deletions

View File

@ -29,7 +29,7 @@ import { MetaService } from '@ngx-meta/core'
import { peertubeLocalStorage } from '@root-helpers/peertube-web-storage'
import { HttpStatusCode } from '@shared/core-utils/miscs/http-error-codes'
import { ServerConfig, ServerErrorCode, UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '@shared/models'
import { getStoredP2PEnabled, getStoredTheater } from '../../../assets/player/peertube-player-local-storage'
import { cleanupVideoWatch, getStoredP2PEnabled, getStoredTheater, getStoredVideoWatchHistory } from '../../../assets/player/peertube-player-local-storage'
import {
CustomizationOptions,
P2PMediaLoaderOptions,
@ -195,6 +195,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
this.theaterEnabled = getStoredTheater()
this.hooks.runAction('action:video-watch.init', 'video-watch')
setTimeout(cleanupVideoWatch, 1500) // Run in timeout to ensure we're not blocking the UI
}
ngOnDestroy () {
@ -768,9 +770,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
const getStartTime = () => {
const byUrl = urlOptions.startTime !== undefined
const byHistory = video.userHistory && (!this.playlist || urlOptions.resume !== undefined)
const byLocalStorage = getStoredVideoWatchHistory(video.uuid)
if (byUrl) return timeToInt(urlOptions.startTime)
if (byHistory) return video.userHistory.currentTime
if (byLocalStorage) return byLocalStorage.duration
return 0
}
@ -828,7 +832,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
serverUrl: environment.apiUrl,
videoCaptions: playerCaptions
videoCaptions: playerCaptions,
videoUUID: video.uuid
},
webtorrent: {

View File

@ -68,6 +68,51 @@ function getStoredLastSubtitle () {
return getLocalStorage('last-subtitle')
}
function saveVideoWatchHistory(videoUUID: string, duration: number) {
return setLocalStorage(`video-watch-history`, JSON.stringify({
...getStoredVideoWatchHistory(),
[videoUUID]: {
duration,
date: `${(new Date()).toISOString()}`
}
}))
}
function getStoredVideoWatchHistory(videoUUID?: string) {
let data
try {
data = JSON.parse(getLocalStorage('video-watch-history'))
} catch (error) {
console.error('Cannot parse video watch history from local storage: ', error)
}
data = data || {}
if (videoUUID) return data[videoUUID]
return data
}
function cleanupVideoWatch() {
const data = getStoredVideoWatchHistory()
const newData = Object.keys(data).reduce((acc, videoUUID) => {
const date = Date.parse(data[videoUUID].date)
const diff = Math.ceil(((new Date()).getTime() - date) / (1000 * 3600 * 24))
if (diff > 30) return acc
return {
...acc,
[videoUUID]: data[videoUUID]
}
}, {})
setLocalStorage('video-watch-history', JSON.stringify(newData))
}
// ---------------------------------------------------------------------------
export {
@ -81,7 +126,10 @@ export {
saveAverageBandwidth,
getAverageBandwidthInStore,
saveLastSubtitle,
getStoredLastSubtitle
getStoredLastSubtitle,
saveVideoWatchHistory,
getStoredVideoWatchHistory,
cleanupVideoWatch
}
// ---------------------------------------------------------------------------

View File

@ -106,6 +106,8 @@ export interface CommonOptions extends CustomizationOptions {
videoCaptions: VideoJSCaption[]
videoUUID: string
userWatching?: UserWatching
serverUrl: string
@ -231,7 +233,8 @@ export class PeertubePlayerManager {
subtitle: commonOptions.subtitle,
videoCaptions: commonOptions.videoCaptions,
stopTime: commonOptions.stopTime,
isLive: commonOptions.isLive
isLive: commonOptions.isLive,
videoUUID: commonOptions.videoUUID
}
}

View File

@ -13,6 +13,7 @@ import {
getStoredVolume,
saveLastSubtitle,
saveMuteInStore,
saveVideoWatchHistory,
saveVolumeInStore
} from './peertube-player-local-storage'
@ -120,7 +121,7 @@ class PeerTubePlugin extends Plugin {
this.initializePlayer()
this.runViewAdd()
if (options.userWatching) this.runUserWatchVideo(options.userWatching)
this.runUserWatchVideo(options.userWatching, options.videoUUID)
})
}
@ -178,7 +179,7 @@ class PeerTubePlugin extends Plugin {
}, 1000)
}
private runUserWatchVideo (options: UserWatching) {
private runUserWatchVideo (options: UserWatching, videoUUID: string) {
let lastCurrentTime = 0
this.userWatchingVideoInterval = setInterval(() => {
@ -187,8 +188,12 @@ class PeerTubePlugin extends Plugin {
if (currentTime - lastCurrentTime >= 1) {
lastCurrentTime = currentTime
this.notifyUserIsWatching(currentTime, options.url, options.authorizationHeader)
.catch(err => console.error('Cannot notify user is watching.', err))
if (options) {
this.notifyUserIsWatching(currentTime, options.url, options.authorizationHeader)
.catch(err => console.error('Cannot notify user is watching.', err))
} else {
saveVideoWatchHistory(videoUUID, currentTime)
}
}
}, this.CONSTANTS.USER_WATCHING_VIDEO_INTERVAL)
}

View File

@ -108,6 +108,8 @@ type PeerTubePluginOptions = {
stopTime: number | string
isLive: boolean
videoUUID: string
}
type PlaylistPluginOptions = {

View File

@ -531,6 +531,7 @@ export class PeerTubeEmbed {
videoCaptions,
inactivityTimeout: 2500,
videoViewUrl: this.getVideoUrl(videoInfo.uuid) + '/views',
videoUUID: videoInfo.uuid,
isLive: videoInfo.isLive,