mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-03 01:39:37 +02:00
Support max FPS configuration
This commit is contained in:
parent
0bd2474fed
commit
bbaf96d60d
37 changed files with 736 additions and 623 deletions
|
@ -31,8 +31,7 @@ import {
|
|||
VideoRateType,
|
||||
VideoResolution,
|
||||
VideoState,
|
||||
VideoStateType,
|
||||
VideoTranscodingFPS
|
||||
VideoStateType
|
||||
} from '@peertube/peertube-models'
|
||||
import { isTestInstance, isTestOrDevInstance, root } from '@peertube/peertube-node-utils'
|
||||
import { RepeatOptions } from 'bullmq'
|
||||
|
@ -41,20 +40,20 @@ import { readJsonSync } from 'fs-extra/esm'
|
|||
import invert from 'lodash-es/invert.js'
|
||||
import { join } from 'path'
|
||||
// Do not use barrels, remain constants as independent as possible
|
||||
import { cpus } from 'os'
|
||||
import { parseDurationToMs, sanitizeHost, sanitizeUrl } from '../helpers/core-utils.js'
|
||||
import { CONFIG, registerConfigChangedHandler } from './config.js'
|
||||
import { cpus } from 'os'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const LAST_MIGRATION_VERSION = 865
|
||||
export const LAST_MIGRATION_VERSION = 865
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const API_VERSION = 'v1'
|
||||
const PEERTUBE_VERSION: string = readJsonSync(join(root(), 'package.json')).version
|
||||
export const API_VERSION = 'v1'
|
||||
export const PEERTUBE_VERSION: string = readJsonSync(join(root(), 'package.json')).version
|
||||
|
||||
const PAGINATION = {
|
||||
export const PAGINATION = {
|
||||
GLOBAL: {
|
||||
COUNT: {
|
||||
DEFAULT: 15,
|
||||
|
@ -68,7 +67,7 @@ const PAGINATION = {
|
|||
}
|
||||
}
|
||||
|
||||
const WEBSERVER = {
|
||||
export const WEBSERVER = {
|
||||
URL: '',
|
||||
HOST: '',
|
||||
SCHEME: '',
|
||||
|
@ -84,7 +83,7 @@ const WEBSERVER = {
|
|||
}
|
||||
|
||||
// Sortable columns per schema
|
||||
const SORTABLE_COLUMNS = {
|
||||
export const SORTABLE_COLUMNS = {
|
||||
ADMIN_USERS: [ 'id', 'username', 'videoQuotaUsed', 'createdAt', 'lastLoginDate', 'role' ],
|
||||
USER_SUBSCRIPTIONS: [ 'id', 'createdAt' ],
|
||||
ACCOUNTS: [ 'createdAt' ],
|
||||
|
@ -149,7 +148,7 @@ const SORTABLE_COLUMNS = {
|
|||
VIDEO_REDUNDANCIES: [ 'name' ]
|
||||
}
|
||||
|
||||
const ROUTE_CACHE_LIFETIME = {
|
||||
export const ROUTE_CACHE_LIFETIME = {
|
||||
FEEDS: '15 minutes',
|
||||
ROBOTS: '2 hours',
|
||||
SITEMAP: '1 day',
|
||||
|
@ -166,27 +165,27 @@ const ROUTE_CACHE_LIFETIME = {
|
|||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Number of points we add/remove after a successful/bad request
|
||||
const ACTOR_FOLLOW_SCORE = {
|
||||
export const ACTOR_FOLLOW_SCORE = {
|
||||
PENALTY: -10,
|
||||
BONUS: 10,
|
||||
BASE: 1000,
|
||||
MAX: 10000
|
||||
}
|
||||
|
||||
const FOLLOW_STATES: { [ id: string ]: FollowState } = {
|
||||
export const FOLLOW_STATES: { [ id: string ]: FollowState } = {
|
||||
PENDING: 'pending',
|
||||
ACCEPTED: 'accepted',
|
||||
REJECTED: 'rejected'
|
||||
}
|
||||
|
||||
const REMOTE_SCHEME = {
|
||||
export const REMOTE_SCHEME = {
|
||||
HTTP: 'https',
|
||||
WS: 'wss'
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const JOB_ATTEMPTS: { [id in JobType]: number } = {
|
||||
export const JOB_ATTEMPTS: { [id in JobType]: number } = {
|
||||
'activitypub-http-broadcast': 1,
|
||||
'activitypub-http-broadcast-parallel': 1,
|
||||
'activitypub-http-unicast': 1,
|
||||
|
@ -217,7 +216,7 @@ const JOB_ATTEMPTS: { [id in JobType]: number } = {
|
|||
'video-transcription': 2
|
||||
}
|
||||
// Excluded keys are jobs that can be configured by admins
|
||||
const JOB_CONCURRENCY: { [id in Exclude<JobType, 'video-transcoding' | 'video-import'>]: number } = {
|
||||
export const JOB_CONCURRENCY: { [id in Exclude<JobType, 'video-transcoding' | 'video-import'>]: number } = {
|
||||
'activitypub-http-broadcast': 1,
|
||||
'activitypub-http-broadcast-parallel': 30,
|
||||
'activitypub-http-unicast': 30,
|
||||
|
@ -245,7 +244,7 @@ const JOB_CONCURRENCY: { [id in Exclude<JobType, 'video-transcoding' | 'video-im
|
|||
'import-user-archive': 1,
|
||||
'video-transcription': 1
|
||||
}
|
||||
const JOB_TTL: { [id in JobType]: number } = {
|
||||
export const JOB_TTL: { [id in JobType]: number } = {
|
||||
'activitypub-http-broadcast': 60000 * 10, // 10 minutes
|
||||
'activitypub-http-broadcast-parallel': 60000 * 10, // 10 minutes
|
||||
'activitypub-http-unicast': 60000 * 10, // 10 minutes
|
||||
|
@ -275,7 +274,7 @@ const JOB_TTL: { [id in JobType]: number } = {
|
|||
'import-user-archive': 60000 * 60 * 24, // 24 hours
|
||||
'video-transcription': 1000 * 3600 * 6 // 6 hours
|
||||
}
|
||||
const REPEAT_JOBS: { [ id in JobType ]?: RepeatOptions } = {
|
||||
export const REPEAT_JOBS: { [ id in JobType ]?: RepeatOptions } = {
|
||||
'videos-views-stats': {
|
||||
pattern: randomInt(1, 20) + ' * * * *' // Between 1-20 minutes past the hour
|
||||
},
|
||||
|
@ -283,13 +282,13 @@ const REPEAT_JOBS: { [ id in JobType ]?: RepeatOptions } = {
|
|||
pattern: '30 5 * * ' + randomInt(0, 7) // 1 time per week (random day) at 5:30 AM
|
||||
}
|
||||
}
|
||||
const JOB_PRIORITY = {
|
||||
export const JOB_PRIORITY = {
|
||||
TRANSCODING: 100,
|
||||
VIDEO_STUDIO: 150,
|
||||
TRANSCRIPTION: 200
|
||||
}
|
||||
|
||||
const JOB_REMOVAL_OPTIONS = {
|
||||
export const JOB_REMOVAL_OPTIONS = {
|
||||
COUNT: 10000, // Max jobs to store
|
||||
|
||||
SUCCESS: { // Success jobs
|
||||
|
@ -306,32 +305,32 @@ const JOB_REMOVAL_OPTIONS = {
|
|||
}
|
||||
}
|
||||
|
||||
const VIDEO_IMPORT_TIMEOUT = Math.floor(JOB_TTL['video-import'] * 0.9)
|
||||
export const VIDEO_IMPORT_TIMEOUT = Math.floor(JOB_TTL['video-import'] * 0.9)
|
||||
|
||||
const RUNNER_JOBS = {
|
||||
export const RUNNER_JOBS = {
|
||||
MAX_FAILURES: 5,
|
||||
LAST_CONTACT_UPDATE_INTERVAL: 30000
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const BROADCAST_CONCURRENCY = 30 // How many requests in parallel we do in activitypub-http-broadcast job
|
||||
const CRAWL_REQUEST_CONCURRENCY = 1 // How many requests in parallel to fetch remote data (likes, shares...)
|
||||
export const BROADCAST_CONCURRENCY = 30 // How many requests in parallel we do in activitypub-http-broadcast job
|
||||
export const CRAWL_REQUEST_CONCURRENCY = 1 // How many requests in parallel to fetch remote data (likes, shares...)
|
||||
|
||||
const AP_CLEANER = {
|
||||
export const AP_CLEANER = {
|
||||
CONCURRENCY: 10, // How many requests in parallel we do in activitypub-cleaner job
|
||||
UNAVAILABLE_TRESHOLD: 3, // How many attempts we do before removing an unavailable remote resource
|
||||
PERIOD: parseDurationToMs('1 week') // /!\ Has to be sync with REPEAT_JOBS
|
||||
}
|
||||
|
||||
const REQUEST_TIMEOUTS = {
|
||||
export const REQUEST_TIMEOUTS = {
|
||||
DEFAULT: 7000, // 7 seconds
|
||||
FILE: 30000, // 30 seconds
|
||||
VIDEO_FILE: 60000, // 1 minute
|
||||
REDUNDANCY: JOB_TTL['video-redundancy']
|
||||
}
|
||||
|
||||
const SCHEDULER_INTERVALS_MS = {
|
||||
export const SCHEDULER_INTERVALS_MS = {
|
||||
RUNNER_JOB_WATCH_DOG: Math.min(CONFIG.REMOTE_RUNNERS.STALLED_JOBS.VOD, CONFIG.REMOTE_RUNNERS.STALLED_JOBS.LIVE),
|
||||
ACTOR_FOLLOW_SCORES: 60000 * 60, // 1 hour
|
||||
REMOVE_OLD_JOBS: 60000 * 60, // 1 hour
|
||||
|
@ -352,7 +351,7 @@ const SCHEDULER_INTERVALS_MS = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const CONSTRAINTS_FIELDS = {
|
||||
export const CONSTRAINTS_FIELDS = {
|
||||
USERS: {
|
||||
NAME: { min: 1, max: 120 }, // Length
|
||||
DESCRIPTION: { min: 3, max: 1000 }, // Length
|
||||
|
@ -515,40 +514,30 @@ const CONSTRAINTS_FIELDS = {
|
|||
}
|
||||
}
|
||||
|
||||
const VIEW_LIFETIME = {
|
||||
export const VIEW_LIFETIME = {
|
||||
VIEW: CONFIG.VIEWS.VIDEOS.VIEW_EXPIRATION,
|
||||
VIEWER_COUNTER: 60000 * 2, // 2 minutes
|
||||
VIEWER_STATS: 60000 * 60 // 1 hour
|
||||
}
|
||||
let VIEWER_SYNC_REDIS = 30000 // Sync viewer into redis
|
||||
export let VIEWER_SYNC_REDIS = 30000 // Sync viewer into redis
|
||||
|
||||
const MAX_LOCAL_VIEWER_WATCH_SECTIONS = 100
|
||||
export const MAX_LOCAL_VIEWER_WATCH_SECTIONS = 100
|
||||
|
||||
let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour
|
||||
export let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour
|
||||
|
||||
const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = {
|
||||
HARD_MIN: 0.1,
|
||||
SOFT_MIN: 1,
|
||||
STANDARD: [ 24, 25, 30 ],
|
||||
HD_STANDARD: [ 50, 60 ],
|
||||
AUDIO_MERGE: 25,
|
||||
AVERAGE: 30,
|
||||
SOFT_MAX: 60,
|
||||
KEEP_ORIGIN_FPS_RESOLUTION_MIN: 720 // We keep the original FPS on high resolutions (720 minimum)
|
||||
}
|
||||
export const DEFAULT_AUDIO_RESOLUTION = VideoResolution.H_480P
|
||||
export const DEFAULT_AUDIO_MERGE_RESOLUTION = 25
|
||||
|
||||
const DEFAULT_AUDIO_RESOLUTION = VideoResolution.H_480P
|
||||
|
||||
const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = {
|
||||
export const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = {
|
||||
LIKE: 'like',
|
||||
DISLIKE: 'dislike'
|
||||
}
|
||||
|
||||
const USER_IMPORT = {
|
||||
export const USER_IMPORT = {
|
||||
MAX_PLAYLIST_ELEMENTS: 1000
|
||||
}
|
||||
|
||||
const FFMPEG_NICE = {
|
||||
export const FFMPEG_NICE = {
|
||||
// parent process defaults to niceness = 0
|
||||
// reminder: lower = higher priority, max value is 19, lowest is -20
|
||||
LIVE: 5, // prioritize over VOD and THUMBNAIL
|
||||
|
@ -556,7 +545,7 @@ const FFMPEG_NICE = {
|
|||
VOD: 15
|
||||
}
|
||||
|
||||
const VIDEO_CATEGORIES = {
|
||||
export const VIDEO_CATEGORIES = {
|
||||
1: 'Music',
|
||||
2: 'Films',
|
||||
3: 'Vehicles',
|
||||
|
@ -578,7 +567,7 @@ const VIDEO_CATEGORIES = {
|
|||
}
|
||||
|
||||
// See https://creativecommons.org/licenses/?lang=en
|
||||
const VIDEO_LICENCES = {
|
||||
export const VIDEO_LICENCES = {
|
||||
1: 'Attribution',
|
||||
2: 'Attribution - Share Alike',
|
||||
3: 'Attribution - No Derivatives',
|
||||
|
@ -588,9 +577,9 @@ const VIDEO_LICENCES = {
|
|||
7: 'Public Domain Dedication'
|
||||
}
|
||||
|
||||
const VIDEO_LANGUAGES: { [id: string]: string } = {}
|
||||
export const VIDEO_LANGUAGES: { [id: string]: string } = {}
|
||||
|
||||
const VIDEO_PRIVACIES: { [ id in VideoPrivacyType ]: string } = {
|
||||
export const VIDEO_PRIVACIES: { [ id in VideoPrivacyType ]: string } = {
|
||||
[VideoPrivacy.PUBLIC]: 'Public',
|
||||
[VideoPrivacy.UNLISTED]: 'Unlisted',
|
||||
[VideoPrivacy.PRIVATE]: 'Private',
|
||||
|
@ -598,7 +587,7 @@ const VIDEO_PRIVACIES: { [ id in VideoPrivacyType ]: string } = {
|
|||
[VideoPrivacy.PASSWORD_PROTECTED]: 'Password protected'
|
||||
}
|
||||
|
||||
const VIDEO_STATES: { [ id in VideoStateType ]: string } = {
|
||||
export const VIDEO_STATES: { [ id in VideoStateType ]: string } = {
|
||||
[VideoState.PUBLISHED]: 'Published',
|
||||
[VideoState.TO_TRANSCODE]: 'To transcode',
|
||||
[VideoState.TO_IMPORT]: 'To import',
|
||||
|
@ -612,7 +601,7 @@ const VIDEO_STATES: { [ id in VideoStateType ]: string } = {
|
|||
[VideoState.TO_MOVE_TO_FILE_SYSTEM_FAILED]: 'Move to file system failed'
|
||||
}
|
||||
|
||||
const VIDEO_IMPORT_STATES: { [ id in VideoImportStateType ]: string } = {
|
||||
export const VIDEO_IMPORT_STATES: { [ id in VideoImportStateType ]: string } = {
|
||||
[VideoImportState.FAILED]: 'Failed',
|
||||
[VideoImportState.PENDING]: 'Pending',
|
||||
[VideoImportState.SUCCESS]: 'Success',
|
||||
|
@ -621,37 +610,37 @@ const VIDEO_IMPORT_STATES: { [ id in VideoImportStateType ]: string } = {
|
|||
[VideoImportState.PROCESSING]: 'Processing'
|
||||
}
|
||||
|
||||
const VIDEO_CHANNEL_SYNC_STATE: { [ id in VideoChannelSyncStateType ]: string } = {
|
||||
export const VIDEO_CHANNEL_SYNC_STATE: { [ id in VideoChannelSyncStateType ]: string } = {
|
||||
[VideoChannelSyncState.FAILED]: 'Failed',
|
||||
[VideoChannelSyncState.SYNCED]: 'Synchronized',
|
||||
[VideoChannelSyncState.PROCESSING]: 'Processing',
|
||||
[VideoChannelSyncState.WAITING_FIRST_RUN]: 'Waiting first run'
|
||||
}
|
||||
|
||||
const ABUSE_STATES: { [ id in AbuseStateType ]: string } = {
|
||||
export const ABUSE_STATES: { [ id in AbuseStateType ]: string } = {
|
||||
[AbuseState.PENDING]: 'Pending',
|
||||
[AbuseState.REJECTED]: 'Rejected',
|
||||
[AbuseState.ACCEPTED]: 'Accepted'
|
||||
}
|
||||
|
||||
const USER_REGISTRATION_STATES: { [ id in UserRegistrationStateType ]: string } = {
|
||||
export const USER_REGISTRATION_STATES: { [ id in UserRegistrationStateType ]: string } = {
|
||||
[UserRegistrationState.PENDING]: 'Pending',
|
||||
[UserRegistrationState.REJECTED]: 'Rejected',
|
||||
[UserRegistrationState.ACCEPTED]: 'Accepted'
|
||||
}
|
||||
|
||||
const VIDEO_PLAYLIST_PRIVACIES: { [ id in VideoPlaylistPrivacyType ]: string } = {
|
||||
export const VIDEO_PLAYLIST_PRIVACIES: { [ id in VideoPlaylistPrivacyType ]: string } = {
|
||||
[VideoPlaylistPrivacy.PUBLIC]: 'Public',
|
||||
[VideoPlaylistPrivacy.UNLISTED]: 'Unlisted',
|
||||
[VideoPlaylistPrivacy.PRIVATE]: 'Private'
|
||||
}
|
||||
|
||||
const VIDEO_PLAYLIST_TYPES: { [ id in VideoPlaylistType_Type ]: string } = {
|
||||
export const VIDEO_PLAYLIST_TYPES: { [ id in VideoPlaylistType_Type ]: string } = {
|
||||
[VideoPlaylistType.REGULAR]: 'Regular',
|
||||
[VideoPlaylistType.WATCH_LATER]: 'Watch later'
|
||||
}
|
||||
|
||||
const RUNNER_JOB_STATES: { [ id in RunnerJobStateType ]: string } = {
|
||||
export const RUNNER_JOB_STATES: { [ id in RunnerJobStateType ]: string } = {
|
||||
[RunnerJobState.PROCESSING]: 'Processing',
|
||||
[RunnerJobState.COMPLETED]: 'Completed',
|
||||
[RunnerJobState.COMPLETING]: 'Completing',
|
||||
|
@ -663,27 +652,27 @@ const RUNNER_JOB_STATES: { [ id in RunnerJobStateType ]: string } = {
|
|||
[RunnerJobState.PARENT_CANCELLED]: 'Parent job cancelled'
|
||||
}
|
||||
|
||||
const USER_EXPORT_STATES: { [ id in UserExportStateType ]: string } = {
|
||||
export const USER_EXPORT_STATES: { [ id in UserExportStateType ]: string } = {
|
||||
[UserExportState.PENDING]: 'Pending',
|
||||
[UserExportState.PROCESSING]: 'Processing',
|
||||
[UserExportState.COMPLETED]: 'Completed',
|
||||
[UserExportState.ERRORED]: 'Failed'
|
||||
}
|
||||
|
||||
const USER_IMPORT_STATES: { [ id in UserImportStateType ]: string } = {
|
||||
export const USER_IMPORT_STATES: { [ id in UserImportStateType ]: string } = {
|
||||
[UserImportState.PENDING]: 'Pending',
|
||||
[UserImportState.PROCESSING]: 'Processing',
|
||||
[UserImportState.COMPLETED]: 'Completed',
|
||||
[UserImportState.ERRORED]: 'Failed'
|
||||
}
|
||||
|
||||
const VIDEO_COMMENTS_POLICY: { [ id in VideoCommentPolicyType ]: string } = {
|
||||
export const VIDEO_COMMENTS_POLICY: { [ id in VideoCommentPolicyType ]: string } = {
|
||||
[VideoCommentPolicy.DISABLED]: 'Disabled',
|
||||
[VideoCommentPolicy.ENABLED]: 'Enabled',
|
||||
[VideoCommentPolicy.REQUIRES_APPROVAL]: 'Requires approval'
|
||||
}
|
||||
|
||||
const MIMETYPES = {
|
||||
export const MIMETYPES = {
|
||||
AUDIO: {
|
||||
MIMETYPE_EXT: {
|
||||
'audio/mpeg': '.mp3',
|
||||
|
@ -769,7 +758,7 @@ MIMETYPES.AUDIO.EXT_MIMETYPE = invert(MIMETYPES.AUDIO.MIMETYPE_EXT)
|
|||
MIMETYPES.IMAGE.EXT_MIMETYPE = invert(MIMETYPES.IMAGE.MIMETYPE_EXT)
|
||||
MIMETYPES.VIDEO_CAPTIONS.EXT_MIMETYPE = invert(MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT)
|
||||
|
||||
const BINARY_CONTENT_TYPES = new Set([
|
||||
export const BINARY_CONTENT_TYPES = new Set([
|
||||
'binary/octet-stream',
|
||||
'application/octet-stream',
|
||||
'application/x-binary'
|
||||
|
@ -777,7 +766,7 @@ const BINARY_CONTENT_TYPES = new Set([
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const OVERVIEWS = {
|
||||
export const OVERVIEWS = {
|
||||
VIDEOS: {
|
||||
SAMPLE_THRESHOLD: 6,
|
||||
SAMPLES_COUNT: 20
|
||||
|
@ -786,9 +775,9 @@ const OVERVIEWS = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const SERVER_ACTOR_NAME = 'peertube'
|
||||
export const SERVER_ACTOR_NAME = 'peertube'
|
||||
|
||||
const ACTIVITY_PUB = {
|
||||
export const ACTIVITY_PUB = {
|
||||
POTENTIAL_ACCEPT_HEADERS: [
|
||||
'application/activity+json',
|
||||
'application/ld+json',
|
||||
|
@ -803,7 +792,7 @@ const ACTIVITY_PUB = {
|
|||
VIDEO_PLAYLIST_REFRESH_INTERVAL: 3600 * 24 * 1000 * 2 // 2 days
|
||||
}
|
||||
|
||||
const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = {
|
||||
export const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = {
|
||||
GROUP: 'Group',
|
||||
PERSON: 'Person',
|
||||
APPLICATION: 'Application',
|
||||
|
@ -811,7 +800,7 @@ const ACTIVITY_PUB_ACTOR_TYPES: { [ id: string ]: ActivityPubActorType } = {
|
|||
SERVICE: 'Service'
|
||||
}
|
||||
|
||||
const HTTP_SIGNATURE = {
|
||||
export const HTTP_SIGNATURE = {
|
||||
HEADER_NAME: 'signature',
|
||||
ALGORITHM: 'rsa-sha256',
|
||||
HEADERS_TO_SIGN_WITH_PAYLOAD: [ '(request-target)', 'host', 'date', 'digest' ],
|
||||
|
@ -821,27 +810,27 @@ const HTTP_SIGNATURE = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
let PRIVATE_RSA_KEY_SIZE = 2048
|
||||
export let PRIVATE_RSA_KEY_SIZE = 2048
|
||||
|
||||
// Password encryption
|
||||
const BCRYPT_SALT_SIZE = 10
|
||||
export const BCRYPT_SALT_SIZE = 10
|
||||
|
||||
const ENCRYPTION = {
|
||||
export const ENCRYPTION = {
|
||||
ALGORITHM: 'aes-256-cbc',
|
||||
IV: 16,
|
||||
SALT: 'peertube',
|
||||
ENCODING: 'hex' as Encoding
|
||||
}
|
||||
|
||||
const USER_PASSWORD_RESET_LIFETIME = 60000 * 60 // 60 minutes
|
||||
const USER_PASSWORD_CREATE_LIFETIME = 60000 * 60 * 24 * 7 // 7 days
|
||||
export const USER_PASSWORD_RESET_LIFETIME = 60000 * 60 // 60 minutes
|
||||
export const USER_PASSWORD_CREATE_LIFETIME = 60000 * 60 * 24 * 7 // 7 days
|
||||
|
||||
const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes
|
||||
let JWT_TOKEN_USER_EXPORT_FILE_LIFETIME = '15 minutes'
|
||||
export const TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME = 60000 * 10 // 10 minutes
|
||||
export let JWT_TOKEN_USER_EXPORT_FILE_LIFETIME = '15 minutes'
|
||||
|
||||
const EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes
|
||||
export const EMAIL_VERIFY_LIFETIME = 60000 * 60 // 60 minutes
|
||||
|
||||
const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = {
|
||||
export const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = {
|
||||
DO_NOT_LIST: 'do_not_list',
|
||||
BLUR: 'blur',
|
||||
DISPLAY: 'display'
|
||||
|
@ -849,13 +838,13 @@ const NSFW_POLICY_TYPES: { [ id: string ]: NSFWPolicyType } = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const USER_EXPORT_MAX_ITEMS = 1000
|
||||
const USER_EXPORT_FILE_PREFIX = 'user-export-'
|
||||
export const USER_EXPORT_MAX_ITEMS = 1000
|
||||
export const USER_EXPORT_FILE_PREFIX = 'user-export-'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
// Express static paths (router)
|
||||
const STATIC_PATHS = {
|
||||
export const STATIC_PATHS = {
|
||||
// TODO: deprecated in v6, to remove
|
||||
THUMBNAILS: '/static/thumbnails/',
|
||||
|
||||
|
@ -874,7 +863,7 @@ const STATIC_PATHS = {
|
|||
PRIVATE_HLS: '/static/streaming-playlists/hls/private/'
|
||||
}
|
||||
}
|
||||
const DOWNLOAD_PATHS = {
|
||||
export const DOWNLOAD_PATHS = {
|
||||
TORRENTS: '/download/torrents/',
|
||||
GENERATE_VIDEO: '/download/videos/generate/',
|
||||
WEB_VIDEOS: '/download/web-videos/',
|
||||
|
@ -882,7 +871,7 @@ const DOWNLOAD_PATHS = {
|
|||
USER_EXPORTS: '/download/user-exports/',
|
||||
ORIGINAL_VIDEO_FILE: '/download/original-video-files/'
|
||||
}
|
||||
const LAZY_STATIC_PATHS = {
|
||||
export const LAZY_STATIC_PATHS = {
|
||||
THUMBNAILS: '/lazy-static/thumbnails/',
|
||||
BANNERS: '/lazy-static/banners/',
|
||||
AVATARS: '/lazy-static/avatars/',
|
||||
|
@ -891,7 +880,7 @@ const LAZY_STATIC_PATHS = {
|
|||
TORRENTS: '/lazy-static/torrents/',
|
||||
STORYBOARDS: '/lazy-static/storyboards/'
|
||||
}
|
||||
const OBJECT_STORAGE_PROXY_PATHS = {
|
||||
export const OBJECT_STORAGE_PROXY_PATHS = {
|
||||
// Need to keep this legacy path for previously generated torrents
|
||||
LEGACY_PRIVATE_WEB_VIDEOS: '/object-storage-proxy/webseed/private/',
|
||||
PRIVATE_WEB_VIDEOS: '/object-storage-proxy/web-videos/private/',
|
||||
|
@ -902,24 +891,24 @@ const OBJECT_STORAGE_PROXY_PATHS = {
|
|||
}
|
||||
|
||||
// Cache control
|
||||
const STATIC_MAX_AGE = {
|
||||
export const STATIC_MAX_AGE = {
|
||||
SERVER: '2h',
|
||||
LAZY_SERVER: '2d',
|
||||
CLIENT: '30d'
|
||||
}
|
||||
|
||||
// Videos thumbnail size
|
||||
const THUMBNAILS_SIZE = {
|
||||
export const THUMBNAILS_SIZE = {
|
||||
width: minBy(CONFIG.THUMBNAILS.SIZES, 'width').width,
|
||||
height: minBy(CONFIG.THUMBNAILS.SIZES, 'width').height,
|
||||
minRemoteWidth: 150
|
||||
}
|
||||
const PREVIEWS_SIZE = {
|
||||
export const PREVIEWS_SIZE = {
|
||||
width: maxBy(CONFIG.THUMBNAILS.SIZES, 'width').width,
|
||||
height: maxBy(CONFIG.THUMBNAILS.SIZES, 'width').height,
|
||||
minRemoteWidth: 400
|
||||
}
|
||||
const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height: number }[] } = {
|
||||
export const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height: number }[] } = {
|
||||
[ActorImageType.AVATAR]: [ // 1/1 ratio
|
||||
{
|
||||
width: 1500,
|
||||
|
@ -950,18 +939,18 @@ const ACTOR_IMAGES_SIZE: { [key in ActorImageType_Type]: { width: number, height
|
|||
]
|
||||
}
|
||||
|
||||
const STORYBOARD = {
|
||||
export const STORYBOARD = {
|
||||
SPRITE_MAX_SIZE: 192,
|
||||
SPRITES_MAX_EDGE_COUNT: 10
|
||||
}
|
||||
|
||||
const EMBED_SIZE = {
|
||||
export const EMBED_SIZE = {
|
||||
width: 560,
|
||||
height: 315
|
||||
}
|
||||
|
||||
// Sub folders of cache directory
|
||||
const FILES_CACHE = {
|
||||
export const FILES_CACHE = {
|
||||
PREVIEWS: {
|
||||
DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'previews'),
|
||||
MAX_AGE: 1000 * 3600 * 3 // 3 hours
|
||||
|
@ -980,7 +969,7 @@ const FILES_CACHE = {
|
|||
}
|
||||
}
|
||||
|
||||
const LRU_CACHE = {
|
||||
export const LRU_CACHE = {
|
||||
USER_TOKENS: {
|
||||
MAX_SIZE: 1000
|
||||
},
|
||||
|
@ -1004,7 +993,7 @@ const LRU_CACHE = {
|
|||
}
|
||||
}
|
||||
|
||||
const DIRECTORIES = {
|
||||
export const DIRECTORIES = {
|
||||
RESUMABLE_UPLOAD: join(CONFIG.STORAGE.TMP_DIR, 'resumable-uploads'),
|
||||
|
||||
HLS_STREAMING_PLAYLIST: {
|
||||
|
@ -1024,9 +1013,9 @@ const DIRECTORIES = {
|
|||
LOCAL_PIP_DIRECTORY: join(CONFIG.STORAGE.BIN_DIR, 'pip')
|
||||
}
|
||||
|
||||
const RESUMABLE_UPLOAD_SESSION_LIFETIME = SCHEDULER_INTERVALS_MS.REMOVE_DANGLING_RESUMABLE_UPLOADS
|
||||
export const RESUMABLE_UPLOAD_SESSION_LIFETIME = SCHEDULER_INTERVALS_MS.REMOVE_DANGLING_RESUMABLE_UPLOADS
|
||||
|
||||
const VIDEO_LIVE = {
|
||||
export const VIDEO_LIVE = {
|
||||
EXTENSION: '.ts',
|
||||
CLEANUP_DELAY: 1000 * 60 * 5, // 5 minutes
|
||||
SEGMENT_TIME_SECONDS: {
|
||||
|
@ -1046,7 +1035,7 @@ const VIDEO_LIVE = {
|
|||
}
|
||||
}
|
||||
|
||||
const MEMOIZE_TTL = {
|
||||
export const MEMOIZE_TTL = {
|
||||
OVERVIEWS_SAMPLE: 1000 * 3600 * 4, // 4 hours
|
||||
INFO_HASH_EXISTS: 1000 * 60, // 1 minute
|
||||
VIDEO_DURATION: 1000 * 10, // 10 seconds
|
||||
|
@ -1056,14 +1045,14 @@ const MEMOIZE_TTL = {
|
|||
EMBED_HTML: 1000 * 10 // 10 seconds
|
||||
}
|
||||
|
||||
const MEMOIZE_LENGTH = {
|
||||
export const MEMOIZE_LENGTH = {
|
||||
INFO_HASH_EXISTS: 200,
|
||||
VIDEO_DURATION: 200
|
||||
}
|
||||
|
||||
const totalCPUs = Math.max(cpus().length, 1)
|
||||
export const totalCPUs = Math.max(cpus().length, 1)
|
||||
|
||||
const WORKER_THREADS = {
|
||||
export const WORKER_THREADS = {
|
||||
DOWNLOAD_IMAGE: {
|
||||
CONCURRENCY: 3,
|
||||
MAX_THREADS: 1
|
||||
|
@ -1086,26 +1075,26 @@ const WORKER_THREADS = {
|
|||
}
|
||||
}
|
||||
|
||||
const REDUNDANCY = {
|
||||
export const REDUNDANCY = {
|
||||
VIDEOS: {
|
||||
RANDOMIZED_FACTOR: 5
|
||||
}
|
||||
}
|
||||
|
||||
const ACCEPT_HEADERS = [ 'html', 'application/json' ].concat(ACTIVITY_PUB.POTENTIAL_ACCEPT_HEADERS)
|
||||
const OTP = {
|
||||
export const ACCEPT_HEADERS = [ 'html', 'application/json' ].concat(ACTIVITY_PUB.POTENTIAL_ACCEPT_HEADERS)
|
||||
export const OTP = {
|
||||
HEADER_NAME: 'x-peertube-otp',
|
||||
HEADER_REQUIRED_VALUE: 'required; app'
|
||||
}
|
||||
|
||||
const ASSETS_PATH = {
|
||||
export const ASSETS_PATH = {
|
||||
DEFAULT_AUDIO_BACKGROUND: join(root(), 'dist', 'core', 'assets', 'default-audio-background.jpg'),
|
||||
DEFAULT_LIVE_BACKGROUND: join(root(), 'dist', 'core', 'assets', 'default-live-background.jpg')
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const CUSTOM_HTML_TAG_COMMENTS = {
|
||||
export const CUSTOM_HTML_TAG_COMMENTS = {
|
||||
TITLE: '<!-- title tag -->',
|
||||
DESCRIPTION: '<!-- description tag -->',
|
||||
CUSTOM_CSS: '<!-- custom css tag -->',
|
||||
|
@ -1113,34 +1102,34 @@ const CUSTOM_HTML_TAG_COMMENTS = {
|
|||
SERVER_CONFIG: '<!-- server config -->'
|
||||
}
|
||||
|
||||
const MAX_LOGS_OUTPUT_CHARACTERS = 10 * 1000 * 1000
|
||||
const LOG_FILENAME = 'peertube.log'
|
||||
const AUDIT_LOG_FILENAME = 'peertube-audit.log'
|
||||
export const MAX_LOGS_OUTPUT_CHARACTERS = 10 * 1000 * 1000
|
||||
export const LOG_FILENAME = 'peertube.log'
|
||||
export const AUDIT_LOG_FILENAME = 'peertube-audit.log'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const TRACKER_RATE_LIMITS = {
|
||||
export const TRACKER_RATE_LIMITS = {
|
||||
INTERVAL: 60000 * 5, // 5 minutes
|
||||
ANNOUNCES_PER_IP_PER_INFOHASH: 15, // maximum announces per torrent in the interval
|
||||
ANNOUNCES_PER_IP: 30, // maximum announces for all our torrents in the interval
|
||||
BLOCK_IP_LIFETIME: parseDurationToMs('3 minutes')
|
||||
}
|
||||
|
||||
const P2P_MEDIA_LOADER_PEER_VERSION = 2
|
||||
export const P2P_MEDIA_LOADER_PEER_VERSION = 2
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const PLUGIN_GLOBAL_CSS_FILE_NAME = 'plugins-global.css'
|
||||
const PLUGIN_GLOBAL_CSS_PATH = join(CONFIG.STORAGE.TMP_DIR, PLUGIN_GLOBAL_CSS_FILE_NAME)
|
||||
export const PLUGIN_GLOBAL_CSS_FILE_NAME = 'plugins-global.css'
|
||||
export const PLUGIN_GLOBAL_CSS_PATH = join(CONFIG.STORAGE.TMP_DIR, PLUGIN_GLOBAL_CSS_FILE_NAME)
|
||||
|
||||
let PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME = 1000 * 60 * 5 // 5 minutes
|
||||
export let PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME = 1000 * 60 * 5 // 5 minutes
|
||||
|
||||
const DEFAULT_THEME_NAME = 'default'
|
||||
const DEFAULT_USER_THEME_NAME = 'instance-default'
|
||||
export const DEFAULT_THEME_NAME = 'default'
|
||||
export const DEFAULT_USER_THEME_NAME = 'instance-default'
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const SEARCH_INDEX = {
|
||||
export const SEARCH_INDEX = {
|
||||
ROUTES: {
|
||||
VIDEOS: '/api/v1/search/videos',
|
||||
VIDEO_CHANNELS: '/api/v1/search/video-channels'
|
||||
|
@ -1149,7 +1138,7 @@ const SEARCH_INDEX = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const STATS_TIMESERIE = {
|
||||
export const STATS_TIMESERIE = {
|
||||
MAX_DAYS: 365 * 10 // Around 10 years
|
||||
}
|
||||
|
||||
|
@ -1231,9 +1220,15 @@ registerConfigChangedHandler(() => {
|
|||
updateWebserverConfig()
|
||||
})
|
||||
|
||||
export async function loadLanguages () {
|
||||
if (Object.keys(VIDEO_LANGUAGES).length !== 0) return
|
||||
|
||||
Object.assign(VIDEO_LANGUAGES, await buildLanguages())
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const FILES_CONTENT_HASH = {
|
||||
export const FILES_CONTENT_HASH = {
|
||||
MANIFEST: generateContentHash(),
|
||||
FAVICON: generateContentHash(),
|
||||
LOGO: generateContentHash()
|
||||
|
@ -1241,7 +1236,7 @@ const FILES_CONTENT_HASH = {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const VIDEO_FILTERS = {
|
||||
export const VIDEO_FILTERS = {
|
||||
WATERMARK: {
|
||||
SIZE_RATIO: 1 / 10,
|
||||
HORIZONTAL_MARGIN_RATIO: 1 / 20,
|
||||
|
@ -1250,116 +1245,7 @@ const VIDEO_FILTERS = {
|
|||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
WEBSERVER,
|
||||
API_VERSION,
|
||||
ENCRYPTION,
|
||||
VIDEO_LIVE,
|
||||
PEERTUBE_VERSION,
|
||||
LAZY_STATIC_PATHS,
|
||||
OBJECT_STORAGE_PROXY_PATHS,
|
||||
SEARCH_INDEX,
|
||||
DIRECTORIES,
|
||||
RESUMABLE_UPLOAD_SESSION_LIFETIME,
|
||||
RUNNER_JOB_STATES,
|
||||
USER_EXPORT_STATES,
|
||||
USER_IMPORT_STATES,
|
||||
P2P_MEDIA_LOADER_PEER_VERSION,
|
||||
STORYBOARD,
|
||||
ACTOR_IMAGES_SIZE,
|
||||
ACCEPT_HEADERS,
|
||||
BCRYPT_SALT_SIZE,
|
||||
TRACKER_RATE_LIMITS,
|
||||
VIDEO_COMMENTS_POLICY,
|
||||
FILES_CACHE,
|
||||
LOG_FILENAME,
|
||||
CONSTRAINTS_FIELDS,
|
||||
EMBED_SIZE,
|
||||
REDUNDANCY,
|
||||
USER_EXPORT_FILE_PREFIX,
|
||||
JOB_CONCURRENCY,
|
||||
JOB_ATTEMPTS,
|
||||
AP_CLEANER,
|
||||
LAST_MIGRATION_VERSION,
|
||||
CUSTOM_HTML_TAG_COMMENTS,
|
||||
STATS_TIMESERIE,
|
||||
BROADCAST_CONCURRENCY,
|
||||
AUDIT_LOG_FILENAME,
|
||||
USER_IMPORT,
|
||||
PAGINATION,
|
||||
ACTOR_FOLLOW_SCORE,
|
||||
PREVIEWS_SIZE,
|
||||
REMOTE_SCHEME,
|
||||
FOLLOW_STATES,
|
||||
DEFAULT_USER_THEME_NAME,
|
||||
SERVER_ACTOR_NAME,
|
||||
TWO_FACTOR_AUTH_REQUEST_TOKEN_LIFETIME,
|
||||
JWT_TOKEN_USER_EXPORT_FILE_LIFETIME,
|
||||
PLUGIN_GLOBAL_CSS_FILE_NAME,
|
||||
PLUGIN_GLOBAL_CSS_PATH,
|
||||
PRIVATE_RSA_KEY_SIZE,
|
||||
VIDEO_FILTERS,
|
||||
ROUTE_CACHE_LIFETIME,
|
||||
SORTABLE_COLUMNS,
|
||||
JOB_TTL,
|
||||
DEFAULT_THEME_NAME,
|
||||
NSFW_POLICY_TYPES,
|
||||
STATIC_MAX_AGE,
|
||||
VIEWER_SYNC_REDIS,
|
||||
STATIC_PATHS,
|
||||
USER_EXPORT_MAX_ITEMS,
|
||||
VIDEO_IMPORT_TIMEOUT,
|
||||
VIDEO_PLAYLIST_TYPES,
|
||||
MAX_LOGS_OUTPUT_CHARACTERS,
|
||||
ACTIVITY_PUB,
|
||||
ACTIVITY_PUB_ACTOR_TYPES,
|
||||
THUMBNAILS_SIZE,
|
||||
VIDEO_CATEGORIES,
|
||||
MEMOIZE_LENGTH,
|
||||
VIDEO_LANGUAGES,
|
||||
VIDEO_PRIVACIES,
|
||||
VIDEO_LICENCES,
|
||||
VIDEO_STATES,
|
||||
WORKER_THREADS,
|
||||
VIDEO_RATE_TYPES,
|
||||
JOB_PRIORITY,
|
||||
VIDEO_TRANSCODING_FPS,
|
||||
FFMPEG_NICE,
|
||||
ABUSE_STATES,
|
||||
USER_REGISTRATION_STATES,
|
||||
LRU_CACHE,
|
||||
REQUEST_TIMEOUTS,
|
||||
RUNNER_JOBS,
|
||||
MAX_LOCAL_VIEWER_WATCH_SECTIONS,
|
||||
USER_PASSWORD_RESET_LIFETIME,
|
||||
USER_PASSWORD_CREATE_LIFETIME,
|
||||
MEMOIZE_TTL,
|
||||
EMAIL_VERIFY_LIFETIME,
|
||||
OVERVIEWS,
|
||||
SCHEDULER_INTERVALS_MS,
|
||||
REPEAT_JOBS,
|
||||
DOWNLOAD_PATHS,
|
||||
MIMETYPES,
|
||||
CRAWL_REQUEST_CONCURRENCY,
|
||||
DEFAULT_AUDIO_RESOLUTION,
|
||||
BINARY_CONTENT_TYPES,
|
||||
JOB_REMOVAL_OPTIONS,
|
||||
HTTP_SIGNATURE,
|
||||
VIDEO_IMPORT_STATES,
|
||||
VIDEO_CHANNEL_SYNC_STATE,
|
||||
VIEW_LIFETIME,
|
||||
CONTACT_FORM_LIFETIME,
|
||||
VIDEO_PLAYLIST_PRIVACIES,
|
||||
PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME,
|
||||
ASSETS_PATH,
|
||||
FILES_CONTENT_HASH,
|
||||
OTP,
|
||||
loadLanguages,
|
||||
buildLanguages,
|
||||
generateContentHash
|
||||
}
|
||||
|
||||
// Private
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function buildVideoMimetypeExt () {
|
||||
|
@ -1480,12 +1366,6 @@ function buildMimetypesRegex (obj: { [id: string]: string | string[] }) {
|
|||
.join('|')
|
||||
}
|
||||
|
||||
async function loadLanguages () {
|
||||
if (Object.keys(VIDEO_LANGUAGES).length !== 0) return
|
||||
|
||||
Object.assign(VIDEO_LANGUAGES, await buildLanguages())
|
||||
}
|
||||
|
||||
async function buildLanguages () {
|
||||
const { iso6393 } = await import('iso-639-3')
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue