Downsample to the closest divisor standard framerate

This commit is contained in:
Rigel Kent 2020-01-14 23:34:03 +01:00 committed by Chocobozzz
parent 0539dba824
commit 06bcfbd9f7
6 changed files with 23 additions and 9 deletions

View File

@ -12,7 +12,8 @@ import {
VIDEO_CATEGORIES, VIDEO_CATEGORIES,
VIDEO_LANGUAGES, VIDEO_LANGUAGES,
VIDEO_LICENCES, VIDEO_LICENCES,
VIDEO_PRIVACIES VIDEO_PRIVACIES,
VIDEO_TRANSCODING_FPS
} from '../../../initializers/constants' } from '../../../initializers/constants'
import { import {
changeVideoChannelShare, changeVideoChannelShare,

View File

@ -286,13 +286,16 @@ export {
async function buildx264Command (command: ffmpeg.FfmpegCommand, options: TranscodeOptions) { async function buildx264Command (command: ffmpeg.FfmpegCommand, options: TranscodeOptions) {
let fps = await getVideoFileFPS(options.inputPath) let fps = await getVideoFileFPS(options.inputPath)
// On small/medium resolutions, limit FPS
if ( if (
// On small/medium resolutions, limit FPS
options.resolution !== undefined && options.resolution !== undefined &&
options.resolution < VIDEO_TRANSCODING_FPS.KEEP_ORIGIN_FPS_RESOLUTION_MIN && options.resolution < VIDEO_TRANSCODING_FPS.KEEP_ORIGIN_FPS_RESOLUTION_MIN &&
fps > VIDEO_TRANSCODING_FPS.AVERAGE fps > VIDEO_TRANSCODING_FPS.AVERAGE ||
// If the video is doesn't match had standard
!VIDEO_TRANSCODING_FPS.HD_STANDARD.map(value => fps % value).includes(0)
) { ) {
fps = VIDEO_TRANSCODING_FPS.AVERAGE // Get closest standard framerate by modulo: downsampling has to be done to a divisor of the nominal fps value
fps = VIDEO_TRANSCODING_FPS.STANDARD.sort((a, b) => fps % a - fps % b)[0]
} }
command = await presetH264(command, options.inputPath, options.resolution, fps) command = await presetH264(command, options.inputPath, options.resolution, fps)
@ -305,7 +308,7 @@ async function buildx264Command (command: ffmpeg.FfmpegCommand, options: Transco
if (fps) { if (fps) {
// Hard FPS limits // Hard FPS limits
if (fps > VIDEO_TRANSCODING_FPS.MAX) fps = VIDEO_TRANSCODING_FPS.MAX if (fps > VIDEO_TRANSCODING_FPS.MAX) fps = VIDEO_TRANSCODING_FPS.HD_STANDARD.sort((a, b) => fps % a - fps % b)[0]
else if (fps < VIDEO_TRANSCODING_FPS.MIN) fps = VIDEO_TRANSCODING_FPS.MIN else if (fps < VIDEO_TRANSCODING_FPS.MIN) fps = VIDEO_TRANSCODING_FPS.MIN
command = command.withFPS(fps) command = command.withFPS(fps)

View File

@ -310,6 +310,8 @@ let CONTACT_FORM_LIFETIME = 60000 * 60 // 1 hour
const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = { const VIDEO_TRANSCODING_FPS: VideoTranscodingFPS = {
MIN: 10, MIN: 10,
STANDARD: [24, 25, 30],
HD_STANDARD: [50, 60],
AVERAGE: 30, AVERAGE: 30,
MAX: 60, MAX: 60,
KEEP_ORIGIN_FPS_RESOLUTION_MIN: 720 // We keep the original FPS on high resolutions (720 minimum) KEEP_ORIGIN_FPS_RESOLUTION_MIN: 720 // We keep the original FPS on high resolutions (720 minimum)

View File

@ -81,7 +81,7 @@ const videosAddValidator = getCommonVideoEditAttributes().concat([
duration = await getDurationFromVideoFile(videoFile.path) duration = await getDurationFromVideoFile(videoFile.path)
} catch (err) { } catch (err) {
logger.error('Invalid input file in videosAddValidator.', { err }) logger.error('Invalid input file in videosAddValidator.', { err })
res.status(400) res.status(422)
.json({ error: 'Invalid input file.' }) .json({ error: 'Invalid input file.' })
return cleanUpReqFiles(req) return cleanUpReqFiles(req)

View File

@ -1,6 +1,8 @@
export type VideoTranscodingFPS = { export type VideoTranscodingFPS = {
MIN: number, MIN: number
AVERAGE: number, STANDARD: number[]
MAX: number, HD_STANDARD: number[]
AVERAGE: number
MAX: number
KEEP_ORIGIN_FPS_RESOLUTION_MIN: number KEEP_ORIGIN_FPS_RESOLUTION_MIN: number
} }

View File

@ -977,6 +977,12 @@ paths:
application/json: application/json:
schema: schema:
$ref: '#/components/schemas/VideoUploadResponse' $ref: '#/components/schemas/VideoUploadResponse'
'403':
description: 'The user video quota is exceeded with this video.'
'408':
description: 'Upload has timed out'
'422':
description: 'Invalid input file.'
requestBody: requestBody:
content: content:
multipart/form-data: multipart/form-data: