aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/job-queue/handlers
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-05-04 15:29:34 +0200
committerChocobozzz <chocobozzz@cpy.re>2023-05-09 08:57:34 +0200
commit5e47f6ab984a7d00782e4c7030afffa1ba480add (patch)
tree1ce586b591a8d71acbc301eba29b9a5e6490439e /server/lib/job-queue/handlers
parent6a4905602636afd6650c9e6f4d0fcc2105d91100 (diff)
downloadPeerTube-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.ts79
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 @@
1import { Job } from 'bullmq' 1import { Job } from 'bullmq'
2import { move, remove } from 'fs-extra' 2import { remove } from 'fs-extra'
3import { join } from 'path' 3import { join } from 'path'
4import { getFFmpegCommandWrapperOptions } from '@server/helpers/ffmpeg' 4import { getFFmpegCommandWrapperOptions } from '@server/helpers/ffmpeg'
5import { createTorrentAndSetInfoHashFromPath } from '@server/helpers/webtorrent'
6import { CONFIG } from '@server/initializers/config' 5import { CONFIG } from '@server/initializers/config'
7import { VIDEO_FILTERS } from '@server/initializers/constants'
8import { federateVideoIfNeeded } from '@server/lib/activitypub/videos'
9import { generateWebTorrentVideoFilename } from '@server/lib/paths'
10import { createOptimizeOrMergeAudioJobs } from '@server/lib/transcoding/create-transcoding-job'
11import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles' 6import { VideoTranscodingProfilesManager } from '@server/lib/transcoding/default-transcoding-profiles'
12import { isAbleToUploadVideo } from '@server/lib/user' 7import { isAbleToUploadVideo } from '@server/lib/user'
13import { buildFileMetadata, removeHLSPlaylist, removeWebTorrentFile } from '@server/lib/video-file'
14import { VideoPathManager } from '@server/lib/video-path-manager' 8import { VideoPathManager } from '@server/lib/video-path-manager'
15import { approximateIntroOutroAdditionalSize, safeCleanupStudioTMPFiles } from '@server/lib/video-studio' 9import { approximateIntroOutroAdditionalSize, onVideoEditionEnded, safeCleanupStudioTMPFiles } from '@server/lib/video-studio'
16import { UserModel } from '@server/models/user/user' 10import { UserModel } from '@server/models/user/user'
17import { VideoModel } from '@server/models/video/video' 11import { VideoModel } from '@server/models/video/video'
18import { VideoFileModel } from '@server/models/video/video-file' 12import { MVideo, MVideoFullLight } from '@server/types/models'
19import { MVideo, MVideoFile, MVideoFullLight, MVideoId, MVideoWithAllFiles } from '@server/types/models' 13import { pick } from '@shared/core-utils'
20import { getLowercaseExtension, pick } from '@shared/core-utils' 14import { buildUUID } from '@shared/extra-utils'
21import { buildUUID, getFileSize } from '@shared/extra-utils' 15import { FFmpegEdition } from '@shared/ffmpeg'
22import { FFmpegEdition, ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamDuration, getVideoStreamFPS } from '@shared/ffmpeg'
23import { 16import {
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
193async 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
212async 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
222async function checkUserQuotaOrThrow (video: MVideoFullLight, payload: VideoStudioEditionPayload) { 167async function checkUserQuotaOrThrow (video: MVideoFullLight, payload: VideoStudioEditionPayload) {
223 const user = await UserModel.loadByVideoId(video.id) 168 const user = await UserModel.loadByVideoId(video.id)
224 169