diff --git a/packages/ffmpeg/src/ffmpeg-command-wrapper.ts b/packages/ffmpeg/src/ffmpeg-command-wrapper.ts index 6c4ab035d..482d20320 100644 --- a/packages/ffmpeg/src/ffmpeg-command-wrapper.ts +++ b/packages/ffmpeg/src/ffmpeg-command-wrapper.ts @@ -3,10 +3,10 @@ import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams, import ffmpeg, { FfmpegCommand } from 'fluent-ffmpeg' type FFmpegLogger = { - info: (msg: string, obj?: any) => void - debug: (msg: string, obj?: any) => void - warn: (msg: string, obj?: any) => void - error: (msg: string, obj?: any) => void + info: (msg: string, obj?: object) => void + debug: (msg: string, obj?: object) => void + warn: (msg: string, obj?: object) => void + error: (msg: string, obj?: object) => void } export interface FFmpegCommandWrapperOptions { diff --git a/packages/tests/src/api/views/video-views-retention-stats.ts b/packages/tests/src/api/views/video-views-retention-stats.ts index 9279b29df..8ffe7c702 100644 --- a/packages/tests/src/api/views/video-views-retention-stats.ts +++ b/packages/tests/src/api/views/video-views-retention-stats.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ -import { expect } from 'chai' -import { prepareViewsServers, prepareViewsVideos, processViewersStats } from '@tests/shared/views.js' -import { cleanupTests, PeerTubeServer } from '@peertube/peertube-server-commands' import { wait } from '@peertube/peertube-core-utils' +import { PeerTubeServer, cleanupTests } from '@peertube/peertube-server-commands' +import { prepareViewsServers, prepareViewsVideos, processViewersStats } from '@tests/shared/views.js' +import { expect } from 'chai' describe('Test views retention stats', function () { let servers: PeerTubeServer[] @@ -36,15 +36,20 @@ describe('Test views retention stats', function () { it('Should display appropriate retention metrics', async function () { await servers[0].views.simulateViewer({ xForwardedFor: '127.0.0.2,127.0.0.1', id: vodVideoId, currentTimes: [ 0, 1 ] }) await servers[0].views.simulateViewer({ xForwardedFor: '127.0.0.3,127.0.0.1', id: vodVideoId, currentTimes: [ 1, 3 ] }) - await servers[1].views.simulateViewer({ xForwardedFor: '127.0.0.2,127.0.0.1', id: vodVideoId, currentTimes: [ 4 ] }) + await servers[1].views.simulateViewer({ xForwardedFor: '127.0.0.2,127.0.0.1', id: vodVideoId, currentTimes: [ 3, 4 ] }) await servers[1].views.simulateViewer({ xForwardedFor: '127.0.0.3,127.0.0.1', id: vodVideoId, currentTimes: [ 0, 1 ] }) + // Do not take into account empty section + await servers[1].views.simulateViewer({ xForwardedFor: '127.0.0.3,127.0.0.1', id: vodVideoId, currentTimes: [ 5, 5 ] }) + await servers[0].views.simulateViewer({ xForwardedFor: '127.0.0.4,127.0.0.1', id: vodVideoId, currentTimes: [ 1, 1 ] }) + await servers[1].views.simulateViewer({ xForwardedFor: '127.0.0.4,127.0.0.1', id: vodVideoId, currentTimes: [ 1, 1 ] }) + await processViewersStats(servers) const { data } = await servers[0].videoStats.getRetentionStats({ videoId: vodVideoId }) expect(data).to.have.lengthOf(6) - expect(data.map(d => d.retentionPercent)).to.deep.equal([ 50, 75, 25, 25, 25, 0 ]) + expect(data.map(d => d.retentionPercent)).to.deep.equal([ 50, 75, 25, 50, 25, 0 ]) }) it('Should display appropriate retention metrics after a server restart', async function () { diff --git a/server/core/lib/views/shared/video-viewer-stats.ts b/server/core/lib/views/shared/video-viewer-stats.ts index cb62a61d3..cee804ce8 100644 --- a/server/core/lib/views/shared/video-viewer-stats.ts +++ b/server/core/lib/views/shared/video-viewer-stats.ts @@ -160,7 +160,7 @@ export class VideoViewerStats { const statsModel = await this.saveViewerStats(video, stats, t) - if (video.remote) { + if (statsModel && video.remote) { await sendCreateWatchAction(statsModel, t) } }) @@ -178,6 +178,8 @@ export class VideoViewerStats { } private async saveViewerStats (video: MVideo, stats: LocalViewerStats, transaction: Transaction) { + if (stats.watchTime === 0) return + const statsModel = new LocalVideoViewerModel({ startDate: new Date(stats.firstUpdated), endDate: new Date(stats.lastUpdated), diff --git a/server/core/models/view/local-video-viewer-watch-section.ts b/server/core/models/view/local-video-viewer-watch-section.ts index ceccde043..ae7f83bca 100644 --- a/server/core/models/view/local-video-viewer-watch-section.ts +++ b/server/core/models/view/local-video-viewer-watch-section.ts @@ -1,8 +1,8 @@ +import { MLocalVideoViewerWatchSection } from '@server/types/models/index.js' import { Transaction } from 'sequelize' import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Table } from 'sequelize-typescript' -import { MLocalVideoViewerWatchSection } from '@server/types/models/index.js' -import { LocalVideoViewerModel } from './local-video-viewer.js' import { SequelizeModel } from '../shared/index.js' +import { LocalVideoViewerModel } from './local-video-viewer.js' @Table({ tableName: 'localVideoViewerWatchSection', @@ -49,9 +49,14 @@ export class LocalVideoViewerWatchSectionModel extends SequelizeModel