Add ability to customize views/playback interval
This commit is contained in:
parent
49a4b8cb7d
commit
fe37e5232b
15 changed files with 143 additions and 14 deletions
|
@ -113,8 +113,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
|
||||
private hotkeys: Hotkey[] = []
|
||||
|
||||
private static VIEW_VIDEO_INTERVAL_MS = 5000
|
||||
|
||||
constructor (
|
||||
private route: ActivatedRoute,
|
||||
private router: Router,
|
||||
|
@ -625,9 +623,16 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
|
||||
instanceName: this.serverConfig.instance.name,
|
||||
language: this.localeId,
|
||||
metricsUrl: environment.apiUrl + '/api/v1/metrics/playback',
|
||||
|
||||
videoViewIntervalMs: VideoWatchComponent.VIEW_VIDEO_INTERVAL_MS,
|
||||
metricsUrl: this.serverConfig.openTelemetry.metrics.enabled
|
||||
? environment.apiUrl + '/api/v1/metrics/playback'
|
||||
: null,
|
||||
metricsInterval: this.serverConfig.openTelemetry.metrics.playbackStatsInterval,
|
||||
|
||||
videoViewIntervalMs: this.isUserLoggedIn()
|
||||
? this.serverConfig.views.videos.watchingInterval.users
|
||||
: this.serverConfig.views.videos.watchingInterval.anonymous,
|
||||
|
||||
authorizationHeader: () => this.authService.getRequestHeaderValue(),
|
||||
|
||||
serverUrl: environment.originServerUrl || window.location.origin,
|
||||
|
|
|
@ -382,6 +382,7 @@ export class PeerTubePlayer {
|
|||
mode: () => this.currentLoadOptions.mode,
|
||||
|
||||
metricsUrl: () => this.options.metricsUrl,
|
||||
metricsInterval: () => this.options.metricsInterval,
|
||||
videoUUID: () => this.currentLoadOptions.videoUUID
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,10 +25,6 @@ class MetricsPlugin extends Plugin {
|
|||
|
||||
private metricsInterval: any
|
||||
|
||||
private readonly CONSTANTS = {
|
||||
METRICS_INTERVAL: 15000
|
||||
}
|
||||
|
||||
constructor (player: videojs.Player, options: MetricsPluginOptions) {
|
||||
super(player)
|
||||
|
||||
|
@ -74,6 +70,7 @@ class MetricsPlugin extends Plugin {
|
|||
|
||||
private runMetricsInterval () {
|
||||
if (this.metricsInterval) clearInterval(this.metricsInterval)
|
||||
if (!this.options_.metricsUrl()) return
|
||||
|
||||
this.metricsInterval = setInterval(() => {
|
||||
let resolution: number
|
||||
|
@ -135,7 +132,7 @@ class MetricsPlugin extends Plugin {
|
|||
|
||||
return fetch(this.options_.metricsUrl(), { method: 'POST', body: JSON.stringify(body), headers })
|
||||
.catch(err => logger.error('Cannot send metrics to the server.', err))
|
||||
}, this.CONSTANTS.METRICS_INTERVAL)
|
||||
}, this.options_.metricsInterval())
|
||||
}
|
||||
|
||||
private trackBytes () {
|
||||
|
|
|
@ -30,6 +30,8 @@ export type PeerTubePlayerContructorOptions = {
|
|||
authorizationHeader: () => string
|
||||
|
||||
metricsUrl: string
|
||||
metricsInterval: number
|
||||
|
||||
serverUrl: string
|
||||
|
||||
errorNotifier: (message: string) => void
|
||||
|
|
|
@ -135,6 +135,7 @@ type PeerTubePluginOptions = {
|
|||
type MetricsPluginOptions = {
|
||||
mode: () => PlayerMode
|
||||
metricsUrl: () => string
|
||||
metricsInterval: () => number
|
||||
videoUUID: () => string
|
||||
}
|
||||
|
||||
|
|
|
@ -186,8 +186,13 @@ export class PlayerOptionsBuilder {
|
|||
playbackRate: this.playbackRate,
|
||||
|
||||
inactivityTimeout: 2500,
|
||||
videoViewIntervalMs: 5000,
|
||||
metricsUrl: window.location.origin + '/api/v1/metrics/playback',
|
||||
|
||||
videoViewIntervalMs: serverConfig.views.videos.watchingInterval.anonymous,
|
||||
|
||||
metricsUrl: serverConfig.openTelemetry.metrics.enabled
|
||||
? window.location.origin + '/api/v1/metrics/playback'
|
||||
: null,
|
||||
metricsInterval: serverConfig.openTelemetry.metrics.playbackStatsInterval,
|
||||
|
||||
authorizationHeader,
|
||||
|
||||
|
|
|
@ -254,6 +254,9 @@ open_telemetry:
|
|||
metrics:
|
||||
enabled: false
|
||||
|
||||
# How often viewers send playback stats to server
|
||||
playback_stats_interval: '15 seconds'
|
||||
|
||||
http_request_duration:
|
||||
# You can disable HTTP request duration metric that can have a high tag cardinality
|
||||
enabled: true
|
||||
|
@ -362,6 +365,17 @@ views:
|
|||
|
||||
ip_view_expiration: '1 hour'
|
||||
|
||||
# How often the web browser sends "is watching" information to the server
|
||||
# Increase the value or set null to disable it if you plan to have many viewers
|
||||
watching_interval:
|
||||
# Non logged-in viewers
|
||||
anonymous: '5 seconds'
|
||||
|
||||
# Logged-in users of your instance
|
||||
# Unlike anonymous viewers, this endpoint is also used to store the "last watched video timecode" for your users
|
||||
# Increasing this value reduces the accuracy of the video resume
|
||||
users: '5 seconds'
|
||||
|
||||
# Used to get country location of views of local videos
|
||||
geo_ip:
|
||||
enabled: true
|
||||
|
|
|
@ -38,6 +38,7 @@ log:
|
|||
open_telemetry:
|
||||
metrics:
|
||||
enabled: true
|
||||
playback_stats_interval: '13 seconds'
|
||||
|
||||
contact_form:
|
||||
enabled: true
|
||||
|
@ -118,6 +119,10 @@ views:
|
|||
remote:
|
||||
max_age: -1
|
||||
|
||||
watching_interval:
|
||||
anonymous: '6 seconds'
|
||||
users: '4 seconds'
|
||||
|
||||
geo_ip:
|
||||
enabled: true
|
||||
|
||||
|
|
|
@ -252,6 +252,9 @@ open_telemetry:
|
|||
metrics:
|
||||
enabled: false
|
||||
|
||||
# How often viewers send playback stats to server
|
||||
playback_stats_interval: '15 seconds'
|
||||
|
||||
http_request_duration:
|
||||
# You can disable HTTP request duration metric that can have a high tag cardinality
|
||||
enabled: true
|
||||
|
@ -360,6 +363,17 @@ views:
|
|||
|
||||
ip_view_expiration: '1 hour'
|
||||
|
||||
# How often the web browser sends "is watching" information to the server
|
||||
# Increase the value or set null to disable it if you plan to have many viewers
|
||||
watching_interval:
|
||||
# Non logged-in viewers
|
||||
anonymous: '5 seconds'
|
||||
|
||||
# Logged-in users of your instance
|
||||
# Unlike anonymous viewers, this endpoint is also used to store the "last watched video timecode" for your users
|
||||
# Increasing this value reduces the accuracy of the video resume
|
||||
users: '5 seconds'
|
||||
|
||||
# Used to get country location of views of local videos
|
||||
geo_ip:
|
||||
enabled: true
|
||||
|
|
|
@ -300,6 +300,27 @@ export interface ServerConfig {
|
|||
homepage: {
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
openTelemetry: {
|
||||
metrics: {
|
||||
enabled: boolean
|
||||
|
||||
// milliseconds
|
||||
playbackStatsInterval: number
|
||||
}
|
||||
}
|
||||
|
||||
views: {
|
||||
videos: {
|
||||
watchingInterval: {
|
||||
// milliseconds
|
||||
anonymous: number
|
||||
|
||||
// milliseconds
|
||||
users: number
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export type HTMLServerConfig = Omit<ServerConfig, 'signup'>
|
||||
|
|
|
@ -498,6 +498,16 @@ describe('Test config', function () {
|
|||
await setAccessTokensToServers([ server ])
|
||||
})
|
||||
|
||||
it('Should have the correct default config', async function () {
|
||||
const data = await server.config.getConfig()
|
||||
|
||||
expect(data.openTelemetry.metrics.enabled).to.be.false
|
||||
expect(data.openTelemetry.metrics.playbackStatsInterval).to.equal(15000)
|
||||
|
||||
expect(data.views.videos.watchingInterval.anonymous).to.equal(5000)
|
||||
expect(data.views.videos.watchingInterval.users).to.equal(5000)
|
||||
})
|
||||
|
||||
it('Should have a correct config on a server with registration enabled', async function () {
|
||||
const data = await server.config.getConfig()
|
||||
|
||||
|
|
|
@ -19,8 +19,9 @@ function checkMissedConfig () {
|
|||
'storage.redundancy', 'storage.tmp', 'storage.streaming_playlists', 'storage.plugins', 'storage.well_known',
|
||||
'log.level', 'log.rotation.enabled', 'log.rotation.max_file_size', 'log.rotation.max_files', 'log.anonymize_ip',
|
||||
'log.log_ping_requests', 'log.log_tracker_unknown_infohash', 'log.prettify_sql', 'log.accept_client_log',
|
||||
'open_telemetry.metrics.enabled', 'open_telemetry.metrics.prometheus_exporter.hostname',
|
||||
'open_telemetry.metrics.prometheus_exporter.port', 'open_telemetry.tracing.enabled', 'open_telemetry.tracing.jaeger_exporter.endpoint',
|
||||
'open_telemetry.metrics.enabled', 'open_telemetry.metrics.playback_stats_interval',
|
||||
'open_telemetry.metrics.prometheus_exporter.hostname', 'open_telemetry.metrics.prometheus_exporter.port',
|
||||
'open_telemetry.tracing.enabled', 'open_telemetry.tracing.jaeger_exporter.endpoint',
|
||||
'open_telemetry.metrics.http_request_duration.enabled',
|
||||
'user.history.videos.enabled', 'user.video_quota', 'user.video_quota_daily',
|
||||
'video_channels.max_per_user',
|
||||
|
@ -54,6 +55,7 @@ function checkMissedConfig () {
|
|||
'followers.instance.enabled', 'followers.instance.manual_approval',
|
||||
'tracker.enabled', 'tracker.private', 'tracker.reject_too_many_announces',
|
||||
'history.videos.max_age', 'views.videos.remote.max_age', 'views.videos.local_buffer_update_interval', 'views.videos.ip_view_expiration',
|
||||
'views.videos.watching_interval.anonymous', 'views.videos.watching_interval.users',
|
||||
'rates_limit.api.window', 'rates_limit.api.max', 'rates_limit.login.window', 'rates_limit.login.max',
|
||||
'rates_limit.signup.window', 'rates_limit.signup.max', 'rates_limit.ask_send_email.window', 'rates_limit.ask_send_email.max',
|
||||
'rates_limit.receive_client_log.window', 'rates_limit.receive_client_log.max', 'rates_limit.plugins.window', 'rates_limit.plugins.max',
|
||||
|
|
|
@ -228,6 +228,8 @@ const CONFIG = {
|
|||
METRICS: {
|
||||
ENABLED: config.get<boolean>('open_telemetry.metrics.enabled'),
|
||||
|
||||
PLAYBACK_STATS_INTERVAL: parseDurationToMs(config.get<string>('open_telemetry.metrics.playback_stats_interval')),
|
||||
|
||||
HTTP_REQUEST_DURATION: {
|
||||
ENABLED: config.get<boolean>('open_telemetry.metrics.http_request_duration.enabled')
|
||||
},
|
||||
|
@ -294,7 +296,11 @@ const CONFIG = {
|
|||
MAX_AGE: parseDurationToMs(config.get('views.videos.remote.max_age'))
|
||||
},
|
||||
LOCAL_BUFFER_UPDATE_INTERVAL: parseDurationToMs(config.get('views.videos.local_buffer_update_interval')),
|
||||
IP_VIEW_EXPIRATION: parseDurationToMs(config.get('views.videos.ip_view_expiration'))
|
||||
IP_VIEW_EXPIRATION: parseDurationToMs(config.get('views.videos.ip_view_expiration')),
|
||||
WATCHING_INTERVAL: {
|
||||
ANONYMOUS: parseDurationToMs(config.get<string>('views.videos.watching_interval.anonymous')),
|
||||
USERS: parseDurationToMs(config.get<string>('views.videos.watching_interval.users'))
|
||||
}
|
||||
}
|
||||
},
|
||||
GEO_IP: {
|
||||
|
|
|
@ -274,6 +274,22 @@ class ServerConfigManager {
|
|||
|
||||
homepage: {
|
||||
enabled: this.homepageEnabled
|
||||
},
|
||||
|
||||
openTelemetry: {
|
||||
metrics: {
|
||||
enabled: CONFIG.OPEN_TELEMETRY.METRICS.ENABLED,
|
||||
playbackStatsInterval: CONFIG.OPEN_TELEMETRY.METRICS.PLAYBACK_STATS_INTERVAL
|
||||
}
|
||||
},
|
||||
|
||||
views: {
|
||||
videos: {
|
||||
watchingInterval: {
|
||||
anonymous: CONFIG.VIEWS.VIDEOS.WATCHING_INTERVAL.ANONYMOUS,
|
||||
users: CONFIG.VIEWS.VIDEOS.WATCHING_INTERVAL.USERS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8126,6 +8126,36 @@ components:
|
|||
enabled:
|
||||
type: boolean
|
||||
|
||||
openTelemetry:
|
||||
type: object
|
||||
description: 'PeerTube >= 6.1'
|
||||
properties:
|
||||
metrics:
|
||||
type: object
|
||||
properties:
|
||||
enabled:
|
||||
type: boolean
|
||||
playbackStatsInterval:
|
||||
type: number
|
||||
description: 'Milliseconds'
|
||||
|
||||
views:
|
||||
type: object
|
||||
description: 'PeerTube >= 6.1'
|
||||
properties:
|
||||
views:
|
||||
type: object
|
||||
properties:
|
||||
watchingInterval:
|
||||
type: object
|
||||
properties:
|
||||
anonymous:
|
||||
type: number
|
||||
description: 'Milliseconds'
|
||||
users:
|
||||
type: number
|
||||
description: 'Milliseconds'
|
||||
|
||||
SendClientLog:
|
||||
properties:
|
||||
message:
|
||||
|
|
Loading…
Reference in a new issue