]>
Commit | Line | Data |
---|---|---|
6a490560 | 1 | import Bluebird from 'bluebird' |
c729caf6 | 2 | import express from 'express' |
6a490560 | 3 | import { move } from 'fs-extra' |
5e47f6ab | 4 | import { basename } from 'path' |
c729caf6 | 5 | import { createAnyReqFiles } from '@server/helpers/express-utils' |
5e47f6ab C |
6 | import { MIMETYPES, VIDEO_FILTERS } from '@server/initializers/constants' |
7 | import { buildTaskFileFieldname, createVideoStudioJob, getStudioTaskFilePath, getTaskFileFromReq } from '@server/lib/video-studio' | |
c729caf6 C |
8 | import { |
9 | HttpStatusCode, | |
92e66e04 C |
10 | VideoState, |
11 | VideoStudioCreateEdition, | |
12 | VideoStudioTask, | |
13 | VideoStudioTaskCut, | |
14 | VideoStudioTaskIntro, | |
15 | VideoStudioTaskOutro, | |
16 | VideoStudioTaskPayload, | |
17 | VideoStudioTaskWatermark | |
c729caf6 | 18 | } from '@shared/models' |
92e66e04 | 19 | import { asyncMiddleware, authenticate, videoStudioAddEditionValidator } from '../../../middlewares' |
c729caf6 | 20 | |
92e66e04 | 21 | const studioRouter = express.Router() |
c729caf6 C |
22 | |
23 | const tasksFiles = createAnyReqFiles( | |
24 | MIMETYPES.VIDEO.MIMETYPE_EXT, | |
c729caf6 | 25 | (req: express.Request, file: Express.Multer.File, cb: (err: Error, result?: boolean) => void) => { |
92e66e04 | 26 | const body = req.body as VideoStudioCreateEdition |
c729caf6 C |
27 | |
28 | // Fetch array element | |
29 | const matches = file.fieldname.match(/tasks\[(\d+)\]/) | |
30 | if (!matches) return cb(new Error('Cannot find array element indice for ' + file.fieldname)) | |
31 | ||
32 | const indice = parseInt(matches[1]) | |
33 | const task = body.tasks[indice] | |
34 | ||
35 | if (!task) return cb(new Error('Cannot find array element of indice ' + indice + ' for ' + file.fieldname)) | |
36 | ||
37 | if ( | |
38 | [ 'add-intro', 'add-outro', 'add-watermark' ].includes(task.name) && | |
39 | file.fieldname === buildTaskFileFieldname(indice) | |
40 | ) { | |
41 | return cb(null, true) | |
42 | } | |
43 | ||
44 | return cb(null, false) | |
45 | } | |
46 | ) | |
47 | ||
92e66e04 | 48 | studioRouter.post('/:videoId/studio/edit', |
c729caf6 C |
49 | authenticate, |
50 | tasksFiles, | |
92e66e04 | 51 | asyncMiddleware(videoStudioAddEditionValidator), |
c729caf6 C |
52 | asyncMiddleware(createEditionTasks) |
53 | ) | |
54 | ||
55 | // --------------------------------------------------------------------------- | |
56 | ||
57 | export { | |
92e66e04 | 58 | studioRouter |
c729caf6 C |
59 | } |
60 | ||
61 | // --------------------------------------------------------------------------- | |
62 | ||
63 | async function createEditionTasks (req: express.Request, res: express.Response) { | |
64 | const files = req.files as Express.Multer.File[] | |
92e66e04 | 65 | const body = req.body as VideoStudioCreateEdition |
c729caf6 C |
66 | const video = res.locals.videoAll |
67 | ||
68 | video.state = VideoState.TO_EDIT | |
69 | await video.save() | |
70 | ||
71 | const payload = { | |
72 | videoUUID: video.uuid, | |
6a490560 | 73 | tasks: await Bluebird.mapSeries(body.tasks, (t, i) => buildTaskPayload(t, i, files)) |
c729caf6 C |
74 | } |
75 | ||
5e47f6ab C |
76 | await createVideoStudioJob({ |
77 | user: res.locals.oauth.token.User, | |
78 | payload, | |
79 | video | |
80 | }) | |
c729caf6 C |
81 | |
82 | return res.sendStatus(HttpStatusCode.NO_CONTENT_204) | |
83 | } | |
84 | ||
85 | const taskPayloadBuilders: { | |
6a490560 C |
86 | [id in VideoStudioTask['name']]: ( |
87 | task: VideoStudioTask, | |
88 | indice?: number, | |
89 | files?: Express.Multer.File[] | |
90 | ) => Promise<VideoStudioTaskPayload> | |
c729caf6 C |
91 | } = { |
92 | 'add-intro': buildIntroOutroTask, | |
93 | 'add-outro': buildIntroOutroTask, | |
94 | 'cut': buildCutTask, | |
95 | 'add-watermark': buildWatermarkTask | |
96 | } | |
97 | ||
6a490560 | 98 | function buildTaskPayload (task: VideoStudioTask, indice: number, files: Express.Multer.File[]): Promise<VideoStudioTaskPayload> { |
c729caf6 C |
99 | return taskPayloadBuilders[task.name](task, indice, files) |
100 | } | |
101 | ||
6a490560 C |
102 | async function buildIntroOutroTask (task: VideoStudioTaskIntro | VideoStudioTaskOutro, indice: number, files: Express.Multer.File[]) { |
103 | const destination = await moveStudioFileToPersistentTMP(getTaskFileFromReq(files, indice).path) | |
104 | ||
c729caf6 C |
105 | return { |
106 | name: task.name, | |
107 | options: { | |
6a490560 | 108 | file: destination |
c729caf6 C |
109 | } |
110 | } | |
111 | } | |
112 | ||
92e66e04 | 113 | function buildCutTask (task: VideoStudioTaskCut) { |
6a490560 | 114 | return Promise.resolve({ |
c729caf6 C |
115 | name: task.name, |
116 | options: { | |
117 | start: task.options.start, | |
118 | end: task.options.end | |
119 | } | |
6a490560 | 120 | }) |
c729caf6 C |
121 | } |
122 | ||
6a490560 C |
123 | async function buildWatermarkTask (task: VideoStudioTaskWatermark, indice: number, files: Express.Multer.File[]) { |
124 | const destination = await moveStudioFileToPersistentTMP(getTaskFileFromReq(files, indice).path) | |
125 | ||
c729caf6 C |
126 | return { |
127 | name: task.name, | |
128 | options: { | |
5e47f6ab C |
129 | file: destination, |
130 | watermarkSizeRatio: VIDEO_FILTERS.WATERMARK.SIZE_RATIO, | |
131 | horitonzalMarginRatio: VIDEO_FILTERS.WATERMARK.HORIZONTAL_MARGIN_RATIO, | |
132 | verticalMarginRatio: VIDEO_FILTERS.WATERMARK.VERTICAL_MARGIN_RATIO | |
c729caf6 C |
133 | } |
134 | } | |
135 | } | |
6a490560 C |
136 | |
137 | async function moveStudioFileToPersistentTMP (file: string) { | |
5e47f6ab | 138 | const destination = getStudioTaskFilePath(basename(file)) |
6a490560 C |
139 | |
140 | await move(file, destination) | |
141 | ||
142 | return destination | |
143 | } |