]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - server/lib/views/video-views-manager.ts
Improve views/viewers documentation
[github/Chocobozzz/PeerTube.git] / server / lib / views / video-views-manager.ts
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'
5
6 /**
7 * If processing a local view:
8 * - We update viewer information (segments watched, watch time etc)
9 * - We add +1 to video viewers counter if this is a new viewer
10 * - We add +1 to video views counter if this is a new view and if the user watched enough seconds
11 * - We send AP message to notify about this viewer and this view
12 * - We update last video time for the user if authenticated
13 *
14 * If processing a remote view:
15 * - We add +1 to video viewers counter
16 * - We add +1 to video views counter
17 *
18 * A viewer is a someone that watched one or multiple sections of a video
19 * A viewer that watched only a few seconds of a video may not increment the video views counter
20 * Viewers statistics are sent to origin instance using the `WatchAction` ActivityPub object
21 *
22 */
23
24 const lTags = loggerTagsFactory('views')
25
26 export class VideoViewsManager {
27
28 private static instance: VideoViewsManager
29
30 private videoViewers: VideoViewers
31 private videoViews: VideoViews
32
33 private constructor () {
34 }
35
36 init () {
37 this.videoViewers = new VideoViewers()
38 this.videoViews = new VideoViews()
39 }
40
41 async processLocalView (options: {
42 video: MVideo
43 currentTime: number
44 ip: string | null
45 viewEvent?: VideoViewEvent
46 }) {
47 const { video, ip, viewEvent, currentTime } = options
48
49 logger.debug('Processing local view for %s and ip %s.', video.url, ip, lTags())
50
51 const successViewer = await this.videoViewers.addLocalViewer({ video, ip, viewEvent, currentTime })
52
53 // Do it after added local viewer to fetch updated information
54 const watchTime = await this.videoViewers.getWatchTime(video.id, ip)
55
56 const successView = await this.videoViews.addLocalView({ video, watchTime, ip })
57
58 return { successView, successViewer }
59 }
60
61 async processRemoteView (options: {
62 video: MVideo
63 viewerExpires?: Date
64 }) {
65 const { video, viewerExpires } = options
66
67 logger.debug('Processing remote view for %s.', video.url, { viewerExpires, ...lTags() })
68
69 if (viewerExpires) await this.videoViewers.addRemoteViewer({ video, viewerExpires })
70 else await this.videoViews.addRemoteView({ video })
71 }
72
73 getViewers (video: MVideo) {
74 return this.videoViewers.getViewers(video)
75 }
76
77 buildViewerExpireTime () {
78 return this.videoViewers.buildViewerExpireTime()
79 }
80
81 processViewers () {
82 return this.videoViewers.processViewerStats()
83 }
84
85 static get Instance () {
86 return this.instance || (this.instance = new this())
87 }
88 }