]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/initializers/constants.ts
Handle .srt subtitles
[github/Chocobozzz/PeerTube.git] / server / initializers / constants.ts
index 26ee3db47526d471d12f32d153a2812b3d4712ec..3837f7062ac2b5d092771d67f525d6a60f673592 100644 (file)
@@ -1,19 +1,20 @@
 import { IConfig } from 'config'
 import { dirname, join } from 'path'
-import { JobType, VideoRateType } from '../../shared/models'
+import { JobType, VideoRateType, VideoState } from '../../shared/models'
 import { ActivityPubActorType } from '../../shared/models/activitypub'
 import { FollowState } from '../../shared/models/actors'
 import { VideoPrivacy } from '../../shared/models/videos'
 // Do not use barrels, remain constants as independent as possible
 import { buildPath, isTestInstance, root, sanitizeHost, sanitizeUrl } from '../helpers/core-utils'
 import { NSFWPolicyType } from '../../shared/models/videos/nsfw-policy.type'
+import { invert } from 'lodash'
 
 // Use a variable to reload the configuration if we need
 let config: IConfig = require('config')
 
 // ---------------------------------------------------------------------------
 
-const LAST_MIGRATION_VERSION = 215
+const LAST_MIGRATION_VERSION = 230
 
 // ---------------------------------------------------------------------------
 
@@ -38,7 +39,7 @@ const SORTABLE_COLUMNS = {
 }
 
 const OAUTH_LIFETIME = {
-  ACCESS_TOKEN: 3600 * 4, // 4 hours
+  ACCESS_TOKEN: 3600 * 24, // 1 day, for upload
   REFRESH_TOKEN: 1209600 // 2 weeks
 }
 
@@ -74,6 +75,7 @@ const JOB_ATTEMPTS: { [ id in JobType ]: number } = {
   'activitypub-http-unicast': 5,
   'activitypub-http-fetcher': 5,
   'activitypub-follow': 5,
+  'video-file-import': 1,
   'video-file': 1,
   'email': 5
 }
@@ -82,6 +84,7 @@ const JOB_CONCURRENCY: { [ id in JobType ]: number } = {
   'activitypub-http-unicast': 5,
   'activitypub-http-fetcher': 1,
   'activitypub-follow': 3,
+  'video-file-import': 1,
   'video-file': 1,
   'email': 5
 }
@@ -91,7 +94,11 @@ const JOB_REQUEST_TTL = 60000 * 10 // 10 minutes
 const JOB_COMPLETED_LIFETIME = 60000 * 60 * 24 * 2 // 2 days
 
 // 1 hour
-let SCHEDULER_INTERVAL = 60000 * 60
+let SCHEDULER_INTERVALS_MS = {
+  badActorFollow: 60000 * 60, // 1 hour
+  removeOldJobs: 60000 * 60, // 1 hour
+  updateVideos: 60000 // 1 minute
+}
 
 // ---------------------------------------------------------------------------
 
