aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api/videos/studio.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-07-31 14:34:36 +0200
committerChocobozzz <me@florianbigard.com>2023-08-11 15:02:33 +0200
commit3a4992633ee62d5edfbb484d9c6bcb3cf158489d (patch)
treee4510b39bdac9c318fdb4b47018d08f15368b8f0 /server/controllers/api/videos/studio.ts
parent04d1da5621d25d59bd5fa1543b725c497bf5d9a8 (diff)
downloadPeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.gz
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.tar.zst
PeerTube-3a4992633ee62d5edfbb484d9c6bcb3cf158489d.zip
Migrate server to ESM
Sorry for the very big commit that may lead to git log issues and merge conflicts, but it's a major step forward: * Server can be faster at startup because imports() are async and we can easily lazy import big modules * Angular doesn't seem to support ES import (with .js extension), so we had to correctly organize peertube into a monorepo: * Use yarn workspace feature * Use typescript reference projects for dependencies * Shared projects have been moved into "packages", each one is now a node module (with a dedicated package.json/tsconfig.json) * server/tools have been moved into apps/ and is now a dedicated app bundled and published on NPM so users don't have to build peertube cli tools manually * server/tests have been moved into packages/ so we don't compile them every time we want to run the server * Use isolatedModule option: * Had to move from const enum to const (https://www.typescriptlang.org/docs/handbook/enums.html#objects-vs-enums) * Had to explictely specify "type" imports when used in decorators * Prefer tsx (that uses esbuild under the hood) instead of ts-node to load typescript files (tests with mocha or scripts): * To reduce test complexity as esbuild doesn't support decorator metadata, we only test server files that do not import server models * We still build tests files into js files for a faster CI * Remove unmaintained peertube CLI import script * Removed some barrels to speed up execution (less imports)
Diffstat (limited to 'server/controllers/api/videos/studio.ts')
-rw-r--r--server/controllers/api/videos/studio.ts143
1 files changed, 0 insertions, 143 deletions
diff --git a/server/controllers/api/videos/studio.ts b/server/controllers/api/videos/studio.ts
deleted file mode 100644
index 7c31dfd2b..000000000
--- a/server/controllers/api/videos/studio.ts
+++ /dev/null
@@ -1,143 +0,0 @@
1import Bluebird from 'bluebird'
2import express from 'express'
3import { move } from 'fs-extra'
4import { basename } from 'path'
5import { createAnyReqFiles } from '@server/helpers/express-utils'
6import { MIMETYPES, VIDEO_FILTERS } from '@server/initializers/constants'
7import { buildTaskFileFieldname, createVideoStudioJob, getStudioTaskFilePath, getTaskFileFromReq } from '@server/lib/video-studio'
8import {
9 HttpStatusCode,
10 VideoState,
11 VideoStudioCreateEdition,
12 VideoStudioTask,
13 VideoStudioTaskCut,
14 VideoStudioTaskIntro,
15 VideoStudioTaskOutro,
16 VideoStudioTaskPayload,
17 VideoStudioTaskWatermark
18} from '@shared/models'
19import { asyncMiddleware, authenticate, videoStudioAddEditionValidator } from '../../../middlewares'
20
21const studioRouter = express.Router()
22
23const tasksFiles = createAnyReqFiles(
24 MIMETYPES.VIDEO.MIMETYPE_EXT,
25 (req: express.Request, file: Express.Multer.File, cb: (err: Error, result?: boolean) => void) => {
26 const body = req.body as VideoStudioCreateEdition
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
48studioRouter.post('/:videoId/studio/edit',
49 authenticate,
50 tasksFiles,
51 asyncMiddleware(videoStudioAddEditionValidator),
52 asyncMiddleware(createEditionTasks)
53)
54
55// ---------------------------------------------------------------------------
56
57export {
58 studioRouter
59}
60
61// ---------------------------------------------------------------------------
62
63async function createEditionTasks (req: express.Request, res: express.Response) {
64 const files = req.files as Express.Multer.File[]
65 const body = req.body as VideoStudioCreateEdition
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,
73 tasks: await Bluebird.mapSeries(body.tasks, (t, i) => buildTaskPayload(t, i, files))
74 }
75
76 await createVideoStudioJob({
77 user: res.locals.oauth.token.User,
78 payload,
79 video
80 })
81
82 return res.sendStatus(HttpStatusCode.NO_CONTENT_204)
83}
84
85const taskPayloadBuilders: {
86 [id in VideoStudioTask['name']]: (
87 task: VideoStudioTask,
88 indice?: number,
89 files?: Express.Multer.File[]
90 ) => Promise<VideoStudioTaskPayload>
91} = {
92 'add-intro': buildIntroOutroTask,
93 'add-outro': buildIntroOutroTask,
94 'cut': buildCutTask,
95 'add-watermark': buildWatermarkTask
96}
97
98function buildTaskPayload (task: VideoStudioTask, indice: number, files: Express.Multer.File[]): Promise<VideoStudioTaskPayload> {
99 return taskPayloadBuilders[task.name](task, indice, files)
100}
101
102async function buildIntroOutroTask (task: VideoStudioTaskIntro | VideoStudioTaskOutro, indice: number, files: Express.Multer.File[]) {
103 const destination = await moveStudioFileToPersistentTMP(getTaskFileFromReq(files, indice).path)
104
105 return {
106 name: task.name,
107 options: {
108 file: destination
109 }
110 }
111}
112
113function buildCutTask (task: VideoStudioTaskCut) {
114 return Promise.resolve({
115 name: task.name,
116 options: {
117 start: task.options.start,
118 end: task.options.end
119 }
120 })
121}
122
123async function buildWatermarkTask (task: VideoStudioTaskWatermark, indice: number, files: Express.Multer.File[]) {
124 const destination = await moveStudioFileToPersistentTMP(getTaskFileFromReq(files, indice).path)
125
126 return {
127 name: task.name,
128 options: {
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
133 }
134 }
135}
136
137async function moveStudioFileToPersistentTMP (file: string) {
138 const destination = getStudioTaskFilePath(basename(file))
139
140 await move(file, destination)
141
142 return destination
143}