1 import { logger, loggerTagsFactory } from '@server/helpers/logger'
2 import { MVideo } from '@server/types/models'
3 import { VideoViewEvent } from '@shared/models'
4 import { VideoViewers, VideoViews } from './shared'
6 const lTags = loggerTagsFactory('views')
8 export class VideoViewsManager {
10 private static instance: VideoViewsManager
12 private videoViewers: VideoViewers
13 private videoViews: VideoViews
15 private constructor () {
19 this.videoViewers = new VideoViewers()
20 this.videoViews = new VideoViews()
23 async processLocalView (options: {
27 viewEvent?: VideoViewEvent
29 const { video, ip, viewEvent, currentTime } = options
31 logger.debug('Processing local view for %s and ip %s.', video.url, ip, lTags())
33 const successViewer = await this.videoViewers.addLocalViewer({ video, ip, viewEvent, currentTime })
35 // Do it after added local viewer to fetch updated information
36 const watchTime = await this.videoViewers.getWatchTime(video.id, ip)
38 const successView = await this.videoViews.addLocalView({ video, watchTime, ip })
40 return { successView, successViewer }
43 async processRemoteView (options: {
47 const { video, viewerExpires } = options
49 logger.debug('Processing remote view for %s.', video.url, { viewerExpires, ...lTags() })
51 if (viewerExpires) await this.videoViewers.addRemoteViewer({ video, viewerExpires })
52 else await this.videoViews.addRemoteView({ video })
55 getViewers (video: MVideo) {
56 return this.videoViewers.getViewers(video)
59 buildViewerExpireTime () {
60 return this.videoViewers.buildViewerExpireTime()
64 return this.videoViewers.processViewerStats()
67 static get Instance () {
68 return this.instance || (this.instance = new this())