diff options
Diffstat (limited to 'server/lib')
4 files changed, 38 insertions, 26 deletions
diff --git a/server/lib/job-queue/handlers/transcoding-job-builder.ts b/server/lib/job-queue/handlers/transcoding-job-builder.ts index 8b4a877d7..cb45337df 100644 --- a/server/lib/job-queue/handlers/transcoding-job-builder.ts +++ b/server/lib/job-queue/handlers/transcoding-job-builder.ts | |||
@@ -36,7 +36,7 @@ async function processTranscodingJobBuilder (job: Job) { | |||
36 | for (const sequentialJobs of (payload.sequentialJobs || [])) { | 36 | for (const sequentialJobs of (payload.sequentialJobs || [])) { |
37 | await JobQueue.Instance.createSequentialJobFlow(...sequentialJobs) | 37 | await JobQueue.Instance.createSequentialJobFlow(...sequentialJobs) |
38 | 38 | ||
39 | await VideoJobInfoModel.increaseOrCreate(payload.videoUUID, 'pendingTranscode', sequentialJobs.length) | 39 | await VideoJobInfoModel.increaseOrCreate(payload.videoUUID, 'pendingTranscode', sequentialJobs.filter(s => !!s).length) |
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
diff --git a/server/lib/job-queue/handlers/video-transcoding.ts b/server/lib/job-queue/handlers/video-transcoding.ts index 17b717275..39f078bf0 100644 --- a/server/lib/job-queue/handlers/video-transcoding.ts +++ b/server/lib/job-queue/handlers/video-transcoding.ts | |||
@@ -81,7 +81,7 @@ async function handleWebTorrentMergeAudioJob (job: Job, payload: MergeAudioTrans | |||
81 | 81 | ||
82 | logger.info('Merge audio transcoding job for %s ended.', video.uuid, lTags(video.uuid)) | 82 | logger.info('Merge audio transcoding job for %s ended.', video.uuid, lTags(video.uuid)) |
83 | 83 | ||
84 | await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: true, video }) | 84 | await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: !payload.hasChildren, video }) |
85 | } | 85 | } |
86 | 86 | ||
87 | async function handleWebTorrentOptimizeJob (job: Job, payload: OptimizeTranscodingPayload, video: MVideoFullLight, user: MUserId) { | 87 | async function handleWebTorrentOptimizeJob (job: Job, payload: OptimizeTranscodingPayload, video: MVideoFullLight, user: MUserId) { |
@@ -91,9 +91,11 @@ async function handleWebTorrentOptimizeJob (job: Job, payload: OptimizeTranscodi | |||
91 | 91 | ||
92 | logger.info('Optimize transcoding job for %s ended.', video.uuid, lTags(video.uuid)) | 92 | logger.info('Optimize transcoding job for %s ended.', video.uuid, lTags(video.uuid)) |
93 | 93 | ||
94 | await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: true, video }) | 94 | await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: !payload.hasChildren, video }) |
95 | } | 95 | } |
96 | 96 | ||
97 | // --------------------------------------------------------------------------- | ||
98 | |||
97 | async function handleNewWebTorrentResolutionJob (job: Job, payload: NewWebTorrentResolutionTranscodingPayload, video: MVideoFullLight) { | 99 | async function handleNewWebTorrentResolutionJob (job: Job, payload: NewWebTorrentResolutionTranscodingPayload, video: MVideoFullLight) { |
98 | logger.info('Handling WebTorrent transcoding job for %s.', video.uuid, lTags(video.uuid)) | 100 | logger.info('Handling WebTorrent transcoding job for %s.', video.uuid, lTags(video.uuid)) |
99 | 101 | ||
@@ -104,19 +106,22 @@ async function handleNewWebTorrentResolutionJob (job: Job, payload: NewWebTorren | |||
104 | await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: true, video }) | 106 | await onTranscodingEnded({ isNewVideo: payload.isNewVideo, moveVideoToNextState: true, video }) |
105 | } | 107 | } |
106 | 108 | ||
107 | async function handleHLSJob (job: Job, payload: HLSTranscodingPayload, video: MVideoFullLight) { | 109 | // --------------------------------------------------------------------------- |
108 | logger.info('Handling HLS transcoding job for %s.', video.uuid, lTags(video.uuid)) | ||
109 | |||
110 | const videoFileInput = payload.copyCodecs | ||
111 | ? video.getWebTorrentFile(payload.resolution) | ||
112 | : video.getMaxQualityFile() | ||
113 | 110 | ||
114 | const videoOrStreamingPlaylist = videoFileInput.getVideoOrStreamingPlaylist() | 111 | async function handleHLSJob (job: Job, payload: HLSTranscodingPayload, videoArg: MVideoFullLight) { |
112 | logger.info('Handling HLS transcoding job for %s.', videoArg.uuid, lTags(videoArg.uuid)) | ||
115 | 113 | ||
116 | const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) | 114 | const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(videoArg.uuid) |
115 | let video: MVideoFullLight | ||
117 | 116 | ||
118 | try { | 117 | try { |
119 | await videoFileInput.getVideo().reload() | 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() | ||
120 | 125 | ||
121 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFileInput.withVideoOrPlaylist(videoOrStreamingPlaylist), videoInputPath => { | 126 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFileInput.withVideoOrPlaylist(videoOrStreamingPlaylist), videoInputPath => { |
122 | return generateHlsPlaylistResolution({ | 127 | return generateHlsPlaylistResolution({ |
diff --git a/server/lib/transcoding/shared/job-builders/transcoding-job-queue-builder.ts b/server/lib/transcoding/shared/job-builders/transcoding-job-queue-builder.ts index 7c892718b..c09c6b8ce 100644 --- a/server/lib/transcoding/shared/job-builders/transcoding-job-queue-builder.ts +++ b/server/lib/transcoding/shared/job-builders/transcoding-job-queue-builder.ts | |||
@@ -76,9 +76,10 @@ export class TranscodingJobQueueBuilder extends AbstractJobBuilder { | |||
76 | 76 | ||
77 | nextTranscodingSequentialJobPayloads = [ ...nextTranscodingSequentialJobPayloads, ...lowerResolutionJobPayloads ] | 77 | nextTranscodingSequentialJobPayloads = [ ...nextTranscodingSequentialJobPayloads, ...lowerResolutionJobPayloads ] |
78 | 78 | ||
79 | const hasChildren = nextTranscodingSequentialJobPayloads.length !== 0 | ||
79 | mergeOrOptimizePayload = videoFile.isAudio() | 80 | mergeOrOptimizePayload = videoFile.isAudio() |
80 | ? this.buildMergeAudioPayload({ videoUUID: video.uuid, isNewVideo }) | 81 | ? this.buildMergeAudioPayload({ videoUUID: video.uuid, isNewVideo, hasChildren }) |
81 | : this.buildOptimizePayload({ videoUUID: video.uuid, isNewVideo, quickTranscode }) | 82 | : this.buildOptimizePayload({ videoUUID: video.uuid, isNewVideo, quickTranscode, hasChildren }) |
82 | }) | 83 | }) |
83 | } finally { | 84 | } finally { |
84 | mutexReleaser() | 85 | mutexReleaser() |
@@ -100,7 +101,9 @@ export class TranscodingJobQueueBuilder extends AbstractJobBuilder { | |||
100 | 101 | ||
101 | const mergeOrOptimizeJob = await this.buildTranscodingJob({ payload: mergeOrOptimizePayload, user }) | 102 | const mergeOrOptimizeJob = await this.buildTranscodingJob({ payload: mergeOrOptimizePayload, user }) |
102 | 103 | ||
103 | return JobQueue.Instance.createSequentialJobFlow(...[ mergeOrOptimizeJob, transcodingJobBuilderJob ]) | 104 | await JobQueue.Instance.createSequentialJobFlow(...[ mergeOrOptimizeJob, transcodingJobBuilderJob ]) |
105 | |||
106 | await VideoJobInfoModel.increaseOrCreate(video.uuid, 'pendingTranscode') | ||
104 | } | 107 | } |
105 | 108 | ||
106 | // --------------------------------------------------------------------------- | 109 | // --------------------------------------------------------------------------- |
@@ -279,15 +282,17 @@ export class TranscodingJobQueueBuilder extends AbstractJobBuilder { | |||
279 | private buildMergeAudioPayload (options: { | 282 | private buildMergeAudioPayload (options: { |
280 | videoUUID: string | 283 | videoUUID: string |
281 | isNewVideo: boolean | 284 | isNewVideo: boolean |
285 | hasChildren: boolean | ||
282 | }): MergeAudioTranscodingPayload { | 286 | }): MergeAudioTranscodingPayload { |
283 | const { videoUUID, isNewVideo } = options | 287 | const { videoUUID, isNewVideo, hasChildren } = options |
284 | 288 | ||
285 | return { | 289 | return { |
286 | type: 'merge-audio-to-webtorrent', | 290 | type: 'merge-audio-to-webtorrent', |
287 | resolution: DEFAULT_AUDIO_RESOLUTION, | 291 | resolution: DEFAULT_AUDIO_RESOLUTION, |
288 | fps: VIDEO_TRANSCODING_FPS.AUDIO_MERGE, | 292 | fps: VIDEO_TRANSCODING_FPS.AUDIO_MERGE, |
289 | videoUUID, | 293 | videoUUID, |
290 | isNewVideo | 294 | isNewVideo, |
295 | hasChildren | ||
291 | } | 296 | } |
292 | } | 297 | } |
293 | 298 | ||
@@ -295,13 +300,15 @@ export class TranscodingJobQueueBuilder extends AbstractJobBuilder { | |||
295 | videoUUID: string | 300 | videoUUID: string |
296 | quickTranscode: boolean | 301 | quickTranscode: boolean |
297 | isNewVideo: boolean | 302 | isNewVideo: boolean |
303 | hasChildren: boolean | ||
298 | }): OptimizeTranscodingPayload { | 304 | }): OptimizeTranscodingPayload { |
299 | const { videoUUID, quickTranscode, isNewVideo } = options | 305 | const { videoUUID, quickTranscode, isNewVideo, hasChildren } = options |
300 | 306 | ||
301 | return { | 307 | return { |
302 | type: 'optimize-to-webtorrent', | 308 | type: 'optimize-to-webtorrent', |
303 | videoUUID, | 309 | videoUUID, |
304 | isNewVideo, | 310 | isNewVideo, |
311 | hasChildren, | ||
305 | quickTranscode | 312 | quickTranscode |
306 | } | 313 | } |
307 | } | 314 | } |
diff --git a/server/lib/transcoding/web-transcoding.ts b/server/lib/transcoding/web-transcoding.ts index d43d03b2a..22bd238ae 100644 --- a/server/lib/transcoding/web-transcoding.ts +++ b/server/lib/transcoding/web-transcoding.ts | |||
@@ -14,6 +14,7 @@ import { buildFileMetadata } from '../video-file' | |||
14 | import { VideoPathManager } from '../video-path-manager' | 14 | import { VideoPathManager } from '../video-path-manager' |
15 | import { buildFFmpegVOD } from './shared' | 15 | import { buildFFmpegVOD } from './shared' |
16 | import { computeResolutionsToTranscode } from './transcoding-resolutions' | 16 | import { computeResolutionsToTranscode } from './transcoding-resolutions' |
17 | import { VideoModel } from '@server/models/video/video' | ||
17 | 18 | ||
18 | // Optimize the original video file and replace it. The resolution is not changed. | 19 | // Optimize the original video file and replace it. The resolution is not changed. |
19 | export async function optimizeOriginalVideofile (options: { | 20 | export async function optimizeOriginalVideofile (options: { |
@@ -32,6 +33,7 @@ export async function optimizeOriginalVideofile (options: { | |||
32 | 33 | ||
33 | try { | 34 | try { |
34 | await video.reload() | 35 | await video.reload() |
36 | await inputVideoFile.reload() | ||
35 | 37 | ||
36 | const fileWithVideoOrPlaylist = inputVideoFile.withVideoOrPlaylist(video) | 38 | const fileWithVideoOrPlaylist = inputVideoFile.withVideoOrPlaylist(video) |
37 | 39 | ||
@@ -88,16 +90,15 @@ export async function transcodeNewWebTorrentResolution (options: { | |||
88 | fps: number | 90 | fps: number |
89 | job: Job | 91 | job: Job |
90 | }) { | 92 | }) { |
91 | const { video, resolution, fps, job } = options | 93 | const { video: videoArg, resolution, fps, job } = options |
92 | 94 | ||
93 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR | 95 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR |
94 | const newExtname = '.mp4' | 96 | const newExtname = '.mp4' |
95 | 97 | ||
96 | const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) | 98 | const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(videoArg.uuid) |
97 | 99 | ||
98 | try { | 100 | try { |
99 | await video.reload() | 101 | const video = await VideoModel.loadFull(videoArg.uuid) |
100 | |||
101 | const file = video.getMaxQualityFile().withVideoOrPlaylist(video) | 102 | const file = video.getMaxQualityFile().withVideoOrPlaylist(video) |
102 | 103 | ||
103 | const result = await VideoPathManager.Instance.makeAvailableVideoFile(file, async videoInputPath => { | 104 | const result = await VideoPathManager.Instance.makeAvailableVideoFile(file, async videoInputPath => { |
@@ -141,16 +142,15 @@ export async function mergeAudioVideofile (options: { | |||
141 | fps: number | 142 | fps: number |
142 | job: Job | 143 | job: Job |
143 | }) { | 144 | }) { |
144 | const { video, resolution, fps, job } = options | 145 | const { video: videoArg, resolution, fps, job } = options |
145 | 146 | ||
146 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR | 147 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR |
147 | const newExtname = '.mp4' | 148 | const newExtname = '.mp4' |
148 | 149 | ||
149 | const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) | 150 | const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(videoArg.uuid) |
150 | 151 | ||
151 | try { | 152 | try { |
152 | await video.reload() | 153 | const video = await VideoModel.loadFull(videoArg.uuid) |
153 | |||
154 | const inputVideoFile = video.getMinQualityFile() | 154 | const inputVideoFile = video.getMinQualityFile() |
155 | 155 | ||
156 | const fileWithVideoOrPlaylist = inputVideoFile.withVideoOrPlaylist(video) | 156 | const fileWithVideoOrPlaylist = inputVideoFile.withVideoOrPlaylist(video) |