@@ -109,10 +116,11 @@ const CONFIG = {
     PASSWORD: config.get<string>('database.password')
   },
   REDIS: {
-    HOSTNAME: config.get<string>('redis.hostname'),
-    PORT: config.get<number>('redis.port'),
-    AUTH: config.get<string>('redis.auth'),
-    DB: config.get<number>('redis.db')
+    HOSTNAME: config.has('redis.hostname') ? config.get<string>('redis.hostname') : null,
+    PORT: config.has('redis.port') ? config.get<number>('redis.port') : null,
+    SOCKET: config.has('redis.socket') ? config.get<string>('redis.socket') : null,
+    AUTH: config.has('redis.auth') ? config.get<string>('redis.auth') : null,
+    DB: config.has('redis.db') ? config.get<number>('redis.db') : null
   },
   SMTP: {
     HOSTNAME: config.get<string>('smtp.hostname'),
@@ -130,6 +138,7 @@ const CONFIG = {
     VIDEOS_DIR: buildPath(config.get<string>('storage.videos')),
     THUMBNAILS_DIR: buildPath(config.get<string>('storage.thumbnails')),
     PREVIEWS_DIR: buildPath(config.get<string>('storage.previews')),
+    CAPTIONS_DIR: buildPath(config.get<string>('storage.captions')),
     TORRENTS_DIR: buildPath(config.get<string>('storage.torrents')),
     CACHE_DIR: buildPath(config.get<string>('storage.cache'))
   },
@@ -175,6 +184,9 @@ const CONFIG = {
   CACHE: {
     PREVIEWS: {
       get SIZE () { return config.get<number>('cache.previews.size') }
+    },
+    VIDEO_CAPTIONS: {
+      get SIZE () { return config.get<number>('cache.captions.size') }
     }
   },
   INSTANCE: {
@@ -217,6 +229,14 @@ const CONSTRAINTS_FIELDS = {
     SUPPORT: { min: 3, max: 500 }, // Length
     URL: { min: 3, max: 2000 } // Length
   },
+  VIDEO_CAPTIONS: {
+    CAPTION_FILE: {
+      EXTNAME: [ '.vtt', '.srt' ],
+      FILE_SIZE: {
+        max: 2 * 1024 * 1024 // 2MB
+      }
+    }
+  },
   VIDEOS: {
     NAME: { min: 3, max: 120 }, // Length
     LANGUAGE: { min: 1, max: 10 }, // Length
@@ -275,7 +295,9 @@ const RATES_LIMIT = {
 let VIDEO_VIEW_LIFETIME = 60000 * 60 // 1 hour
 const VIDEO_TRANSCODING_FPS = {
   MIN: 10,
-  MAX: 30
+  AVERAGE: 30,
+  MAX: 60,
+  KEEP_ORIGIN_FPS_RESOLUTION_MIN: 720 // We keep the original FPS on high resolutions (720 minimum)
 }
 
 const VIDEO_RATE_TYPES: { [ id: string ]: VideoRateType } = {
@@ -323,11 +345,17 @@ const VIDEO_PRIVACIES = {
   [VideoPrivacy.PRIVATE]: 'Private'
 }
 
+const VIDEO_STATES = {
+  [VideoState.PUBLISHED]: 'Published',
+  [VideoState.TO_TRANSCODE]: 'To transcode'
+}
+
 const VIDEO_MIMETYPE_EXT = {
   'video/webm': '.webm',
   'video/ogg': '.ogv',
   'video/mp4': '.mp4'
 }
+const VIDEO_EXT_MIMETYPE = invert(VIDEO_MIMETYPE_EXT)
 
 const IMAGE_MIMETYPE_EXT = {
   'image/png': '.png',
@@ -335,6 +363,11 @@ const IMAGE_MIMETYPE_EXT = {
   'image/jpeg': '.jpg'
 }
 
+const VIDEO_CAPTIONS_MIMETYPE_EXT = {
+  'text/vtt': '.vtt',
+  'application/x-subrip': '.srt'
+}
+
 // ---------------------------------------------------------------------------
 
 const SERVER_ACTOR_NAME = 'peertube'
@@ -387,7 +420,8 @@ const STATIC_PATHS = {
   THUMBNAILS: '/static/thumbnails/',
   TORRENTS: '/static/torrents/',
   WEBSEED: '/static/webseed/',
-  AVATARS: '/static/avatars/'
+  AVATARS: '/static/avatars/',
+  VIDEO_CAPTIONS: '/static/video-captions/'
 }
 const STATIC_DOWNLOAD_PATHS = {
   TORRENTS: '/download/torrents/',
@@ -418,8 +452,13 @@ const EMBED_SIZE = {
 
 // Sub folders of cache directory
 const CACHE = {
-  DIRECTORIES: {
-    PREVIEWS: join(CONFIG.STORAGE.CACHE_DIR, 'previews')
+  PREVIEWS: {
+    DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'previews'),
+    MAX_AGE: 1000 * 3600 * 3 // 3 hours
+  },
+  VIDEO_CAPTIONS: {
+    DIRECTORY: join(CONFIG.STORAGE.CACHE_DIR, 'video-captions'),
+    MAX_AGE: 1000 * 3600 * 3 // 3 hours
   }
 }
 
@@ -437,17 +476,37 @@ const FEEDS = {
 
 // ---------------------------------------------------------------------------
 
+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
+}
+
+// ---------------------------------------------------------------------------
+
 // Special constants for a test instance
 if (isTestInstance() === true) {
   ACTOR_FOLLOW_SCORE.BASE = 20
+
   REMOTE_SCHEME.HTTP = 'http'
   REMOTE_SCHEME.WS = 'ws'
+
   STATIC_MAX_AGE = '0'
+
   ACTIVITY_PUB.COLLECTION_ITEMS_PER_PAGE = 2
   ACTIVITY_PUB.ACTOR_REFRESH_INTERVAL = 10 * 1000 // 10 seconds
+
   CONSTRAINTS_FIELDS.ACTORS.AVATAR.FILE_SIZE.max = 100 * 1024 // 100KB
-  SCHEDULER_INTERVAL = 10000
+
+  SCHEDULER_INTERVALS_MS.badActorFollow = 10000
+  SCHEDULER_INTERVALS_MS.removeOldJobs = 10000
+  SCHEDULER_INTERVALS_MS.updateVideos = 5000
+
   VIDEO_VIEW_LIFETIME = 1000 // 1 second
+
+  JOB_ATTEMPTS['email'] = 1
+
+  CACHE.VIDEO_CAPTIONS.MAX_AGE = 3000
 }
 
 updateWebserverConfig()
@@ -456,9 +515,11 @@ updateWebserverConfig()
 
 export {
   API_VERSION,
+  VIDEO_CAPTIONS_MIMETYPE_EXT,
   AVATARS_SIZE,
   ACCEPT_HEADERS,
   BCRYPT_SALT_SIZE,
+  TRACKER_RATE_LIMITS,
   CACHE,
   CONFIG,
   CONSTRAINTS_FIELDS,
@@ -489,6 +550,7 @@ export {
   VIDEO_LANGUAGES,
   VIDEO_PRIVACIES,
   VIDEO_LICENCES,
+  VIDEO_STATES,
   VIDEO_RATE_TYPES,
   VIDEO_MIMETYPE_EXT,
   VIDEO_TRANSCODING_FPS,
@@ -496,11 +558,13 @@ export {
   JOB_REQUEST_TTL,
   USER_PASSWORD_RESET_LIFETIME,
   IMAGE_MIMETYPE_EXT,
-  SCHEDULER_INTERVAL,
+  SCHEDULER_INTERVALS_MS,
   STATIC_DOWNLOAD_PATHS,
   RATES_LIMIT,
+  VIDEO_EXT_MIMETYPE,
   JOB_COMPLETED_LIFETIME,
-  VIDEO_VIEW_LIFETIME
+  VIDEO_VIEW_LIFETIME,
+  buildLanguages
 }
 
 // ---------------------------------------------------------------------------