]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blame - server/lib/job-queue/handlers/video-transcoding.ts
Add expect message to ease debug
[github/Chocobozzz/PeerTube.git] / server / lib / job-queue / handlers / video-transcoding.ts
CommitLineData
5a921e7b 1import { Job } from 'bullmq'
0c9668f7
C
2import { onTranscodingEnded } from '@server/lib/transcoding/ended-transcoding'
3import { generateHlsPlaylistResolution } from '@server/lib/transcoding/hls-transcoding'
4import { mergeAudioVideofile, optimizeOriginalVideofile, transcodeNewWebTorrentResolution } from '@server/lib/transcoding/web-transcoding'
5import { removeAllWebTorrentFiles } from '@server/lib/video-file'
0305db28 6import { VideoPathManager } from '@server/lib/video-path-manager'
0c9668f7 7import { moveToFailedTranscodingState } from '@server/lib/video-state'
7d9ba5c0 8import { UserModel } from '@server/models/user/user'
0305db28 9import { VideoJobInfoModel } from '@server/models/video/video-job-info'
0c9668f7 10import { MUser, MUserId, MVideoFullLight } from '@server/types/models'
8dc8a34e 11import {
24516aa2 12 HLSTranscodingPayload,
8dc8a34e 13 MergeAudioTranscodingPayload,
0f11ec8d 14 NewWebTorrentResolutionTranscodingPayload,
8dc8a34e
C
15 OptimizeTranscodingPayload,
16 VideoTranscodingPayload
d17c7b4e 17} from '@shared/models'
5a298a5a 18import { logger, loggerTagsFactory } from '../../../helpers/logger'
3fd3ab2d 19import { VideoModel } from '../../../models/video/video'
24516aa2 20
41fb13c3 21type HandlerFunction = (job: Job, payload: VideoTranscodingPayload, video: MVideoFullLight, user: MUser) => Promise<void>
77d7e851 22
e83d06a7 23const handlers: { [ id in VideoTranscodingPayload['type'] ]: HandlerFunction } = {
24516aa2 24 'new-resolution-to-hls': handleHLSJob,
24516aa2 25 'new-resolution-to-webtorrent': handleNewWebTorrentResolutionJob,
24516aa2 26 'merge-audio-to-webtorrent': handleWebTorrentMergeAudioJob,
24516aa2
C
27 'optimize-to-webtorrent': handleWebTorrentOptimizeJob
28}
40298b02 29
5a298a5a
C
30const lTags = loggerTagsFactory('transcoding')
31
41fb13c3 32async function processVideoTranscoding (job: Job) {
a0327eed 33 const payload = job.data as VideoTranscodingPayload
51335c72 34 logger.info('Processing transcoding job %s.', job.id, lTags(payload.videoUUID))
94a5ff8a 35
4fae2b1f 36 const video = await VideoModel.loadFull(payload.videoUUID)
f5028693
C
37 // No video, maybe deleted?
38 if (!video) {
5a298a5a 39 logger.info('Do not process job %d, video does not exist.', job.id, lTags(payload.videoUUID))
f5028693
C
40 return undefined
41 }
42
77d7e851
C
43 const user = await UserModel.loadByChannelActorId(video.VideoChannel.actorId)
44
24516aa2 45 const handler = handlers[payload.type]
b5b68755 46
24516aa2 47 if (!handler) {
221ee1ad 48 await moveToFailedTranscodingState(video)
025d858e 49 await VideoJobInfoModel.decrease(video.uuid, 'pendingTranscode')
221ee1ad 50
24516aa2
C
51 throw new Error('Cannot find transcoding handler for ' + payload.type)
52 }
b5b68755 53
4e29f4fe 54 try {
55 await handler(job, payload, video, user)
56 } catch (error) {
221ee1ad 57 await moveToFailedTranscodingState(video)
4e29f4fe 58
025d858e
C
59 await VideoJobInfoModel.decrease(video.uuid, 'pendingTranscode')
60
4e29f4fe 61 throw error
62 }
24516aa2
C
63
64 return video
65}
09209296 66
025d858e
C
67// ---------------------------------------------------------------------------
68
69export {
70 processVideoTranscoding
71}
72
24516aa2
C
73// ---------------------------------------------------------------------------
74// Job handlers
75// ---------------------------------------------------------------------------
2186386c 76
41fb13c3 77async function handleWebTorrentMergeAudioJob (job: Job, payload: MergeAudioTranscodingPayload, video: MVideoFullLight, user: MUserId) {
5a298a5a
C
78 logger.info('Handling merge audio transcoding job for %s.', video.uuid, lTags(video.uuid))
79
0c9668f7 80 await mergeAudioVideofile({ video, resolution: payload.resolution, fps: payload.fps, job })
24516aa2 81
5a298a5a
C
82 logger.info('Merge audio transcoding job for %s ended.', video.uuid, lTags(video.uuid))
83
cc2abbc3 84 await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: !payload.hasChildren, video })
40298b02
C
85}
86
41fb13c3 87async function handleWebTorrentOptimizeJob (job: Job, payload: OptimizeTranscodingPayload, video: MVideoFullLight, user: MUserId) {
5a298a5a
C
88 logger.info('Handling optimize transcoding job for %s.', video.uuid, lTags(video.uuid))
89
0c9668f7 90 await optimizeOriginalVideofile({ video, inputVideoFile: video.getMaxQualityFile(), quickTranscode: payload.quickTranscode, job })
24516aa2 91
5a298a5a
C
92 logger.info('Optimize transcoding job for %s ended.', video.uuid, lTags(video.uuid))
93
cc2abbc3 94 await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: !payload.hasChildren, video })
24516aa2
C
95}
96
cc2abbc3
C
97// ---------------------------------------------------------------------------
98
0c9668f7
C
99async function handleNewWebTorrentResolutionJob (job: Job, payload: NewWebTorrentResolutionTranscodingPayload, video: MVideoFullLight) {
100 logger.info('Handling WebTorrent transcoding job for %s.', video.uuid, lTags(video.uuid))
e8d246d5 101
0c9668f7 102 await transcodeNewWebTorrentResolution({ video, resolution: payload.resolution, fps: payload.fps, job })
3545e72c 103
0c9668f7 104 logger.info('WebTorrent transcoding job for %s ended.', video.uuid, lTags(video.uuid))
3545e72c 105
0c9668f7 106 await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: true, video })
40298b02
C
107}
108
cc2abbc3 109// ---------------------------------------------------------------------------
24516aa2 110
cc2abbc3
C
111async function handleHLSJob (job: Job, payload: HLSTranscodingPayload, videoArg: MVideoFullLight) {
112 logger.info('Handling HLS transcoding job for %s.', videoArg.uuid, lTags(videoArg.uuid))
025d858e 113
cc2abbc3
C
114 const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(videoArg.uuid)
115 let video: MVideoFullLight
09209296 116
0c9668f7 117 try {
cc2abbc3
C
118 video = await VideoModel.loadFull(videoArg.uuid)
119
120 const videoFileInput = payload.copyCodecs
121 ? video.getWebTorrentFile(payload.resolution)
122 : video.getMaxQualityFile()
123
124 const videoOrStreamingPlaylist = videoFileInput.getVideoOrStreamingPlaylist()
cbe2f36d 125
0c9668f7
C
126 await VideoPathManager.Instance.makeAvailableVideoFile(videoFileInput.withVideoOrPlaylist(videoOrStreamingPlaylist), videoInputPath => {
127 return generateHlsPlaylistResolution({
128 video,
129 videoInputPath,
130 inputFileMutexReleaser,
131 resolution: payload.resolution,
132 fps: payload.fps,
133 copyCodecs: payload.copyCodecs,
134 job
135 })
136 })
137 } finally {
138 inputFileMutexReleaser()
09209296 139 }
77d7e851 140
0c9668f7 141 logger.info('HLS transcoding job for %s ended.', video.uuid, lTags(video.uuid))
24516aa2 142
0c9668f7
C
143 if (payload.deleteWebTorrentFiles === true) {
144 logger.info('Removing WebTorrent files of %s now we have a HLS version of it.', video.uuid, lTags(video.uuid))
70243d7a 145
0c9668f7 146 await removeAllWebTorrentFiles(video)
70243d7a
C
147 }
148
0c9668f7 149 await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: true, video })
24516aa2 150}