diff options
-rw-r--r-- | server/controllers/api/videos/index.ts | 3 | ||||
-rw-r--r-- | server/helpers/ffmpeg-utils.ts | 11 | ||||
-rw-r--r-- | server/initializers/constants.ts | 2 | ||||
-rw-r--r-- | server/middlewares/validators/videos/videos.ts | 2 | ||||
-rw-r--r-- | shared/models/videos/video-transcoding-fps.model.ts | 8 | ||||
-rw-r--r-- | support/doc/api/openapi.yaml | 6 |
6 files changed, 23 insertions, 9 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 8d4ff07eb..a593f7076 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -12,7 +12,8 @@ import { | |||
12 | VIDEO_CATEGORIES, | 12 | VIDEO_CATEGORIES, |
13 | VIDEO_LANGUAGES, | 13 | VIDEO_LANGUAGES, |
14 | VIDEO_LICENCES, | 14 | VIDEO_LICENCES, |
15 | VIDEO_PRIVACIES | 15 | VIDEO_PRIVACIES, |
16 | VIDEO_TRANSCODING_FPS | ||
16 | } from '../../../initializers/constants' | 17 | } from '../../../initializers/constants' |
17 | import { | 18 | import { |
18 | changeVideoChannelShare, | 19 | changeVideoChannelShare, |
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index 00c32e99a..78f9ba07c 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts | |||
@@ -286,13 +286,16 @@ export { | |||
286 | 286 | ||
287 | async function buildx264Command (command: ffmpeg.FfmpegCommand, options: TranscodeOptions) { | 287 | async function buildx264Command (command: ffmpeg.FfmpegCommand, options: TranscodeOptions) { |
288 | let fps = await getVideoFileFPS(options.inputPath) | 288 | let fps = await getVideoFileFPS(options.inputPath) |
289 | // On small/medium resolutions, limit FPS | ||
290 | if ( | 289 | if ( |
290 | // On small/medium resolutions, limit FPS | ||
291 | options.resolution !== undefined && | 291 | options.resolution !== undefined && |
292 | options.resolution < VIDEO_TRANSCODING_FPS.KEEP_ORIGIN_FPS_RESOLUTION_MIN && | 292 | options.resolution < VIDEO_TRANSCODING_FPS.KEEP_ORIGIN_FPS_RESOLUTION_MIN && |
293 | fps > VIDEO_TRANSCODING_FPS.AVERAGE | 293 | fps > VIDEO_TRANSCODING_FPS.AVERAGE || |
294 | // If the video is doesn't match had standard | ||
295 | !VIDEO_TRANSCODING_FPS.HD_STANDARD.map(value => fps % value).includes(0) | ||
294 | ) { | 296 | ) { |
295 | fps = VIDEO_TRANSCODING_FPS.AVERAGE | 297 | // Get closest standard framerate by modulo: downsampling has to be done to a divisor of the nominal fps value |
298 | fps = VIDEO_TRANSCODING_FPS.STANDARD.sort((a, b) => fps % a - fps % b)[0] | ||
296 | } | 299 | } |
297 | 300 | ||
298 | command = await presetH264(command, options.inputPath, options.resolution, fps) | 301 | command = await presetH264(command, options.inputPath, options.resolution, fps) |
@@ -305,7 +308,7 @@ async function buildx264Command (command: ffmpeg.FfmpegCommand, options: Transco | |||
305 | 308 | ||
306 | if (fps) { | 309 | if (fps) { |
307 | // Hard FPS limits | 310 | // Hard FPS limits |
308 | if (fps > VIDEO_TRANSCODING_FPS.MAX) fps = VIDEO_TRANSCODING_FPS.MAX | 311 | if (fps > VIDEO_TRANSCODING_FPS.MAX) fps = VIDEO_TRANSCODING_FPS.HD_STANDARD.sort((a, b) => fps % a - fps % b)[0] |
309 | else if (fps < VIDEO_TRANSCODING_FPS.MIN) fps = VIDEO_TRANSCODING_FPS.MIN | 312 | else if (fps < VIDEO_TRANSCODING_FPS.MIN) fps = VIDEO_TRANSCODING_FPS.MIN |
310 | 313 | ||
311 | command = command.withFPS(fps) | 314 | command = command.withFPS(fps) |
diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index e01ab8943..64803b1db 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts | |||
@@ -310,6 +310,8 @@ let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour | |||
310 | 310 | ||
311 | const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = { | 311 | const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = { |
312 | MIN: 10, | 312 | MIN: 10, |
313 | STANDARD: [24, 25, 30], | ||
314 | HD_STANDARD: [50, 60], | ||
313 | AVERAGE: 30, | 315 | AVERAGE: 30, |
314 | MAX: 60, | 316 | MAX: 60, |
315 | KEEP_ORIGIN_FPS_RESOLUTION_MIN: 720 // We keep the original FPS on high resolutions (720 minimum) | 317 | KEEP_ORIGIN_FPS_RESOLUTION_MIN: 720 // We keep the original FPS on high resolutions (720 minimum) |
diff --git a/server/middlewares/validators/videos/videos.ts b/server/middlewares/validators/videos/videos.ts index 6733d9dec..00ee375cb 100644 --- a/server/middlewares/validators/videos/videos.ts +++ b/server/middlewares/validators/videos/videos.ts | |||
@@ -81,7 +81,7 @@ const videosAddValidator = getCommonVideoEditAttributes().concat([ | |||
81 | duration = await getDurationFromVideoFile(videoFile.path) | 81 | duration = await getDurationFromVideoFile(videoFile.path) |
82 | } catch (err) { | 82 | } catch (err) { |
83 | logger.error('Invalid input file in videosAddValidator.', { err }) | 83 | logger.error('Invalid input file in videosAddValidator.', { err }) |
84 | res.status(400) | 84 | res.status(422) |
85 | .json({ error: 'Invalid input file.' }) | 85 | .json({ error: 'Invalid input file.' }) |
86 | 86 | ||
87 | return cleanUpReqFiles(req) | 87 | return cleanUpReqFiles(req) |
diff --git a/shared/models/videos/video-transcoding-fps.model.ts b/shared/models/videos/video-transcoding-fps.model.ts index 82022d2f1..25fc1c2da 100644 --- a/shared/models/videos/video-transcoding-fps.model.ts +++ b/shared/models/videos/video-transcoding-fps.model.ts | |||
@@ -1,6 +1,8 @@ | |||
1 | export type VideoTranscodingFPS = { | 1 | export type VideoTranscodingFPS = { |
2 | MIN: number, | 2 | MIN: number |
3 | AVERAGE: number, | 3 | STANDARD: number[] |
4 | MAX: number, | 4 | HD_STANDARD: number[] |
5 | AVERAGE: number | ||
6 | MAX: number | ||
5 | KEEP_ORIGIN_FPS_RESOLUTION_MIN: number | 7 | KEEP_ORIGIN_FPS_RESOLUTION_MIN: number |
6 | } | 8 | } |
diff --git a/support/doc/api/openapi.yaml b/support/doc/api/openapi.yaml index 43718e2a1..907187e4c 100644 --- a/support/doc/api/openapi.yaml +++ b/support/doc/api/openapi.yaml | |||
@@ -977,6 +977,12 @@ paths: | |||
977 | application/json: | 977 | application/json: |
978 | schema: | 978 | schema: |
979 | $ref: '#/components/schemas/VideoUploadResponse' | 979 | $ref: '#/components/schemas/VideoUploadResponse' |
980 | '403': | ||
981 | description: 'The user video quota is exceeded with this video.' | ||
982 | '408': | ||
983 | description: 'Upload has timed out' | ||
984 | '422': | ||
985 | description: 'Invalid input file.' | ||
980 | requestBody: | 986 | requestBody: |
981 | content: | 987 | content: |
982 | multipart/form-data: | 988 | multipart/form-data: |