aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/peertube-runner/server/process/process.ts6
-rw-r--r--packages/peertube-runner/server/process/shared/common.ts9
-rw-r--r--packages/peertube-runner/server/process/shared/index.ts1
-rw-r--r--packages/peertube-runner/server/process/shared/process-studio.ts50
-rw-r--r--packages/peertube-runner/server/process/shared/process-vod.ts85
-rw-r--r--packages/peertube-runner/server/shared/supported-job.ts4
-rw-r--r--server/controllers/api/runners/jobs-files.ts6
-rw-r--r--server/controllers/api/runners/jobs.ts4
-rw-r--r--server/helpers/custom-validators/runners/jobs.ts16
-rw-r--r--server/lib/job-queue/handlers/video-studio-edition.ts6
-rw-r--r--server/lib/runners/job-handlers/abstract-job-handler.ts10
-rw-r--r--server/lib/runners/job-handlers/index.ts2
-rw-r--r--server/lib/runners/job-handlers/runner-job-handlers.ts4
-rw-r--r--server/lib/runners/job-handlers/video-studio-transcoding-job-handler.ts (renamed from server/lib/runners/job-handlers/video-edition-transcoding-job-handler.ts)24
-rw-r--r--server/lib/transcoding/default-transcoding-profiles.ts145
-rw-r--r--server/lib/video-studio.ts8
-rw-r--r--server/middlewares/validators/runners/job-files.ts4
-rw-r--r--server/tests/api/check-params/runners.ts10
-rw-r--r--server/tests/api/runners/runner-studio-transcoding.ts10
-rw-r--r--server/tests/api/transcoding/video-studio.ts4
-rw-r--r--shared/ffmpeg/ffmpeg-default-transcoding-profile.ts (renamed from packages/peertube-runner/server/process/shared/transcoding-profiles.ts)4
-rw-r--r--shared/ffmpeg/index.ts1
-rw-r--r--shared/models/runners/runner-job-payload.model.ts4
-rw-r--r--shared/models/runners/runner-job-private-payload.model.ts4
-rw-r--r--shared/models/runners/runner-job-success-body.model.ts4
-rw-r--r--shared/models/runners/runner-job-type.type.ts2
26 files changed, 151 insertions, 276 deletions
diff --git a/packages/peertube-runner/server/process/process.ts b/packages/peertube-runner/server/process/process.ts
index ef231cb38..1caafda8c 100644
--- a/packages/peertube-runner/server/process/process.ts
+++ b/packages/peertube-runner/server/process/process.ts
@@ -1,7 +1,7 @@
1import { logger } from 'packages/peertube-runner/shared/logger' 1import { logger } from 'packages/peertube-runner/shared/logger'
2import { 2import {
3 RunnerJobLiveRTMPHLSTranscodingPayload, 3 RunnerJobLiveRTMPHLSTranscodingPayload,
4 RunnerJobVideoEditionTranscodingPayload, 4 RunnerJobStudioTranscodingPayload,
5 RunnerJobVODAudioMergeTranscodingPayload, 5 RunnerJobVODAudioMergeTranscodingPayload,
6 RunnerJobVODHLSTranscodingPayload, 6 RunnerJobVODHLSTranscodingPayload,
7 RunnerJobVODWebVideoTranscodingPayload 7 RunnerJobVODWebVideoTranscodingPayload
@@ -23,8 +23,8 @@ export async function processJob (options: ProcessOptions) {
23 await processHLSTranscoding(options as ProcessOptions<RunnerJobVODHLSTranscodingPayload>) 23 await processHLSTranscoding(options as ProcessOptions<RunnerJobVODHLSTranscodingPayload>)
24 } else if (job.type === 'live-rtmp-hls-transcoding') { 24 } else if (job.type === 'live-rtmp-hls-transcoding') {
25 await new ProcessLiveRTMPHLSTranscoding(options as ProcessOptions<RunnerJobLiveRTMPHLSTranscodingPayload>).process() 25 await new ProcessLiveRTMPHLSTranscoding(options as ProcessOptions<RunnerJobLiveRTMPHLSTranscodingPayload>).process()
26 } else if (job.type === 'video-edition-transcoding') { 26 } else if (job.type === 'video-studio-transcoding') {
27 await processStudioTranscoding(options as ProcessOptions<RunnerJobVideoEditionTranscodingPayload>) 27 await processStudioTranscoding(options as ProcessOptions<RunnerJobStudioTranscodingPayload>)
28 } else { 28 } else {
29 logger.error(`Unknown job ${job.type} to process`) 29 logger.error(`Unknown job ${job.type} to process`)
30 return 30 return
diff --git a/packages/peertube-runner/server/process/shared/common.ts b/packages/peertube-runner/server/process/shared/common.ts
index 3cac98388..88f7c33f1 100644
--- a/packages/peertube-runner/server/process/shared/common.ts
+++ b/packages/peertube-runner/server/process/shared/common.ts
@@ -1,13 +1,12 @@
1import { remove } from 'fs-extra'
1import { throttle } from 'lodash' 2import { throttle } from 'lodash'
2import { ConfigManager, downloadFile, logger } from 'packages/peertube-runner/shared' 3import { ConfigManager, downloadFile, logger } from 'packages/peertube-runner/shared'
3import { join } from 'path' 4import { join } from 'path'
4import { buildUUID } from '@shared/extra-utils' 5import { buildUUID } from '@shared/extra-utils'
5import { FFmpegEdition, FFmpegLive, FFmpegVOD } from '@shared/ffmpeg' 6import { FFmpegEdition, FFmpegLive, FFmpegVOD, getDefaultAvailableEncoders, getDefaultEncodersToTry } from '@shared/ffmpeg'
6import { RunnerJob, RunnerJobPayload } from '@shared/models' 7import { RunnerJob, RunnerJobPayload } from '@shared/models'
7import { PeerTubeServer } from '@shared/server-commands' 8import { PeerTubeServer } from '@shared/server-commands'
8import { getTranscodingLogger } from './transcoding-logger' 9import { getTranscodingLogger } from './transcoding-logger'
9import { getAvailableEncoders, getEncodersToTry } from './transcoding-profiles'
10import { remove } from 'fs-extra'
11 10
12export type JobWithToken <T extends RunnerJobPayload = RunnerJobPayload> = RunnerJob<T> & { jobToken: string } 11export type JobWithToken <T extends RunnerJobPayload = RunnerJobPayload> = RunnerJob<T> & { jobToken: string }
13 12
@@ -92,8 +91,8 @@ function getCommonFFmpegOptions () {
92 tmpDirectory: ConfigManager.Instance.getTranscodingDirectory(), 91 tmpDirectory: ConfigManager.Instance.getTranscodingDirectory(),
93 profile: 'default', 92 profile: 'default',
94 availableEncoders: { 93 availableEncoders: {
95 available: getAvailableEncoders(), 94 available: getDefaultAvailableEncoders(),
96 encodersToTry: getEncodersToTry() 95 encodersToTry: getDefaultEncodersToTry()
97 }, 96 },
98 logger: getTranscodingLogger() 97 logger: getTranscodingLogger()
99 } 98 }
diff --git a/packages/peertube-runner/server/process/shared/index.ts b/packages/peertube-runner/server/process/shared/index.ts
index 8e09a7869..556c51365 100644
--- a/packages/peertube-runner/server/process/shared/index.ts
+++ b/packages/peertube-runner/server/process/shared/index.ts
@@ -1,4 +1,3 @@
1export * from './common' 1export * from './common'
2export * from './process-vod' 2export * from './process-vod'
3export * from './transcoding-logger' 3export * from './transcoding-logger'
4export * from './transcoding-profiles'
diff --git a/packages/peertube-runner/server/process/shared/process-studio.ts b/packages/peertube-runner/server/process/shared/process-studio.ts
index f8262096e..9c745d031 100644
--- a/packages/peertube-runner/server/process/shared/process-studio.ts
+++ b/packages/peertube-runner/server/process/shared/process-studio.ts
@@ -1,11 +1,11 @@
1import { remove } from 'fs-extra' 1import { remove } from 'fs-extra'
2import { pick } from 'lodash' 2import { pick } from 'lodash'
3import { logger } from 'packages/peertube-runner/shared' 3import { logger } from 'packages/peertube-runner/shared'
4import { extname, join } from 'path' 4import { join } from 'path'
5import { buildUUID } from '@shared/extra-utils' 5import { buildUUID } from '@shared/extra-utils'
6import { 6import {
7 RunnerJobVideoEditionTranscodingPayload, 7 RunnerJobStudioTranscodingPayload,
8 VideoEditionTranscodingSuccess, 8 VideoStudioTranscodingSuccess,
9 VideoStudioTask, 9 VideoStudioTask,
10 VideoStudioTaskCutPayload, 10 VideoStudioTaskCutPayload,
11 VideoStudioTaskIntroPayload, 11 VideoStudioTaskIntroPayload,
@@ -16,7 +16,7 @@ import {
16import { ConfigManager } from '../../../shared/config-manager' 16import { ConfigManager } from '../../../shared/config-manager'
17import { buildFFmpegEdition, downloadInputFile, JobWithToken, ProcessOptions } from './common' 17import { buildFFmpegEdition, downloadInputFile, JobWithToken, ProcessOptions } from './common'
18 18
19export async function processStudioTranscoding (options: ProcessOptions<RunnerJobVideoEditionTranscodingPayload>) { 19export async function processStudioTranscoding (options: ProcessOptions<RunnerJobStudioTranscodingPayload>) {
20 const { server, job, runnerToken } = options 20 const { server, job, runnerToken } = options
21 const payload = job.payload 21 const payload = job.payload
22 22
@@ -43,7 +43,7 @@ export async function processStudioTranscoding (options: ProcessOptions<RunnerJo
43 tmpInputFilePath = outputPath 43 tmpInputFilePath = outputPath
44 } 44 }
45 45
46 const successBody: VideoEditionTranscodingSuccess = { 46 const successBody: VideoStudioTranscodingSuccess = {
47 videoFile: outputPath 47 videoFile: outputPath
48 } 48 }
49 49
@@ -94,14 +94,18 @@ async function processAddIntroOutro (options: TaskProcessorOptions<VideoStudioTa
94 94
95 const introOutroPath = await downloadInputFile({ url: task.options.file, runnerToken, job }) 95 const introOutroPath = await downloadInputFile({ url: task.options.file, runnerToken, job })
96 96
97 return buildFFmpegEdition().addIntroOutro({ 97 try {
98 ...pick(options, [ 'inputPath', 'outputPath' ]), 98 await buildFFmpegEdition().addIntroOutro({
99 ...pick(options, [ 'inputPath', 'outputPath' ]),
99 100
100 introOutroPath, 101 introOutroPath,
101 type: task.name === 'add-intro' 102 type: task.name === 'add-intro'
102 ? 'intro' 103 ? 'intro'
103 : 'outro' 104 : 'outro'
104 }) 105 })
106 } finally {
107 await remove(introOutroPath)
108 }
105} 109}
106 110
107function processCut (options: TaskProcessorOptions<VideoStudioTaskCutPayload>) { 111function processCut (options: TaskProcessorOptions<VideoStudioTaskCutPayload>) {
@@ -124,15 +128,19 @@ async function processAddWatermark (options: TaskProcessorOptions<VideoStudioTas
124 128
125 const watermarkPath = await downloadInputFile({ url: task.options.file, runnerToken, job }) 129 const watermarkPath = await downloadInputFile({ url: task.options.file, runnerToken, job })
126 130
127 return buildFFmpegEdition().addWatermark({ 131 try {
128 ...pick(options, [ 'inputPath', 'outputPath' ]), 132 await buildFFmpegEdition().addWatermark({
133 ...pick(options, [ 'inputPath', 'outputPath' ]),
129 134
130 watermarkPath, 135 watermarkPath,
131 136
132 videoFilters: { 137 videoFilters: {
133 watermarkSizeRatio: task.options.watermarkSizeRatio, 138 watermarkSizeRatio: task.options.watermarkSizeRatio,
134 horitonzalMarginRatio: task.options.horitonzalMarginRatio, 139 horitonzalMarginRatio: task.options.horitonzalMarginRatio,
135 verticalMarginRatio: task.options.verticalMarginRatio 140 verticalMarginRatio: task.options.verticalMarginRatio
136 } 141 }
137 }) 142 })
143 } finally {
144 await remove(watermarkPath)
145 }
138} 146}
diff --git a/packages/peertube-runner/server/process/shared/process-vod.ts b/packages/peertube-runner/server/process/shared/process-vod.ts
index d84ece3cb..22489afd5 100644
--- a/packages/peertube-runner/server/process/shared/process-vod.ts
+++ b/packages/peertube-runner/server/process/shared/process-vod.ts
@@ -22,31 +22,34 @@ export async function processWebVideoTranscoding (options: ProcessOptions<Runner
22 22
23 const outputPath = join(ConfigManager.Instance.getTranscodingDirectory(), `output-${buildUUID()}.mp4`) 23 const outputPath = join(ConfigManager.Instance.getTranscodingDirectory(), `output-${buildUUID()}.mp4`)
24 24
25 await ffmpegVod.transcode({ 25 try {
26 type: 'video', 26 await ffmpegVod.transcode({
27 27 type: 'video',
28 inputPath,
29 28
30 outputPath, 29 inputPath,
31 30
32 inputFileMutexReleaser: () => {}, 31 outputPath,
33 32
34 resolution: payload.output.resolution, 33 inputFileMutexReleaser: () => {},
35 fps: payload.output.fps
36 })
37 34
38 const successBody: VODWebVideoTranscodingSuccess = { 35 resolution: payload.output.resolution,
39 videoFile: outputPath 36 fps: payload.output.fps
40 } 37 })
41 38
42 await server.runnerJobs.success({ 39 const successBody: VODWebVideoTranscodingSuccess = {
43 jobToken: job.jobToken, 40 videoFile: outputPath
44 jobUUID: job.uuid, 41 }
45 runnerToken,
46 payload: successBody
47 })
48 42
49 await remove(outputPath) 43 await server.runnerJobs.success({
44 jobToken: job.jobToken,
45 jobUUID: job.uuid,
46 runnerToken,
47 payload: successBody
48 })
49 } finally {
50 await remove(inputPath)
51 await remove(outputPath)
52 }
50} 53}
51 54
52export async function processHLSTranscoding (options: ProcessOptions<RunnerJobVODHLSTranscodingPayload>) { 55export async function processHLSTranscoding (options: ProcessOptions<RunnerJobVODHLSTranscodingPayload>) {
@@ -105,30 +108,34 @@ export async function processAudioMergeTranscoding (options: ProcessOptions<Runn
105 108
106 const ffmpegVod = buildFFmpegVOD({ job, server, runnerToken }) 109 const ffmpegVod = buildFFmpegVOD({ job, server, runnerToken })
107 110
108 await ffmpegVod.transcode({ 111 try {
109 type: 'merge-audio', 112 await ffmpegVod.transcode({
110 113 type: 'merge-audio',
111 audioPath,
112 inputPath,
113 114
114 outputPath, 115 audioPath,
116 inputPath,
115 117
116 inputFileMutexReleaser: () => {}, 118 outputPath,
117 119
118 resolution: payload.output.resolution, 120 inputFileMutexReleaser: () => {},
119 fps: payload.output.fps
120 })
121 121
122 const successBody: VODAudioMergeTranscodingSuccess = { 122 resolution: payload.output.resolution,
123 videoFile: outputPath 123 fps: payload.output.fps
124 } 124 })
125 125
126 await server.runnerJobs.success({ 126 const successBody: VODAudioMergeTranscodingSuccess = {
127 jobToken: job.jobToken, 127 videoFile: outputPath
128 jobUUID: job.uuid, 128 }
129 runnerToken,
130 payload: successBody
131 })
132 129
133 await remove(outputPath) 130 await server.runnerJobs.success({
131 jobToken: job.jobToken,
132 jobUUID: job.uuid,
133 runnerToken,
134 payload: successBody
135 })
136 } finally {
137 await remove(audioPath)
138 await remove(inputPath)
139 await remove(outputPath)
140 }
134} 141}
diff --git a/packages/peertube-runner/server/shared/supported-job.ts b/packages/peertube-runner/server/shared/supported-job.ts
index 87d5a39cc..1137d8206 100644
--- a/packages/peertube-runner/server/shared/supported-job.ts
+++ b/packages/peertube-runner/server/shared/supported-job.ts
@@ -2,7 +2,7 @@ import {
2 RunnerJobLiveRTMPHLSTranscodingPayload, 2 RunnerJobLiveRTMPHLSTranscodingPayload,
3 RunnerJobPayload, 3 RunnerJobPayload,
4 RunnerJobType, 4 RunnerJobType,
5 RunnerJobVideoEditionTranscodingPayload, 5 RunnerJobStudioTranscodingPayload,
6 RunnerJobVODAudioMergeTranscodingPayload, 6 RunnerJobVODAudioMergeTranscodingPayload,
7 RunnerJobVODHLSTranscodingPayload, 7 RunnerJobVODHLSTranscodingPayload,
8 RunnerJobVODWebVideoTranscodingPayload, 8 RunnerJobVODWebVideoTranscodingPayload,
@@ -22,7 +22,7 @@ const supportedMatrix = {
22 'live-rtmp-hls-transcoding': (_payload: RunnerJobLiveRTMPHLSTranscodingPayload) => { 22 'live-rtmp-hls-transcoding': (_payload: RunnerJobLiveRTMPHLSTranscodingPayload) => {
23 return true 23 return true
24 }, 24 },
25 'video-edition-transcoding': (payload: RunnerJobVideoEditionTranscodingPayload) => { 25 'video-studio-transcoding': (payload: RunnerJobStudioTranscodingPayload) => {
26 const tasks = payload?.tasks 26 const tasks = payload?.tasks
27 const supported = new Set<VideoStudioTaskPayload['name']>([ 'add-intro', 'add-outro', 'add-watermark', 'cut' ]) 27 const supported = new Set<VideoStudioTaskPayload['name']>([ 'add-intro', 'add-outro', 'add-watermark', 'cut' ])
28 28
diff --git a/server/controllers/api/runners/jobs-files.ts b/server/controllers/api/runners/jobs-files.ts
index 4efa40b3a..260d824a8 100644
--- a/server/controllers/api/runners/jobs-files.ts
+++ b/server/controllers/api/runners/jobs-files.ts
@@ -31,7 +31,7 @@ runnerJobFilesRouter.post('/jobs/:jobUUID/files/videos/:videoId/studio/task-file
31 asyncMiddleware(jobOfRunnerGetValidator), 31 asyncMiddleware(jobOfRunnerGetValidator),
32 asyncMiddleware(runnerJobGetVideoTranscodingFileValidator), 32 asyncMiddleware(runnerJobGetVideoTranscodingFileValidator),
33 runnerJobGetVideoStudioTaskFileValidator, 33 runnerJobGetVideoStudioTaskFileValidator,
34 getVideoEditionTaskFile 34 getVideoStudioTaskFile
35) 35)
36 36
37// --------------------------------------------------------------------------- 37// ---------------------------------------------------------------------------
@@ -94,14 +94,14 @@ function getMaxQualityVideoPreview (req: express.Request, res: express.Response)
94 return res.sendFile(file.getPath()) 94 return res.sendFile(file.getPath())
95} 95}
96 96
97function getVideoEditionTaskFile (req: express.Request, res: express.Response) { 97function getVideoStudioTaskFile (req: express.Request, res: express.Response) {
98 const runnerJob = res.locals.runnerJob 98 const runnerJob = res.locals.runnerJob
99 const runner = runnerJob.Runner 99 const runner = runnerJob.Runner
100 const video = res.locals.videoAll 100 const video = res.locals.videoAll
101 const filename = req.params.filename 101 const filename = req.params.filename
102 102
103 logger.info( 103 logger.info(
104 'Get video edition task file %s of video %s of job %s for runner %s', filename, video.uuid, runnerJob.uuid, runner.name, 104 'Get video studio task file %s of video %s of job %s for runner %s', filename, video.uuid, runnerJob.uuid, runner.name,
105 lTags(runner.name, runnerJob.id, runnerJob.type) 105 lTags(runner.name, runnerJob.id, runnerJob.type)
106 ) 106 )
107 107
diff --git a/server/controllers/api/runners/jobs.ts b/server/controllers/api/runners/jobs.ts
index 8e34c07a3..3f2a92182 100644
--- a/server/controllers/api/runners/jobs.ts
+++ b/server/controllers/api/runners/jobs.ts
@@ -42,7 +42,7 @@ import {
42 RunnerJobUpdateBody, 42 RunnerJobUpdateBody,
43 RunnerJobUpdatePayload, 43 RunnerJobUpdatePayload,
44 UserRight, 44 UserRight,
45 VideoEditionTranscodingSuccess, 45 VideoStudioTranscodingSuccess,
46 VODAudioMergeTranscodingSuccess, 46 VODAudioMergeTranscodingSuccess,
47 VODHLSTranscodingSuccess, 47 VODHLSTranscodingSuccess,
48 VODWebVideoTranscodingSuccess 48 VODWebVideoTranscodingSuccess
@@ -300,7 +300,7 @@ const jobSuccessPayloadBuilders: {
300 } 300 }
301 }, 301 },
302 302
303 'video-edition-transcoding': (payload: VideoEditionTranscodingSuccess, files) => { 303 'video-studio-transcoding': (payload: VideoStudioTranscodingSuccess, files) => {
304 return { 304 return {
305 ...payload, 305 ...payload,
306 306
diff --git a/server/helpers/custom-validators/runners/jobs.ts b/server/helpers/custom-validators/runners/jobs.ts
index 934bd37c9..725a7658f 100644
--- a/server/helpers/custom-validators/runners/jobs.ts
+++ b/server/helpers/custom-validators/runners/jobs.ts
@@ -6,7 +6,7 @@ import {
6 RunnerJobSuccessPayload, 6 RunnerJobSuccessPayload,
7 RunnerJobType, 7 RunnerJobType,
8 RunnerJobUpdatePayload, 8 RunnerJobUpdatePayload,
9 VideoEditionTranscodingSuccess, 9 VideoStudioTranscodingSuccess,
10 VODAudioMergeTranscodingSuccess, 10 VODAudioMergeTranscodingSuccess,
11 VODHLSTranscodingSuccess, 11 VODHLSTranscodingSuccess,
12 VODWebVideoTranscodingSuccess 12 VODWebVideoTranscodingSuccess
@@ -25,7 +25,7 @@ function isRunnerJobSuccessPayloadValid (value: RunnerJobSuccessPayload, type: R
25 isRunnerJobVODHLSResultPayloadValid(value as VODHLSTranscodingSuccess, type, files) || 25 isRunnerJobVODHLSResultPayloadValid(value as VODHLSTranscodingSuccess, type, files) ||
26 isRunnerJobVODAudioMergeResultPayloadValid(value as VODHLSTranscodingSuccess, type, files) || 26 isRunnerJobVODAudioMergeResultPayloadValid(value as VODHLSTranscodingSuccess, type, files) ||
27 isRunnerJobLiveRTMPHLSResultPayloadValid(value as LiveRTMPHLSTranscodingSuccess, type) || 27 isRunnerJobLiveRTMPHLSResultPayloadValid(value as LiveRTMPHLSTranscodingSuccess, type) ||
28 isRunnerJobVideoEditionResultPayloadValid(value as VideoEditionTranscodingSuccess, type, files) 28 isRunnerJobVideoStudioResultPayloadValid(value as VideoStudioTranscodingSuccess, type, files)
29} 29}
30 30
31// --------------------------------------------------------------------------- 31// ---------------------------------------------------------------------------
@@ -37,7 +37,7 @@ function isRunnerJobProgressValid (value: string) {
37function isRunnerJobUpdatePayloadValid (value: RunnerJobUpdatePayload, type: RunnerJobType, files: UploadFilesForCheck) { 37function isRunnerJobUpdatePayloadValid (value: RunnerJobUpdatePayload, type: RunnerJobType, files: UploadFilesForCheck) {
38 return isRunnerJobVODWebVideoUpdatePayloadValid(value, type, files) || 38 return isRunnerJobVODWebVideoUpdatePayloadValid(value, type, files) ||
39 isRunnerJobVODHLSUpdatePayloadValid(value, type, files) || 39 isRunnerJobVODHLSUpdatePayloadValid(value, type, files) ||
40 isRunnerJobVideoEditionUpdatePayloadValid(value, type, files) || 40 isRunnerJobVideoStudioUpdatePayloadValid(value, type, files) ||
41 isRunnerJobVODAudioMergeUpdatePayloadValid(value, type, files) || 41 isRunnerJobVODAudioMergeUpdatePayloadValid(value, type, files) ||
42 isRunnerJobLiveRTMPHLSUpdatePayloadValid(value, type, files) 42 isRunnerJobLiveRTMPHLSUpdatePayloadValid(value, type, files)
43} 43}
@@ -105,12 +105,12 @@ function isRunnerJobLiveRTMPHLSResultPayloadValid (
105 return type === 'live-rtmp-hls-transcoding' && (!value || (typeof value === 'object' && Object.keys(value).length === 0)) 105 return type === 'live-rtmp-hls-transcoding' && (!value || (typeof value === 'object' && Object.keys(value).length === 0))
106} 106}
107 107
108function isRunnerJobVideoEditionResultPayloadValid ( 108function isRunnerJobVideoStudioResultPayloadValid (
109 _value: VideoEditionTranscodingSuccess, 109 _value: VideoStudioTranscodingSuccess,
110 type: RunnerJobType, 110 type: RunnerJobType,
111 files: UploadFilesForCheck 111 files: UploadFilesForCheck
112) { 112) {
113 return type === 'video-edition-transcoding' && 113 return type === 'video-studio-transcoding' &&
114 isFileValid({ files, field: 'payload[videoFile]', mimeTypeRegex: null, maxSize: null }) 114 isFileValid({ files, field: 'payload[videoFile]', mimeTypeRegex: null, maxSize: null })
115} 115}
116 116
@@ -177,11 +177,11 @@ function isRunnerJobLiveRTMPHLSUpdatePayloadValid (
177 ) 177 )
178} 178}
179 179
180function isRunnerJobVideoEditionUpdatePayloadValid ( 180function isRunnerJobVideoStudioUpdatePayloadValid (
181 value: RunnerJobUpdatePayload, 181 value: RunnerJobUpdatePayload,
182 type: RunnerJobType, 182 type: RunnerJobType,
183 _files: UploadFilesForCheck 183 _files: UploadFilesForCheck
184) { 184) {
185 return type === 'video-edition-transcoding' && 185 return type === 'video-studio-transcoding' &&
186 (!value || (typeof value === 'object' && Object.keys(value).length === 0)) 186 (!value || (typeof value === 'object' && Object.keys(value).length === 0))
187} 187}
diff --git a/server/lib/job-queue/handlers/video-studio-edition.ts b/server/lib/job-queue/handlers/video-studio-edition.ts
index df73caf72..caf051bfa 100644
--- a/server/lib/job-queue/handlers/video-studio-edition.ts
+++ b/server/lib/job-queue/handlers/video-studio-edition.ts
@@ -6,7 +6,7 @@ import { CONFIG } from '@server/initializers/config'
6import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles' 6import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles'
7import { isAbleToUploadVideo } from '@server/lib/user' 7import { isAbleToUploadVideo } from '@server/lib/user'
8import { VideoPathManager } from '@server/lib/video-path-manager' 8import { VideoPathManager } from '@server/lib/video-path-manager'
9import { approximateIntroOutroAdditionalSize, onVideoEditionEnded, safeCleanupStudioTMPFiles } from '@server/lib/video-studio' 9import { approximateIntroOutroAdditionalSize, onVideoStudioEnded, safeCleanupStudioTMPFiles } from '@server/lib/video-studio'
10import { UserModel } from '@server/models/user/user' 10import { UserModel } from '@server/models/user/user'
11import { VideoModel } from '@server/models/video/video' 11import { VideoModel } from '@server/models/video/video'
12import { MVideo, MVideoFullLight } from '@server/types/models' 12import { MVideo, MVideoFullLight } from '@server/types/models'
@@ -24,7 +24,7 @@ import {
24} from '@shared/models' 24} from '@shared/models'
25import { logger, loggerTagsFactory } from '../../../helpers/logger' 25import { logger, loggerTagsFactory } from '../../../helpers/logger'
26 26
27const lTagsBase = loggerTagsFactory('video-edition') 27const lTagsBase = loggerTagsFactory('video-studio')
28 28
29async function processVideoStudioEdition (job: Job) { 29async function processVideoStudioEdition (job: Job) {
30 const payload = job.data as VideoStudioEditionPayload 30 const payload = job.data as VideoStudioEditionPayload
@@ -74,7 +74,7 @@ async function processVideoStudioEdition (job: Job) {
74 74
75 logger.info('Video edition ended for video %s.', video.uuid, lTags) 75 logger.info('Video edition ended for video %s.', video.uuid, lTags)
76 76
77 await onVideoEditionEnded({ video, editionResultPath, tasks: payload.tasks }) 77 await onVideoStudioEnded({ video, editionResultPath, tasks: payload.tasks })
78 } catch (err) { 78 } catch (err) {
79 await safeCleanupStudioTMPFiles(payload.tasks) 79 await safeCleanupStudioTMPFiles(payload.tasks)
80 80
diff --git a/server/lib/runners/job-handlers/abstract-job-handler.ts b/server/lib/runners/job-handlers/abstract-job-handler.ts
index 76fd1c5ac..28c3e1eda 100644
--- a/server/lib/runners/job-handlers/abstract-job-handler.ts
+++ b/server/lib/runners/job-handlers/abstract-job-handler.ts
@@ -15,8 +15,8 @@ import {
15 RunnerJobSuccessPayload, 15 RunnerJobSuccessPayload,
16 RunnerJobType, 16 RunnerJobType,
17 RunnerJobUpdatePayload, 17 RunnerJobUpdatePayload,
18 RunnerJobVideoEditionTranscodingPayload, 18 RunnerJobStudioTranscodingPayload,
19 RunnerJobVideoEditionTranscodingPrivatePayload, 19 RunnerJobVideoStudioTranscodingPrivatePayload,
20 RunnerJobVODAudioMergeTranscodingPayload, 20 RunnerJobVODAudioMergeTranscodingPayload,
21 RunnerJobVODAudioMergeTranscodingPrivatePayload, 21 RunnerJobVODAudioMergeTranscodingPrivatePayload,
22 RunnerJobVODHLSTranscodingPayload, 22 RunnerJobVODHLSTranscodingPayload,
@@ -47,9 +47,9 @@ type CreateRunnerJobArg =
47 privatePayload: RunnerJobLiveRTMPHLSTranscodingPrivatePayload 47 privatePayload: RunnerJobLiveRTMPHLSTranscodingPrivatePayload
48 } | 48 } |
49 { 49 {
50 type: Extract<RunnerJobType, 'video-edition-transcoding'> 50 type: Extract<RunnerJobType, 'video-studio-transcoding'>
51 payload: RunnerJobVideoEditionTranscodingPayload 51 payload: RunnerJobStudioTranscodingPayload
52 privatePayload: RunnerJobVideoEditionTranscodingPrivatePayload 52 privatePayload: RunnerJobVideoStudioTranscodingPrivatePayload
53 } 53 }
54 54
55export abstract class AbstractJobHandler <C, U extends RunnerJobUpdatePayload, S extends RunnerJobSuccessPayload> { 55export abstract class AbstractJobHandler <C, U extends RunnerJobUpdatePayload, S extends RunnerJobSuccessPayload> {
diff --git a/server/lib/runners/job-handlers/index.ts b/server/lib/runners/job-handlers/index.ts
index a40cee865..40ad2f97a 100644
--- a/server/lib/runners/job-handlers/index.ts
+++ b/server/lib/runners/job-handlers/index.ts
@@ -1,7 +1,7 @@
1export * from './abstract-job-handler' 1export * from './abstract-job-handler'
2export * from './live-rtmp-hls-transcoding-job-handler' 2export * from './live-rtmp-hls-transcoding-job-handler'
3export * from './runner-job-handlers' 3export * from './runner-job-handlers'
4export * from './video-edition-transcoding-job-handler' 4export * from './video-studio-transcoding-job-handler'
5export * from './vod-audio-merge-transcoding-job-handler' 5export * from './vod-audio-merge-transcoding-job-handler'
6export * from './vod-hls-transcoding-job-handler' 6export * from './vod-hls-transcoding-job-handler'
7export * from './vod-web-video-transcoding-job-handler' 7export * from './vod-web-video-transcoding-job-handler'
diff --git a/server/lib/runners/job-handlers/runner-job-handlers.ts b/server/lib/runners/job-handlers/runner-job-handlers.ts
index 4ea6684ea..85551c365 100644
--- a/server/lib/runners/job-handlers/runner-job-handlers.ts
+++ b/server/lib/runners/job-handlers/runner-job-handlers.ts
@@ -2,7 +2,7 @@ import { MRunnerJob } from '@server/types/models/runners'
2import { RunnerJobSuccessPayload, RunnerJobType, RunnerJobUpdatePayload } from '@shared/models' 2import { RunnerJobSuccessPayload, RunnerJobType, RunnerJobUpdatePayload } from '@shared/models'
3import { AbstractJobHandler } from './abstract-job-handler' 3import { AbstractJobHandler } from './abstract-job-handler'
4import { LiveRTMPHLSTranscodingJobHandler } from './live-rtmp-hls-transcoding-job-handler' 4import { LiveRTMPHLSTranscodingJobHandler } from './live-rtmp-hls-transcoding-job-handler'
5import { VideoEditionTranscodingJobHandler } from './video-edition-transcoding-job-handler' 5import { VideoStudioTranscodingJobHandler } from './video-studio-transcoding-job-handler'
6import { VODAudioMergeTranscodingJobHandler } from './vod-audio-merge-transcoding-job-handler' 6import { VODAudioMergeTranscodingJobHandler } from './vod-audio-merge-transcoding-job-handler'
7import { VODHLSTranscodingJobHandler } from './vod-hls-transcoding-job-handler' 7import { VODHLSTranscodingJobHandler } from './vod-hls-transcoding-job-handler'
8import { VODWebVideoTranscodingJobHandler } from './vod-web-video-transcoding-job-handler' 8import { VODWebVideoTranscodingJobHandler } from './vod-web-video-transcoding-job-handler'
@@ -12,7 +12,7 @@ const processors: Record<RunnerJobType, new() => AbstractJobHandler<unknown, Run
12 'vod-hls-transcoding': VODHLSTranscodingJobHandler, 12 'vod-hls-transcoding': VODHLSTranscodingJobHandler,
13 'vod-audio-merge-transcoding': VODAudioMergeTranscodingJobHandler, 13 'vod-audio-merge-transcoding': VODAudioMergeTranscodingJobHandler,
14 'live-rtmp-hls-transcoding': LiveRTMPHLSTranscodingJobHandler, 14 'live-rtmp-hls-transcoding': LiveRTMPHLSTranscodingJobHandler,
15 'video-edition-transcoding': VideoEditionTranscodingJobHandler 15 'video-studio-transcoding': VideoStudioTranscodingJobHandler
16} 16}
17 17
18export function getRunnerJobHandlerClass (job: MRunnerJob) { 18export function getRunnerJobHandlerClass (job: MRunnerJob) {
diff --git a/server/lib/runners/job-handlers/video-edition-transcoding-job-handler.ts b/server/lib/runners/job-handlers/video-studio-transcoding-job-handler.ts
index 39a755c48..f604382b7 100644
--- a/server/lib/runners/job-handlers/video-edition-transcoding-job-handler.ts
+++ b/server/lib/runners/job-handlers/video-studio-transcoding-job-handler.ts
@@ -1,7 +1,7 @@
1 1
2import { basename } from 'path' 2import { basename } from 'path'
3import { logger } from '@server/helpers/logger' 3import { logger } from '@server/helpers/logger'
4import { onVideoEditionEnded, safeCleanupStudioTMPFiles } from '@server/lib/video-studio' 4import { onVideoStudioEnded, safeCleanupStudioTMPFiles } from '@server/lib/video-studio'
5import { MVideo } from '@server/types/models' 5import { MVideo } from '@server/types/models'
6import { MRunnerJob } from '@server/types/models/runners' 6import { MRunnerJob } from '@server/types/models/runners'
7import { buildUUID } from '@shared/extra-utils' 7import { buildUUID } from '@shared/extra-utils'
@@ -11,9 +11,9 @@ import {
11 isVideoStudioTaskWatermark, 11 isVideoStudioTaskWatermark,
12 RunnerJobState, 12 RunnerJobState,
13 RunnerJobUpdatePayload, 13 RunnerJobUpdatePayload,
14 RunnerJobVideoEditionTranscodingPayload, 14 RunnerJobStudioTranscodingPayload,
15 RunnerJobVideoEditionTranscodingPrivatePayload, 15 RunnerJobVideoStudioTranscodingPrivatePayload,
16 VideoEditionTranscodingSuccess, 16 VideoStudioTranscodingSuccess,
17 VideoState, 17 VideoState,
18 VideoStudioTaskPayload 18 VideoStudioTaskPayload
19} from '@shared/models' 19} from '@shared/models'
@@ -28,13 +28,13 @@ type CreateOptions = {
28} 28}
29 29
30// eslint-disable-next-line max-len 30// eslint-disable-next-line max-len
31export class VideoEditionTranscodingJobHandler extends AbstractJobHandler<CreateOptions, RunnerJobUpdatePayload, VideoEditionTranscodingSuccess> { 31export class VideoStudioTranscodingJobHandler extends AbstractJobHandler<CreateOptions, RunnerJobUpdatePayload, VideoStudioTranscodingSuccess> {
32 32
33 async create (options: CreateOptions) { 33 async create (options: CreateOptions) {
34 const { video, priority, tasks } = options 34 const { video, priority, tasks } = options
35 35
36 const jobUUID = buildUUID() 36 const jobUUID = buildUUID()
37 const payload: RunnerJobVideoEditionTranscodingPayload = { 37 const payload: RunnerJobStudioTranscodingPayload = {
38 input: { 38 input: {
39 videoFileUrl: generateRunnerTranscodingVideoInputFileUrl(jobUUID, video.uuid) 39 videoFileUrl: generateRunnerTranscodingVideoInputFileUrl(jobUUID, video.uuid)
40 }, 40 },
@@ -67,13 +67,13 @@ export class VideoEditionTranscodingJobHandler extends AbstractJobHandler<Create
67 }) 67 })
68 } 68 }
69 69
70 const privatePayload: RunnerJobVideoEditionTranscodingPrivatePayload = { 70 const privatePayload: RunnerJobVideoStudioTranscodingPrivatePayload = {
71 videoUUID: video.uuid, 71 videoUUID: video.uuid,
72 originalTasks: tasks 72 originalTasks: tasks
73 } 73 }
74 74
75 const job = await this.createRunnerJob({ 75 const job = await this.createRunnerJob({
76 type: 'video-edition-transcoding', 76 type: 'video-studio-transcoding',
77 jobUUID, 77 jobUUID,
78 payload, 78 payload,
79 privatePayload, 79 privatePayload,
@@ -103,10 +103,10 @@ export class VideoEditionTranscodingJobHandler extends AbstractJobHandler<Create
103 103
104 protected async specificComplete (options: { 104 protected async specificComplete (options: {
105 runnerJob: MRunnerJob 105 runnerJob: MRunnerJob
106 resultPayload: VideoEditionTranscodingSuccess 106 resultPayload: VideoStudioTranscodingSuccess
107 }) { 107 }) {
108 const { runnerJob, resultPayload } = options 108 const { runnerJob, resultPayload } = options
109 const privatePayload = runnerJob.privatePayload as RunnerJobVideoEditionTranscodingPrivatePayload 109 const privatePayload = runnerJob.privatePayload as RunnerJobVideoStudioTranscodingPrivatePayload
110 110
111 const video = await loadTranscodingRunnerVideo(runnerJob, this.lTags) 111 const video = await loadTranscodingRunnerVideo(runnerJob, this.lTags)
112 if (!video) { 112 if (!video) {
@@ -116,7 +116,7 @@ export class VideoEditionTranscodingJobHandler extends AbstractJobHandler<Create
116 116
117 const videoFilePath = resultPayload.videoFile as string 117 const videoFilePath = resultPayload.videoFile as string
118 118
119 await onVideoEditionEnded({ video, editionResultPath: videoFilePath, tasks: privatePayload.originalTasks }) 119 await onVideoStudioEnded({ video, editionResultPath: videoFilePath, tasks: privatePayload.originalTasks })
120 120
121 logger.info( 121 logger.info(
122 'Runner video edition transcoding job %s for %s ended.', 122 'Runner video edition transcoding job %s for %s ended.',
@@ -146,7 +146,7 @@ export class VideoEditionTranscodingJobHandler extends AbstractJobHandler<Create
146 }) { 146 }) {
147 const { runnerJob } = options 147 const { runnerJob } = options
148 148
149 const payload = runnerJob.privatePayload as RunnerJobVideoEditionTranscodingPrivatePayload 149 const payload = runnerJob.privatePayload as RunnerJobVideoStudioTranscodingPrivatePayload
150 await safeCleanupStudioTMPFiles(payload.originalTasks) 150 await safeCleanupStudioTMPFiles(payload.originalTasks)
151 151
152 const video = await loadTranscodingRunnerVideo(options.runnerJob, this.lTags) 152 const video = await loadTranscodingRunnerVideo(options.runnerJob, this.lTags)
diff --git a/server/lib/transcoding/default-transcoding-profiles.ts b/server/lib/transcoding/default-transcoding-profiles.ts
index 5251784ac..8f8fdd026 100644
--- a/server/lib/transcoding/default-transcoding-profiles.ts
+++ b/server/lib/transcoding/default-transcoding-profiles.ts
@@ -1,88 +1,7 @@
1 1
2import { logger } from '@server/helpers/logger' 2import { logger } from '@server/helpers/logger'
3import { getAverageBitrate, getMinLimitBitrate } from '@shared/core-utils' 3import { FFmpegCommandWrapper, getDefaultAvailableEncoders } from '@shared/ffmpeg'
4import { buildStreamSuffix, FFmpegCommandWrapper, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '@shared/ffmpeg' 4import { AvailableEncoders, EncoderOptionsBuilder } from '@shared/models'
5import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '@shared/models'
6import { canDoQuickAudioTranscode } from './transcoding-quick-transcode'
7
8/**
9 *
10 * Available encoders and profiles for the transcoding jobs
11 * These functions are used by ffmpeg-utils that will get the encoders and options depending on the chosen profile
12 *
13 * Resources:
14 * * https://slhck.info/video/2017/03/01/rate-control.html
15 * * https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
16 */
17
18// ---------------------------------------------------------------------------
19// Default builders
20// ---------------------------------------------------------------------------
21
22const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
23 const { fps, inputRatio, inputBitrate, resolution } = options
24
25 // TODO: remove in 4.2, fps is not optional anymore
26 if (!fps) return { outputOptions: [ ] }
27
28 const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
29
30 return {
31 outputOptions: [
32 ...getCommonOutputOptions(targetBitrate),
33
34 `-r ${fps}`
35 ]
36 }
37}
38
39const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
40 const { streamNum, fps, inputBitrate, inputRatio, resolution } = options
41
42 const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
43
44 return {
45 outputOptions: [
46 ...getCommonOutputOptions(targetBitrate, streamNum),
47
48 `${buildStreamSuffix('-r:v', streamNum)} ${fps}`,
49 `${buildStreamSuffix('-b:v', streamNum)} ${targetBitrate}`
50 ]
51 }
52}
53
54const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum, canCopyAudio }) => {
55 const probe = await ffprobePromise(input)
56
57 if (canCopyAudio && await canDoQuickAudioTranscode(input, probe)) {
58 logger.debug('Copy audio stream %s by AAC encoder.', input)
59 return { copy: true, outputOptions: [ ] }
60 }
61
62 const parsedAudio = await getAudioStream(input, probe)
63
64 // We try to reduce the ceiling bitrate by making rough matches of bitrates
65 // Of course this is far from perfect, but it might save some space in the end
66
67 const audioCodecName = parsedAudio.audioStream['codec_name']
68
69 const bitrate = getMaxAudioBitrate(audioCodecName, parsedAudio.bitrate)
70
71 logger.debug('Calculating audio bitrate of %s by AAC encoder.', input, { bitrate: parsedAudio.bitrate, audioCodecName })
72
73 // Force stereo as it causes some issues with HLS playback in Chrome
74 const base = [ '-channel_layout', 'stereo' ]
75
76 if (bitrate !== -1) {
77 return { outputOptions: base.concat([ buildStreamSuffix('-b:a', streamNum), bitrate + 'k' ]) }
78 }
79
80 return { outputOptions: base }
81}
82
83const defaultLibFDKAACVODOptionsBuilder: EncoderOptionsBuilder = ({ streamNum }) => {
84 return { outputOptions: [ buildStreamSuffix('-q:a', streamNum), '5' ] }
85}
86 5
87// --------------------------------------------------------------------------- 6// ---------------------------------------------------------------------------
88// Profile manager to get and change default profiles 7// Profile manager to get and change default profiles
@@ -97,27 +16,7 @@ class VideoTranscodingProfilesManager {
97 live: this.buildDefaultEncodersPriorities() 16 live: this.buildDefaultEncodersPriorities()
98 } 17 }
99 18
100 private readonly availableEncoders = { 19 private readonly availableEncoders = getDefaultAvailableEncoders()
101 vod: {
102 libx264: {
103 default: defaultX264VODOptionsBuilder
104 },
105 aac: {
106 default: defaultAACOptionsBuilder
107 },
108 libfdk_aac: {
109 default: defaultLibFDKAACVODOptionsBuilder
110 }
111 },
112 live: {
113 libx264: {
114 default: defaultX264LiveOptionsBuilder
115 },
116 aac: {
117 default: defaultAACOptionsBuilder
118 }
119 }
120 }
121 20
122 private availableProfiles = { 21 private availableProfiles = {
123 vod: [] as string[], 22 vod: [] as string[],
@@ -242,41 +141,3 @@ class VideoTranscodingProfilesManager {
242export { 141export {
243 VideoTranscodingProfilesManager 142 VideoTranscodingProfilesManager
244} 143}
245
246// ---------------------------------------------------------------------------
247
248function getTargetBitrate (options: {
249 inputBitrate: number
250 resolution: VideoResolution
251 ratio: number
252 fps: number
253}) {
254 const { inputBitrate, resolution, ratio, fps } = options
255
256 const capped = capBitrate(inputBitrate, getAverageBitrate({ resolution, fps, ratio }))
257 const limit = getMinLimitBitrate({ resolution, fps, ratio })
258
259 return Math.max(limit, capped)
260}
261
262function capBitrate (inputBitrate: number, targetBitrate: number) {
263 if (!inputBitrate) return targetBitrate
264
265 // Add 30% margin to input bitrate
266 const inputBitrateWithMargin = inputBitrate + (inputBitrate * 0.3)
267
268 return Math.min(targetBitrate, inputBitrateWithMargin)
269}
270
271function getCommonOutputOptions (targetBitrate: number, streamNum?: number) {
272 return [
273 `-preset veryfast`,
274 `${buildStreamSuffix('-maxrate:v', streamNum)} ${targetBitrate}`,
275 `${buildStreamSuffix('-bufsize:v', streamNum)} ${targetBitrate * 2}`,
276
277 // NOTE: b-strategy 1 - heuristic algorithm, 16 is optimal B-frames for it
278 `-b_strategy 1`,
279 // NOTE: Why 16: https://github.com/Chocobozzz/PeerTube/pull/774. b-strategy 2 -> B-frames<16
280 `-bf 16`
281 ]
282}
diff --git a/server/lib/video-studio.ts b/server/lib/video-studio.ts
index 2c993faeb..0d3db8f60 100644
--- a/server/lib/video-studio.ts
+++ b/server/lib/video-studio.ts
@@ -9,13 +9,13 @@ import { getVideoStreamDuration } from '@shared/ffmpeg'
9import { VideoStudioEditionPayload, VideoStudioTask, VideoStudioTaskPayload } from '@shared/models' 9import { VideoStudioEditionPayload, VideoStudioTask, VideoStudioTaskPayload } from '@shared/models'
10import { federateVideoIfNeeded } from './activitypub/videos' 10import { federateVideoIfNeeded } from './activitypub/videos'
11import { JobQueue } from './job-queue' 11import { JobQueue } from './job-queue'
12import { VideoEditionTranscodingJobHandler } from './runners' 12import { VideoStudioTranscodingJobHandler } from './runners'
13import { createOptimizeOrMergeAudioJobs } from './transcoding/create-transcoding-job' 13import { createOptimizeOrMergeAudioJobs } from './transcoding/create-transcoding-job'
14import { getTranscodingJobPriority } from './transcoding/transcoding-priority' 14import { getTranscodingJobPriority } from './transcoding/transcoding-priority'
15import { buildNewFile, removeHLSPlaylist, removeWebTorrentFile } from './video-file' 15import { buildNewFile, removeHLSPlaylist, removeWebTorrentFile } from './video-file'
16import { VideoPathManager } from './video-path-manager' 16import { VideoPathManager } from './video-path-manager'
17 17
18const lTags = loggerTagsFactory('video-edition') 18const lTags = loggerTagsFactory('video-studio')
19 19
20export function buildTaskFileFieldname (indice: number, fieldName = 'file') { 20export function buildTaskFileFieldname (indice: number, fieldName = 'file') {
21 return `tasks[${indice}][options][${fieldName}]` 21 return `tasks[${indice}][options][${fieldName}]`
@@ -78,14 +78,14 @@ export async function createVideoStudioJob (options: {
78 const priority = await getTranscodingJobPriority({ user, type: 'studio', fallback: 0 }) 78 const priority = await getTranscodingJobPriority({ user, type: 'studio', fallback: 0 })
79 79
80 if (CONFIG.VIDEO_STUDIO.REMOTE_RUNNERS.ENABLED) { 80 if (CONFIG.VIDEO_STUDIO.REMOTE_RUNNERS.ENABLED) {
81 await new VideoEditionTranscodingJobHandler().create({ video, tasks: payload.tasks, priority }) 81 await new VideoStudioTranscodingJobHandler().create({ video, tasks: payload.tasks, priority })
82 return 82 return
83 } 83 }
84 84
85 await JobQueue.Instance.createJob({ type: 'video-studio-edition', payload, priority }) 85 await JobQueue.Instance.createJob({ type: 'video-studio-edition', payload, priority })
86} 86}
87 87
88export async function onVideoEditionEnded (options: { 88export async function onVideoStudioEnded (options: {
89 editionResultPath: string 89 editionResultPath: string
90 tasks: VideoStudioTaskPayload[] 90 tasks: VideoStudioTaskPayload[]
91 video: MVideoFullLight 91 video: MVideoFullLight
diff --git a/server/middlewares/validators/runners/job-files.ts b/server/middlewares/validators/runners/job-files.ts
index e5afff0e5..57c27fcfe 100644
--- a/server/middlewares/validators/runners/job-files.ts
+++ b/server/middlewares/validators/runners/job-files.ts
@@ -2,7 +2,7 @@ import express from 'express'
2import { param } from 'express-validator' 2import { param } from 'express-validator'
3import { basename } from 'path' 3import { basename } from 'path'
4import { isSafeFilename } from '@server/helpers/custom-validators/misc' 4import { isSafeFilename } from '@server/helpers/custom-validators/misc'
5import { hasVideoStudioTaskFile, HttpStatusCode, RunnerJobVideoEditionTranscodingPayload } from '@shared/models' 5import { hasVideoStudioTaskFile, HttpStatusCode, RunnerJobStudioTranscodingPayload } from '@shared/models'
6import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from '../shared' 6import { areValidationErrors, doesVideoExist, isValidVideoIdParam } from '../shared'
7 7
8const tags = [ 'runner' ] 8const tags = [ 'runner' ]
@@ -37,7 +37,7 @@ export const runnerJobGetVideoStudioTaskFileValidator = [
37 37
38 const filename = req.params.filename 38 const filename = req.params.filename
39 39
40 const payload = res.locals.runnerJob.payload as RunnerJobVideoEditionTranscodingPayload 40 const payload = res.locals.runnerJob.payload as RunnerJobStudioTranscodingPayload
41 41
42 const found = Array.isArray(payload?.tasks) && payload.tasks.some(t => { 42 const found = Array.isArray(payload?.tasks) && payload.tasks.some(t => {
43 if (hasVideoStudioTaskFile(t)) { 43 if (hasVideoStudioTaskFile(t)) {
diff --git a/server/tests/api/check-params/runners.ts b/server/tests/api/check-params/runners.ts
index 90a301392..cee1993e6 100644
--- a/server/tests/api/check-params/runners.ts
+++ b/server/tests/api/check-params/runners.ts
@@ -8,7 +8,7 @@ import {
8 RunnerJobState, 8 RunnerJobState,
9 RunnerJobSuccessPayload, 9 RunnerJobSuccessPayload,
10 RunnerJobUpdatePayload, 10 RunnerJobUpdatePayload,
11 RunnerJobVideoEditionTranscodingPayload, 11 RunnerJobStudioTranscodingPayload,
12 VideoPrivacy, 12 VideoPrivacy,
13 VideoStudioTaskIntro 13 VideoStudioTaskIntro
14} from '@shared/models' 14} from '@shared/models'
@@ -404,10 +404,10 @@ describe('Test managing runners', function () {
404 tasks: VideoStudioCommand.getComplexTask() 404 tasks: VideoStudioCommand.getComplexTask()
405 }) 405 })
406 406
407 const { job } = await server.runnerJobs.autoAccept({ runnerToken, type: 'video-edition-transcoding' }) 407 const { job } = await server.runnerJobs.autoAccept({ runnerToken, type: 'video-studio-transcoding' })
408 studioAcceptedJob = job 408 studioAcceptedJob = job
409 409
410 const tasks = (job.payload as RunnerJobVideoEditionTranscodingPayload).tasks 410 const tasks = (job.payload as RunnerJobStudioTranscodingPayload).tasks
411 const fileUrl = (tasks.find(t => isVideoStudioTaskIntro(t)) as VideoStudioTaskIntro).options.file as string 411 const fileUrl = (tasks.find(t => isVideoStudioTaskIntro(t)) as VideoStudioTaskIntro).options.file as string
412 studioFile = basename(fileUrl) 412 studioFile = basename(fileUrl)
413 } 413 }
@@ -787,7 +787,7 @@ describe('Test managing runners', function () {
787 787
788 describe('Video studio', function () { 788 describe('Video studio', function () {
789 789
790 it('Should fail with an invalid video edition transcoding payload', async function () { 790 it('Should fail with an invalid video studio transcoding payload', async function () {
791 await server.runnerJobs.success({ 791 await server.runnerJobs.success({
792 jobUUID: studioAcceptedJob.uuid, 792 jobUUID: studioAcceptedJob.uuid,
793 jobToken: studioAcceptedJob.jobToken, 793 jobToken: studioAcceptedJob.jobToken,
@@ -849,7 +849,7 @@ describe('Test managing runners', function () {
849 }) 849 })
850 }) 850 })
851 851
852 describe('Video edition tasks file routes', function () { 852 describe('Video studio tasks file routes', function () {
853 853
854 it('Should fail with an invalid studio filename', async function () { 854 it('Should fail with an invalid studio filename', async function () {
855 await fetchStudioFiles({ 855 await fetchStudioFiles({
diff --git a/server/tests/api/runners/runner-studio-transcoding.ts b/server/tests/api/runners/runner-studio-transcoding.ts
index 9ae629be6..41c556775 100644
--- a/server/tests/api/runners/runner-studio-transcoding.ts
+++ b/server/tests/api/runners/runner-studio-transcoding.ts
@@ -5,8 +5,8 @@ import { readFile } from 'fs-extra'
5import { checkPersistentTmpIsEmpty, checkVideoDuration } from '@server/tests/shared' 5import { checkPersistentTmpIsEmpty, checkVideoDuration } from '@server/tests/shared'
6import { buildAbsoluteFixturePath } from '@shared/core-utils' 6import { buildAbsoluteFixturePath } from '@shared/core-utils'
7import { 7import {
8 RunnerJobVideoEditionTranscodingPayload, 8 RunnerJobStudioTranscodingPayload,
9 VideoEditionTranscodingSuccess, 9 VideoStudioTranscodingSuccess,
10 VideoState, 10 VideoState,
11 VideoStudioTask, 11 VideoStudioTask,
12 VideoStudioTaskIntro 12 VideoStudioTaskIntro
@@ -121,10 +121,10 @@ describe('Test runner video studio transcoding', function () {
121 await checkVideoDuration(server, videoUUID, 5) 121 await checkVideoDuration(server, videoUUID, 5)
122 } 122 }
123 123
124 const { job } = await servers[0].runnerJobs.accept<RunnerJobVideoEditionTranscodingPayload>({ runnerToken, jobUUID }) 124 const { job } = await servers[0].runnerJobs.accept<RunnerJobStudioTranscodingPayload>({ runnerToken, jobUUID })
125 const jobToken = job.jobToken 125 const jobToken = job.jobToken
126 126
127 expect(job.type === 'video-edition-transcoding') 127 expect(job.type === 'video-studio-transcoding')
128 expect(job.payload.input.videoFileUrl).to.exist 128 expect(job.payload.input.videoFileUrl).to.exist
129 129
130 // Check video input file 130 // Check video input file
@@ -150,7 +150,7 @@ describe('Test runner video studio transcoding', function () {
150 expect(body).to.deep.equal(inputFile) 150 expect(body).to.deep.equal(inputFile)
151 } 151 }
152 152
153 const payload: VideoEditionTranscodingSuccess = { videoFile: 'video_very_short_240p.mp4' } 153 const payload: VideoStudioTranscodingSuccess = { videoFile: 'video_very_short_240p.mp4' }
154 await servers[0].runnerJobs.success({ runnerToken, jobUUID, jobToken, payload }) 154 await servers[0].runnerJobs.success({ runnerToken, jobUUID, jobToken, payload })
155 155
156 await waitJobs(servers) 156 await waitJobs(servers)
diff --git a/server/tests/api/transcoding/video-studio.ts b/server/tests/api/transcoding/video-studio.ts
index 2f64ef6bd..d22cfff4a 100644
--- a/server/tests/api/transcoding/video-studio.ts
+++ b/server/tests/api/transcoding/video-studio.ts
@@ -270,7 +270,7 @@ describe('Test video studio', function () {
270 }) 270 })
271 }) 271 })
272 272
273 describe('HLS only video edition', function () { 273 describe('HLS only studio edition', function () {
274 274
275 before(async function () { 275 before(async function () {
276 // Disable webtorrent 276 // Disable webtorrent
@@ -300,7 +300,7 @@ describe('Test video studio', function () {
300 }) 300 })
301 }) 301 })
302 302
303 describe('Object storage video edition', function () { 303 describe('Object storage studio edition', function () {
304 if (areMockObjectStorageTestsDisabled()) return 304 if (areMockObjectStorageTestsDisabled()) return
305 305
306 before(async function () { 306 before(async function () {
diff --git a/packages/peertube-runner/server/process/shared/transcoding-profiles.ts b/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts
index 492d17d6a..f7fc49465 100644
--- a/packages/peertube-runner/server/process/shared/transcoding-profiles.ts
+++ b/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts
@@ -57,7 +57,7 @@ const defaultLibFDKAACVODOptionsBuilder: EncoderOptionsBuilder = ({ streamNum })
57 return { outputOptions: [ buildStreamSuffix('-q:a', streamNum), '5' ] } 57 return { outputOptions: [ buildStreamSuffix('-q:a', streamNum), '5' ] }
58} 58}
59 59
60export function getAvailableEncoders () { 60export function getDefaultAvailableEncoders () {
61 return { 61 return {
62 vod: { 62 vod: {
63 libx264: { 63 libx264: {
@@ -81,7 +81,7 @@ export function getAvailableEncoders () {
81 } 81 }
82} 82}
83 83
84export function getEncodersToTry () { 84export function getDefaultEncodersToTry () {
85 return { 85 return {
86 vod: { 86 vod: {
87 video: [ 'libx264' ], 87 video: [ 'libx264' ],
diff --git a/shared/ffmpeg/index.ts b/shared/ffmpeg/index.ts
index 07a7d5402..1dab292da 100644
--- a/shared/ffmpeg/index.ts
+++ b/shared/ffmpeg/index.ts
@@ -1,4 +1,5 @@
1export * from './ffmpeg-command-wrapper' 1export * from './ffmpeg-command-wrapper'
2export * from './ffmpeg-default-transcoding-profile'
2export * from './ffmpeg-edition' 3export * from './ffmpeg-edition'
3export * from './ffmpeg-images' 4export * from './ffmpeg-images'
4export * from './ffmpeg-live' 5export * from './ffmpeg-live'
diff --git a/shared/models/runners/runner-job-payload.model.ts b/shared/models/runners/runner-job-payload.model.ts
index 9f0db0dc4..3dda6c51f 100644
--- a/shared/models/runners/runner-job-payload.model.ts
+++ b/shared/models/runners/runner-job-payload.model.ts
@@ -8,7 +8,7 @@ export type RunnerJobVODPayload =
8export type RunnerJobPayload = 8export type RunnerJobPayload =
9 RunnerJobVODPayload | 9 RunnerJobVODPayload |
10 RunnerJobLiveRTMPHLSTranscodingPayload | 10 RunnerJobLiveRTMPHLSTranscodingPayload |
11 RunnerJobVideoEditionTranscodingPayload 11 RunnerJobStudioTranscodingPayload
12 12
13// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
14 14
@@ -46,7 +46,7 @@ export interface RunnerJobVODAudioMergeTranscodingPayload {
46 } 46 }
47} 47}
48 48
49export interface RunnerJobVideoEditionTranscodingPayload { 49export interface RunnerJobStudioTranscodingPayload {
50 input: { 50 input: {
51 videoFileUrl: string 51 videoFileUrl: string
52 } 52 }
diff --git a/shared/models/runners/runner-job-private-payload.model.ts b/shared/models/runners/runner-job-private-payload.model.ts
index c8fe0a7d8..32b837de4 100644
--- a/shared/models/runners/runner-job-private-payload.model.ts
+++ b/shared/models/runners/runner-job-private-payload.model.ts
@@ -8,7 +8,7 @@ export type RunnerJobVODPrivatePayload =
8export type RunnerJobPrivatePayload = 8export type RunnerJobPrivatePayload =
9 RunnerJobVODPrivatePayload | 9 RunnerJobVODPrivatePayload |
10 RunnerJobLiveRTMPHLSTranscodingPrivatePayload | 10 RunnerJobLiveRTMPHLSTranscodingPrivatePayload |
11 RunnerJobVideoEditionTranscodingPrivatePayload 11 RunnerJobVideoStudioTranscodingPrivatePayload
12 12
13// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
14 14
@@ -38,7 +38,7 @@ export interface RunnerJobLiveRTMPHLSTranscodingPrivatePayload {
38 38
39// --------------------------------------------------------------------------- 39// ---------------------------------------------------------------------------
40 40
41export interface RunnerJobVideoEditionTranscodingPrivatePayload { 41export interface RunnerJobVideoStudioTranscodingPrivatePayload {
42 videoUUID: string 42 videoUUID: string
43 originalTasks: VideoStudioTaskPayload[] 43 originalTasks: VideoStudioTaskPayload[]
44} 44}
diff --git a/shared/models/runners/runner-job-success-body.model.ts b/shared/models/runners/runner-job-success-body.model.ts
index 17e921f69..f45336b05 100644
--- a/shared/models/runners/runner-job-success-body.model.ts
+++ b/shared/models/runners/runner-job-success-body.model.ts
@@ -12,7 +12,7 @@ export type RunnerJobSuccessPayload =
12 VODHLSTranscodingSuccess | 12 VODHLSTranscodingSuccess |
13 VODAudioMergeTranscodingSuccess | 13 VODAudioMergeTranscodingSuccess |
14 LiveRTMPHLSTranscodingSuccess | 14 LiveRTMPHLSTranscodingSuccess |
15 VideoEditionTranscodingSuccess 15 VideoStudioTranscodingSuccess
16 16
17export interface VODWebVideoTranscodingSuccess { 17export interface VODWebVideoTranscodingSuccess {
18 videoFile: Blob | string 18 videoFile: Blob | string
@@ -31,7 +31,7 @@ export interface LiveRTMPHLSTranscodingSuccess {
31 31
32} 32}
33 33
34export interface VideoEditionTranscodingSuccess { 34export interface VideoStudioTranscodingSuccess {
35 videoFile: Blob | string 35 videoFile: Blob | string
36} 36}
37 37
diff --git a/shared/models/runners/runner-job-type.type.ts b/shared/models/runners/runner-job-type.type.ts
index 3b997cb6e..91b92a729 100644
--- a/shared/models/runners/runner-job-type.type.ts
+++ b/shared/models/runners/runner-job-type.type.ts
@@ -3,4 +3,4 @@ export type RunnerJobType =
3 'vod-hls-transcoding' | 3 'vod-hls-transcoding' |
4 'vod-audio-merge-transcoding' | 4 'vod-audio-merge-transcoding' |
5 'live-rtmp-hls-transcoding' | 5 'live-rtmp-hls-transcoding' |
6 'video-edition-transcoding' 6 'video-studio-transcoding'