diff options
Diffstat (limited to 'packages/peertube-runner/server/process/shared/process-studio.ts')
-rw-r--r-- | packages/peertube-runner/server/process/shared/process-studio.ts | 165 |
1 files changed, 0 insertions, 165 deletions
diff --git a/packages/peertube-runner/server/process/shared/process-studio.ts b/packages/peertube-runner/server/process/shared/process-studio.ts deleted file mode 100644 index 7bb209e80..000000000 --- a/packages/peertube-runner/server/process/shared/process-studio.ts +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | import { remove } from 'fs-extra' | ||
2 | import { logger } from 'packages/peertube-runner/shared' | ||
3 | import { join } from 'path' | ||
4 | import { pick } from '@shared/core-utils' | ||
5 | import { buildUUID } from '@shared/extra-utils' | ||
6 | import { | ||
7 | RunnerJobStudioTranscodingPayload, | ||
8 | VideoStudioTask, | ||
9 | VideoStudioTaskCutPayload, | ||
10 | VideoStudioTaskIntroPayload, | ||
11 | VideoStudioTaskOutroPayload, | ||
12 | VideoStudioTaskPayload, | ||
13 | VideoStudioTaskWatermarkPayload, | ||
14 | VideoStudioTranscodingSuccess | ||
15 | } from '@shared/models' | ||
16 | import { ConfigManager } from '../../../shared/config-manager' | ||
17 | import { buildFFmpegEdition, downloadInputFile, JobWithToken, ProcessOptions, scheduleTranscodingProgress } from './common' | ||
18 | |||
19 | export async function processStudioTranscoding (options: ProcessOptions<RunnerJobStudioTranscodingPayload>) { | ||
20 | const { server, job, runnerToken } = options | ||
21 | const payload = job.payload | ||
22 | |||
23 | let inputPath: string | ||
24 | let outputPath: string | ||
25 | let tmpInputFilePath: string | ||
26 | |||
27 | let tasksProgress = 0 | ||
28 | |||
29 | const updateProgressInterval = scheduleTranscodingProgress({ | ||
30 | job, | ||
31 | server, | ||
32 | runnerToken, | ||
33 | progressGetter: () => tasksProgress | ||
34 | }) | ||
35 | |||
36 | try { | ||
37 | logger.info(`Downloading input file ${payload.input.videoFileUrl} for job ${job.jobToken}`) | ||
38 | |||
39 | inputPath = await downloadInputFile({ url: payload.input.videoFileUrl, runnerToken, job }) | ||
40 | tmpInputFilePath = inputPath | ||
41 | |||
42 | logger.info(`Input file ${payload.input.videoFileUrl} downloaded for job ${job.jobToken}. Running studio transcoding tasks.`) | ||
43 | |||
44 | for (const task of payload.tasks) { | ||
45 | const outputFilename = 'output-edition-' + buildUUID() + '.mp4' | ||
46 | outputPath = join(ConfigManager.Instance.getTranscodingDirectory(), outputFilename) | ||
47 | |||
48 | await processTask({ | ||
49 | inputPath: tmpInputFilePath, | ||
50 | outputPath, | ||
51 | task, | ||
52 | job, | ||
53 | runnerToken | ||
54 | }) | ||
55 | |||
56 | if (tmpInputFilePath) await remove(tmpInputFilePath) | ||
57 | |||
58 | // For the next iteration | ||
59 | tmpInputFilePath = outputPath | ||
60 | |||
61 | tasksProgress += Math.floor(100 / payload.tasks.length) | ||
62 | } | ||
63 | |||
64 | const successBody: VideoStudioTranscodingSuccess = { | ||
65 | videoFile: outputPath | ||
66 | } | ||
67 | |||
68 | await server.runnerJobs.success({ | ||
69 | jobToken: job.jobToken, | ||
70 | jobUUID: job.uuid, | ||
71 | runnerToken, | ||
72 | payload: successBody | ||
73 | }) | ||
74 | } finally { | ||
75 | if (tmpInputFilePath) await remove(tmpInputFilePath) | ||
76 | if (outputPath) await remove(outputPath) | ||
77 | if (updateProgressInterval) clearInterval(updateProgressInterval) | ||
78 | } | ||
79 | } | ||
80 | |||
81 | // --------------------------------------------------------------------------- | ||
82 | // Private | ||
83 | // --------------------------------------------------------------------------- | ||
84 | |||
85 | type TaskProcessorOptions <T extends VideoStudioTaskPayload = VideoStudioTaskPayload> = { | ||
86 | inputPath: string | ||
87 | outputPath: string | ||
88 | task: T | ||
89 | runnerToken: string | ||
90 | job: JobWithToken | ||
91 | } | ||
92 | |||
93 | const taskProcessors: { [id in VideoStudioTask['name']]: (options: TaskProcessorOptions) => Promise<any> } = { | ||
94 | 'add-intro': processAddIntroOutro, | ||
95 | 'add-outro': processAddIntroOutro, | ||
96 | 'cut': processCut, | ||
97 | 'add-watermark': processAddWatermark | ||
98 | } | ||
99 | |||
100 | async function processTask (options: TaskProcessorOptions) { | ||
101 | const { task } = options | ||
102 | |||
103 | const processor = taskProcessors[options.task.name] | ||
104 | if (!process) throw new Error('Unknown task ' + task.name) | ||
105 | |||
106 | return processor(options) | ||
107 | } | ||
108 | |||
109 | async function processAddIntroOutro (options: TaskProcessorOptions<VideoStudioTaskIntroPayload | VideoStudioTaskOutroPayload>) { | ||
110 | const { inputPath, task, runnerToken, job } = options | ||
111 | |||
112 | logger.debug('Adding intro/outro to ' + inputPath) | ||
113 | |||
114 | const introOutroPath = await downloadInputFile({ url: task.options.file, runnerToken, job }) | ||
115 | |||
116 | try { | ||
117 | await buildFFmpegEdition().addIntroOutro({ | ||
118 | ...pick(options, [ 'inputPath', 'outputPath' ]), | ||
119 | |||
120 | introOutroPath, | ||
121 | type: task.name === 'add-intro' | ||
122 | ? 'intro' | ||
123 | : 'outro' | ||
124 | }) | ||
125 | } finally { | ||
126 | await remove(introOutroPath) | ||
127 | } | ||
128 | } | ||
129 | |||
130 | function processCut (options: TaskProcessorOptions<VideoStudioTaskCutPayload>) { | ||
131 | const { inputPath, task } = options | ||
132 | |||
133 | logger.debug(`Cutting ${inputPath}`) | ||
134 | |||
135 | return buildFFmpegEdition().cutVideo({ | ||
136 | ...pick(options, [ 'inputPath', 'outputPath' ]), | ||
137 | |||
138 | start: task.options.start, | ||
139 | end: task.options.end | ||
140 | }) | ||
141 | } | ||
142 | |||
143 | async function processAddWatermark (options: TaskProcessorOptions<VideoStudioTaskWatermarkPayload>) { | ||
144 | const { inputPath, task, runnerToken, job } = options | ||
145 | |||
146 | logger.debug('Adding watermark to ' + inputPath) | ||
147 | |||
148 | const watermarkPath = await downloadInputFile({ url: task.options.file, runnerToken, job }) | ||
149 | |||
150 | try { | ||
151 | await buildFFmpegEdition().addWatermark({ | ||
152 | ...pick(options, [ 'inputPath', 'outputPath' ]), | ||
153 | |||
154 | watermarkPath, | ||
155 | |||
156 | videoFilters: { | ||
157 | watermarkSizeRatio: task.options.watermarkSizeRatio, | ||
158 | horitonzalMarginRatio: task.options.horitonzalMarginRatio, | ||
159 | verticalMarginRatio: task.options.verticalMarginRatio | ||
160 | } | ||
161 | }) | ||
162 | } finally { | ||
163 | await remove(watermarkPath) | ||
164 | } | ||
165 | } | ||