mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-10-05 02:39:33 +02:00
Add basic video editor support
This commit is contained in:
parent
a24bf4dc65
commit
c729caf6cc
130 changed files with 3969 additions and 1353 deletions
|
@ -1,4 +1,5 @@
|
|||
|
||||
import { UploadFilesForCheck } from 'express'
|
||||
import { CONSTRAINTS_FIELDS } from '../../initializers/constants'
|
||||
import { isFileValid } from './misc'
|
||||
|
||||
|
@ -6,8 +7,14 @@ const imageMimeTypes = CONSTRAINTS_FIELDS.ACTORS.IMAGE.EXTNAME
|
|||
.map(v => v.replace('.', ''))
|
||||
.join('|')
|
||||
const imageMimeTypesRegex = `image/(${imageMimeTypes})`
|
||||
function isActorImageFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], fieldname: string) {
|
||||
return isFileValid(files, imageMimeTypesRegex, fieldname, CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max)
|
||||
|
||||
function isActorImageFile (files: UploadFilesForCheck, fieldname: string) {
|
||||
return isFileValid({
|
||||
files,
|
||||
mimeTypeRegex: imageMimeTypesRegex,
|
||||
field: fieldname,
|
||||
maxSize: CONSTRAINTS_FIELDS.ACTORS.IMAGE.FILE_SIZE.max
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -61,75 +61,43 @@ function isIntOrNull (value: any) {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function isFileFieldValid (
|
||||
files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
|
||||
field: string,
|
||||
optional = false
|
||||
) {
|
||||
function isFileValid (options: {
|
||||
files: UploadFilesForCheck
|
||||
|
||||
maxSize: number | null
|
||||
mimeTypeRegex: string | null
|
||||
|
||||
field?: string
|
||||
|
||||
optional?: boolean // Default false
|
||||
}) {
|
||||
const { files, mimeTypeRegex, field, maxSize, optional = false } = options
|
||||
|
||||
// Should have files
|
||||
if (!files) return optional
|
||||
if (isArray(files)) return optional
|
||||
|
||||
// Should have a file
|
||||
const fileArray = files[field]
|
||||
if (!fileArray || fileArray.length === 0) {
|
||||
const fileArray = isArray(files)
|
||||
? files
|
||||
: files[field]
|
||||
|
||||
if (!fileArray || !isArray(fileArray) || fileArray.length === 0) {
|
||||
return optional
|
||||
}
|
||||
|
||||
// The file should exist
|
||||
const file = fileArray[0]
|
||||
if (!file || !file.originalname) return false
|
||||
return file
|
||||
}
|
||||
|
||||
function isFileMimeTypeValid (
|
||||
files: UploadFilesForCheck,
|
||||
mimeTypeRegex: string,
|
||||
field: string,
|
||||
optional = false
|
||||
) {
|
||||
// Should have files
|
||||
if (!files) return optional
|
||||
if (isArray(files)) return optional
|
||||
|
||||
// Should have a file
|
||||
const fileArray = files[field]
|
||||
if (!fileArray || fileArray.length === 0) {
|
||||
return optional
|
||||
}
|
||||
|
||||
// The file should exist
|
||||
const file = fileArray[0]
|
||||
if (!file || !file.originalname) return false
|
||||
|
||||
return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype)
|
||||
}
|
||||
|
||||
function isFileValid (
|
||||
files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[],
|
||||
mimeTypeRegex: string,
|
||||
field: string,
|
||||
maxSize: number | null,
|
||||
optional = false
|
||||
) {
|
||||
// Should have files
|
||||
if (!files) return optional
|
||||
if (isArray(files)) return optional
|
||||
|
||||
// Should have a file
|
||||
const fileArray = files[field]
|
||||
if (!fileArray || fileArray.length === 0) {
|
||||
return optional
|
||||
}
|
||||
|
||||
// The file should exist
|
||||
// The file exists
|
||||
const file = fileArray[0]
|
||||
if (!file || !file.originalname) return false
|
||||
|
||||
// Check size
|
||||
if ((maxSize !== null) && file.size > maxSize) return false
|
||||
|
||||
return new RegExp(`^${mimeTypeRegex}$`, 'i').test(file.mimetype)
|
||||
if (mimeTypeRegex === null) return true
|
||||
|
||||
return checkMimetypeRegex(file.mimetype, mimeTypeRegex)
|
||||
}
|
||||
|
||||
function checkMimetypeRegex (fileMimeType: string, mimeTypeRegex: string) {
|
||||
return new RegExp(`^${mimeTypeRegex}$`, 'i').test(fileMimeType)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
@ -204,7 +172,6 @@ export {
|
|||
areUUIDsValid,
|
||||
toArray,
|
||||
toIntArray,
|
||||
isFileFieldValid,
|
||||
isFileMimeTypeValid,
|
||||
isFileValid
|
||||
isFileValid,
|
||||
checkMimetypeRegex
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { getFileSize } from '@shared/extra-utils'
|
||||
import { UploadFilesForCheck } from 'express'
|
||||
import { readFile } from 'fs-extra'
|
||||
import { getFileSize } from '@shared/extra-utils'
|
||||
import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_LANGUAGES } from '../../initializers/constants'
|
||||
import { exists, isFileValid } from './misc'
|
||||
|
||||
|
@ -11,8 +12,13 @@ const videoCaptionTypesRegex = Object.keys(MIMETYPES.VIDEO_CAPTIONS.MIMETYPE_EXT
|
|||
.concat([ 'application/octet-stream' ]) // MacOS sends application/octet-stream
|
||||
.map(m => `(${m})`)
|
||||
.join('|')
|
||||
function isVideoCaptionFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
|
||||
return isFileValid(files, videoCaptionTypesRegex, field, CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.FILE_SIZE.max)
|
||||
function isVideoCaptionFile (files: UploadFilesForCheck, field: string) {
|
||||
return isFileValid({
|
||||
files,
|
||||
mimeTypeRegex: videoCaptionTypesRegex,
|
||||
field,
|
||||
maxSize: CONSTRAINTS_FIELDS.VIDEO_CAPTIONS.CAPTION_FILE.FILE_SIZE.max
|
||||
})
|
||||
}
|
||||
|
||||
async function isVTTFileValid (filePath: string) {
|
||||
|
|
52
server/helpers/custom-validators/video-editor.ts
Normal file
52
server/helpers/custom-validators/video-editor.ts
Normal file
|
@ -0,0 +1,52 @@
|
|||
import validator from 'validator'
|
||||
import { CONSTRAINTS_FIELDS } from '@server/initializers/constants'
|
||||
import { buildTaskFileFieldname } from '@server/lib/video-editor'
|
||||
import { VideoEditorTask } from '@shared/models'
|
||||
import { isArray } from './misc'
|
||||
import { isVideoFileMimeTypeValid, isVideoImageValid } from './videos'
|
||||
|
||||
function isValidEditorTasksArray (tasks: any) {
|
||||
if (!isArray(tasks)) return false
|
||||
|
||||
return tasks.length >= CONSTRAINTS_FIELDS.VIDEO_EDITOR.TASKS.min &&
|
||||
tasks.length <= CONSTRAINTS_FIELDS.VIDEO_EDITOR.TASKS.max
|
||||
}
|
||||
|
||||
function isEditorCutTaskValid (task: VideoEditorTask) {
|
||||
if (task.name !== 'cut') return false
|
||||
if (!task.options) return false
|
||||
|
||||
const { start, end } = task.options
|
||||
if (!start && !end) return false
|
||||
|
||||
if (start && !validator.isInt(start + '', CONSTRAINTS_FIELDS.VIDEO_EDITOR.CUT_TIME)) return false
|
||||
if (end && !validator.isInt(end + '', CONSTRAINTS_FIELDS.VIDEO_EDITOR.CUT_TIME)) return false
|
||||
|
||||
if (!start || !end) return true
|
||||
|
||||
return parseInt(start + '') < parseInt(end + '')
|
||||
}
|
||||
|
||||
function isEditorTaskAddIntroOutroValid (task: VideoEditorTask, indice: number, files: Express.Multer.File[]) {
|
||||
const file = files.find(f => f.fieldname === buildTaskFileFieldname(indice, 'file'))
|
||||
|
||||
return (task.name === 'add-intro' || task.name === 'add-outro') &&
|
||||
file && isVideoFileMimeTypeValid([ file ], null)
|
||||
}
|
||||
|
||||
function isEditorTaskAddWatermarkValid (task: VideoEditorTask, indice: number, files: Express.Multer.File[]) {
|
||||
const file = files.find(f => f.fieldname === buildTaskFileFieldname(indice, 'file'))
|
||||
|
||||
return task.name === 'add-watermark' &&
|
||||
file && isVideoImageValid([ file ], null, true)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export {
|
||||
isValidEditorTasksArray,
|
||||
|
||||
isEditorCutTaskValid,
|
||||
isEditorTaskAddIntroOutroValid,
|
||||
isEditorTaskAddWatermarkValid
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import 'multer'
|
||||
import { UploadFilesForCheck } from 'express'
|
||||
import validator from 'validator'
|
||||
import { CONSTRAINTS_FIELDS, MIMETYPES, VIDEO_IMPORT_STATES } from '../../initializers/constants'
|
||||
import { exists, isFileValid } from './misc'
|
||||
|
@ -25,8 +26,14 @@ const videoTorrentImportRegex = Object.keys(MIMETYPES.TORRENT.MIMETYPE_EXT)
|
|||
.concat([ 'application/octet-stream' ]) // MacOS sends application/octet-stream
|
||||
.map(m => `(${m})`)
|
||||
.join('|')
|
||||
function isVideoImportTorrentFile (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[]) {
|
||||
return isFileValid(files, videoTorrentImportRegex, 'torrentfile', CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max, true)
|
||||
function isVideoImportTorrentFile (files: UploadFilesForCheck) {
|
||||
return isFileValid({
|
||||
files,
|
||||
mimeTypeRegex: videoTorrentImportRegex,
|
||||
field: 'torrentfile',
|
||||
maxSize: CONSTRAINTS_FIELDS.VIDEO_IMPORTS.TORRENT_FILE.FILE_SIZE.max,
|
||||
optional: true
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -13,7 +13,7 @@ import {
|
|||
VIDEO_RATE_TYPES,
|
||||
VIDEO_STATES
|
||||
} from '../../initializers/constants'
|
||||
import { exists, isArray, isDateValid, isFileMimeTypeValid, isFileValid } from './misc'
|
||||
import { exists, isArray, isDateValid, isFileValid } from './misc'
|
||||
|
||||
const VIDEOS_CONSTRAINTS_FIELDS = CONSTRAINTS_FIELDS.VIDEOS
|
||||
|
||||
|
@ -66,7 +66,7 @@ function isVideoTagValid (tag: string) {
|
|||
return exists(tag) && validator.isLength(tag, VIDEOS_CONSTRAINTS_FIELDS.TAG)
|
||||
}
|
||||
|
||||
function isVideoTagsValid (tags: string[]) {
|
||||
function areVideoTagsValid (tags: string[]) {
|
||||
return tags === null || (
|
||||
isArray(tags) &&
|
||||
validator.isInt(tags.length.toString(), VIDEOS_CONSTRAINTS_FIELDS.TAGS) &&
|
||||
|
@ -86,8 +86,13 @@ function isVideoFileExtnameValid (value: string) {
|
|||
return exists(value) && (value === VIDEO_LIVE.EXTENSION || MIMETYPES.VIDEO.EXT_MIMETYPE[value] !== undefined)
|
||||
}
|
||||
|
||||
function isVideoFileMimeTypeValid (files: UploadFilesForCheck) {
|
||||
return isFileMimeTypeValid(files, MIMETYPES.VIDEO.MIMETYPES_REGEX, 'videofile')
|
||||
function isVideoFileMimeTypeValid (files: UploadFilesForCheck, field = 'videofile') {
|
||||
return isFileValid({
|
||||
files,
|
||||
mimeTypeRegex: MIMETYPES.VIDEO.MIMETYPES_REGEX,
|
||||
field,
|
||||
maxSize: null
|
||||
})
|
||||
}
|
||||
|
||||
const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
|
||||
|
@ -95,8 +100,14 @@ const videoImageTypes = CONSTRAINTS_FIELDS.VIDEOS.IMAGE.EXTNAME
|
|||
.join('|')
|
||||
const videoImageTypesRegex = `image/(${videoImageTypes})`
|
||||
|
||||
function isVideoImage (files: { [ fieldname: string ]: Express.Multer.File[] } | Express.Multer.File[], field: string) {
|
||||
return isFileValid(files, videoImageTypesRegex, field, CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max, true)
|
||||
function isVideoImageValid (files: UploadFilesForCheck, field: string, optional = true) {
|
||||
return isFileValid({
|
||||
files,
|
||||
mimeTypeRegex: videoImageTypesRegex,
|
||||
field,
|
||||
maxSize: CONSTRAINTS_FIELDS.VIDEOS.IMAGE.FILE_SIZE.max,
|
||||
optional
|
||||
})
|
||||
}
|
||||
|
||||
function isVideoPrivacyValid (value: number) {
|
||||
|
@ -144,7 +155,7 @@ export {
|
|||
isVideoDescriptionValid,
|
||||
isVideoFileInfoHashValid,
|
||||
isVideoNameValid,
|
||||
isVideoTagsValid,
|
||||
areVideoTagsValid,
|
||||
isVideoFPSResolutionValid,
|
||||
isScheduleVideoUpdatePrivacyValid,
|
||||
isVideoOriginallyPublishedAtValid,
|
||||
|
@ -160,7 +171,7 @@ export {
|
|||
isVideoPrivacyValid,
|
||||
isVideoFileResolutionValid,
|
||||
isVideoFileSizeValid,
|
||||
isVideoImage,
|
||||
isVideoImageValid,
|
||||
isVideoSupportValid,
|
||||
isVideoFilterValid
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue