diff options
author | Chocobozzz <me@florianbigard.com> | 2023-05-04 15:29:34 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2023-05-09 08:57:34 +0200 |
commit | 5e47f6ab984a7d00782e4c7030afffa1ba480add (patch) | |
tree | 1ce586b591a8d71acbc301eba29b9a5e6490439e /server/lib/job-queue/handlers | |
parent | 6a4905602636afd6650c9e6f4d0fcc2105d91100 (diff) | |
download | PeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.tar.gz PeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.tar.zst PeerTube-5e47f6ab984a7d00782e4c7030afffa1ba480add.zip |
Support studio transcoding in peertube runner
Diffstat (limited to 'server/lib/job-queue/handlers')
-rw-r--r-- | server/lib/job-queue/handlers/video-studio-edition.ts | 79 |
1 files changed, 12 insertions, 67 deletions
diff --git a/server/lib/job-queue/handlers/video-studio-edition.ts b/server/lib/job-queue/handlers/video-studio-edition.ts index 5e8dd4f51..df73caf72 100644 --- a/server/lib/job-queue/handlers/video-studio-edition.ts +++ b/server/lib/job-queue/handlers/video-studio-edition.ts | |||
@@ -1,25 +1,18 @@ | |||
1 | import { Job } from 'bullmq' | 1 | import { Job } from 'bullmq' |
2 | import { move, remove } from 'fs-extra' | 2 | import { remove } from 'fs-extra' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { getFFmpegCommandWrapperOptions } from '@server/helpers/ffmpeg' | 4 | import { getFFmpegCommandWrapperOptions } from '@server/helpers/ffmpeg' |
5 | import { createTorrentAndSetInfoHashFromPath } from '@server/helpers/webtorrent' | ||
6 | import { CONFIG } from '@server/initializers/config' | 5 | import { CONFIG } from '@server/initializers/config' |
7 | import { VIDEO_FILTERS } from '@server/initializers/constants' | ||
8 | import { federateVideoIfNeeded } from '@server/lib/activitypub/videos' | ||
9 | import { generateWebTorrentVideoFilename } from '@server/lib/paths' | ||
10 | import { createOptimizeOrMergeAudioJobs } from '@server/lib/transcoding/create-transcoding-job' | ||
11 | import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles' | 6 | import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles' |
12 | import { isAbleToUploadVideo } from '@server/lib/user' | 7 | import { isAbleToUploadVideo } from '@server/lib/user' |
13 | import { buildFileMetadata, removeHLSPlaylist, removeWebTorrentFile } from '@server/lib/video-file' | ||
14 | import { VideoPathManager } from '@server/lib/video-path-manager' | 8 | import { VideoPathManager } from '@server/lib/video-path-manager' |
15 | import { approximateIntroOutroAdditionalSize, safeCleanupStudioTMPFiles } from '@server/lib/video-studio' | 9 | import { approximateIntroOutroAdditionalSize, onVideoEditionEnded, safeCleanupStudioTMPFiles } from '@server/lib/video-studio' |
16 | import { UserModel } from '@server/models/user/user' | 10 | import { UserModel } from '@server/models/user/user' |
17 | import { VideoModel } from '@server/models/video/video' | 11 | import { VideoModel } from '@server/models/video/video' |
18 | import { VideoFileModel } from '@server/models/video/video-file' | 12 | import { MVideo, MVideoFullLight } from '@server/types/models' |
19 | import { MVideo, MVideoFile, MVideoFullLight, MVideoId, MVideoWithAllFiles } from '@server/types/models' | 13 | import { pick } from '@shared/core-utils' |
20 | import { getLowercaseExtension, pick } from '@shared/core-utils' | 14 | import { buildUUID } from '@shared/extra-utils' |
21 | import { buildUUID, getFileSize } from '@shared/extra-utils' | 15 | import { FFmpegEdition } from '@shared/ffmpeg' |
22 | import { FFmpegEdition, ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamDuration, getVideoStreamFPS } from '@shared/ffmpeg' | ||
23 | import { | 16 | import { |
24 | VideoStudioEditionPayload, | 17 | VideoStudioEditionPayload, |
25 | VideoStudioTask, | 18 | VideoStudioTask, |
@@ -46,7 +39,7 @@ async function processVideoStudioEdition (job: Job) { | |||
46 | if (!video) { | 39 | if (!video) { |
47 | logger.info('Can\'t process job %d, video does not exist.', job.id, lTags) | 40 | logger.info('Can\'t process job %d, video does not exist.', job.id, lTags) |
48 | 41 | ||
49 | await safeCleanupStudioTMPFiles(payload) | 42 | await safeCleanupStudioTMPFiles(payload.tasks) |
50 | return undefined | 43 | return undefined |
51 | } | 44 | } |
52 | 45 | ||
@@ -81,28 +74,9 @@ async function processVideoStudioEdition (job: Job) { | |||
81 | 74 | ||
82 | logger.info('Video edition ended for video %s.', video.uuid, lTags) | 75 | logger.info('Video edition ended for video %s.', video.uuid, lTags) |
83 | 76 | ||
84 | const newFile = await buildNewFile(video, editionResultPath) | 77 | await onVideoEditionEnded({ video, editionResultPath, tasks: payload.tasks }) |
85 | |||
86 | const outputPath = VideoPathManager.Instance.getFSVideoFileOutputPath(video, newFile) | ||
87 | await move(editionResultPath, outputPath) | ||
88 | |||
89 | await safeCleanupStudioTMPFiles(payload) | ||
90 | |||
91 | await createTorrentAndSetInfoHashFromPath(video, newFile, outputPath) | ||
92 | await removeAllFiles(video, newFile) | ||
93 | |||
94 | await newFile.save() | ||
95 | |||
96 | video.duration = await getVideoStreamDuration(outputPath) | ||
97 | await video.save() | ||
98 | |||
99 | await federateVideoIfNeeded(video, false, undefined) | ||
100 | |||
101 | const user = await UserModel.loadByVideoId(video.id) | ||
102 | |||
103 | await createOptimizeOrMergeAudioJobs({ video, videoFile: newFile, isNewVideo: false, user, videoFileAlreadyLocked: false }) | ||
104 | } catch (err) { | 78 | } catch (err) { |
105 | await safeCleanupStudioTMPFiles(payload) | 79 | await safeCleanupStudioTMPFiles(payload.tasks) |
106 | 80 | ||
107 | throw err | 81 | throw err |
108 | } | 82 | } |
@@ -181,44 +155,15 @@ function processAddWatermark (options: TaskProcessorOptions<VideoStudioTaskWater | |||
181 | watermarkPath: task.options.file, | 155 | watermarkPath: task.options.file, |
182 | 156 | ||
183 | videoFilters: { | 157 | videoFilters: { |
184 | watermarkSizeRatio: VIDEO_FILTERS.WATERMARK.SIZE_RATIO, | 158 | watermarkSizeRatio: task.options.watermarkSizeRatio, |
185 | horitonzalMarginRatio: VIDEO_FILTERS.WATERMARK.HORIZONTAL_MARGIN_RATIO, | 159 | horitonzalMarginRatio: task.options.horitonzalMarginRatio, |
186 | verticalMarginRatio: VIDEO_FILTERS.WATERMARK.VERTICAL_MARGIN_RATIO | 160 | verticalMarginRatio: task.options.verticalMarginRatio |
187 | } | 161 | } |
188 | }) | 162 | }) |
189 | } | 163 | } |
190 | 164 | ||
191 | // --------------------------------------------------------------------------- | 165 | // --------------------------------------------------------------------------- |
192 | 166 | ||
193 | async function buildNewFile (video: MVideoId, path: string) { | ||
194 | const videoFile = new VideoFileModel({ | ||
195 | extname: getLowercaseExtension(path), | ||
196 | size: await getFileSize(path), | ||
197 | metadata: await buildFileMetadata(path), | ||
198 | videoStreamingPlaylistId: null, | ||
199 | videoId: video.id | ||
200 | }) | ||
201 | |||
202 | const probe = await ffprobePromise(path) | ||
203 | |||
204 | videoFile.fps = await getVideoStreamFPS(path, probe) | ||
205 | videoFile.resolution = (await getVideoStreamDimensionsInfo(path, probe)).resolution | ||
206 | |||
207 | videoFile.filename = generateWebTorrentVideoFilename(videoFile.resolution, videoFile.extname) | ||
208 | |||
209 | return videoFile | ||
210 | } | ||
211 | |||
212 | async function removeAllFiles (video: MVideoWithAllFiles, webTorrentFileException: MVideoFile) { | ||
213 | await removeHLSPlaylist(video) | ||
214 | |||
215 | for (const file of video.VideoFiles) { | ||
216 | if (file.id === webTorrentFileException.id) continue | ||
217 | |||
218 | await removeWebTorrentFile(video, file.id) | ||
219 | } | ||
220 | } | ||
221 | |||
222 | async function checkUserQuotaOrThrow (video: MVideoFullLight, payload: VideoStudioEditionPayload) { | 167 | async function checkUserQuotaOrThrow (video: MVideoFullLight, payload: VideoStudioEditionPayload) { |
223 | const user = await UserModel.loadByVideoId(video.id) | 168 | const user = await UserModel.loadByVideoId(video.id) |
224 | 169 | ||