]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blob - packages/peertube-runner/server/process/shared/process-vod.ts
Support studio transcoding in peertube runner
[github/Chocobozzz/PeerTube.git] / packages / peertube-runner / server / process / shared / process-vod.ts
1 import { remove } from 'fs-extra'
2 import { join } from 'path'
3 import { buildUUID } from '@shared/extra-utils'
4 import {
5 RunnerJobVODAudioMergeTranscodingPayload,
6 RunnerJobVODHLSTranscodingPayload,
7 RunnerJobVODWebVideoTranscodingPayload,
8 VODAudioMergeTranscodingSuccess,
9 VODHLSTranscodingSuccess,
10 VODWebVideoTranscodingSuccess
11 } from '@shared/models'
12 import { ConfigManager } from '../../../shared/config-manager'
13 import { buildFFmpegVOD, downloadInputFile, ProcessOptions } from './common'
14
15 export async function processWebVideoTranscoding (options: ProcessOptions<RunnerJobVODWebVideoTranscodingPayload>) {
16 const { server, job, runnerToken } = options
17 const payload = job.payload
18
19 const inputPath = await downloadInputFile({ url: payload.input.videoFileUrl, runnerToken, job })
20
21 const ffmpegVod = buildFFmpegVOD({ job, server, runnerToken })
22
23 const outputPath = join(ConfigManager.Instance.getTranscodingDirectory(), `output-${buildUUID()}.mp4`)
24
25 await ffmpegVod.transcode({
26 type: 'video',
27
28 inputPath,
29
30 outputPath,
31
32 inputFileMutexReleaser: () => {},
33
34 resolution: payload.output.resolution,
35 fps: payload.output.fps
36 })
37
38 const successBody: VODWebVideoTranscodingSuccess = {
39 videoFile: outputPath
40 }
41
42 await server.runnerJobs.success({
43 jobToken: job.jobToken,
44 jobUUID: job.uuid,
45 runnerToken,
46 payload: successBody
47 })
48
49 await remove(outputPath)
50 }
51
52 export async function processHLSTranscoding (options: ProcessOptions<RunnerJobVODHLSTranscodingPayload>) {
53 const { server, job, runnerToken } = options
54 const payload = job.payload
55
56 const inputPath = await downloadInputFile({ url: payload.input.videoFileUrl, runnerToken, job })
57 const uuid = buildUUID()
58
59 const outputPath = join(ConfigManager.Instance.getTranscodingDirectory(), `${uuid}-${payload.output.resolution}.m3u8`)
60 const videoFilename = `${uuid}-${payload.output.resolution}-fragmented.mp4`
61 const videoPath = join(join(ConfigManager.Instance.getTranscodingDirectory(), videoFilename))
62
63 const ffmpegVod = buildFFmpegVOD({ job, server, runnerToken })
64
65 try {
66 await ffmpegVod.transcode({
67 type: 'hls',
68 copyCodecs: false,
69 inputPath,
70 hlsPlaylist: { videoFilename },
71 outputPath,
72
73 inputFileMutexReleaser: () => {},
74
75 resolution: payload.output.resolution,
76 fps: payload.output.fps
77 })
78
79 const successBody: VODHLSTranscodingSuccess = {
80 resolutionPlaylistFile: outputPath,
81 videoFile: videoPath
82 }
83
84 await server.runnerJobs.success({
85 jobToken: job.jobToken,
86 jobUUID: job.uuid,
87 runnerToken,
88 payload: successBody
89 })
90 } finally {
91 await remove(inputPath)
92 await remove(outputPath)
93 await remove(videoPath)
94 }
95 }
96
97 export async function processAudioMergeTranscoding (options: ProcessOptions<RunnerJobVODAudioMergeTranscodingPayload>) {
98 const { server, job, runnerToken } = options
99 const payload = job.payload
100
101 const audioPath = await downloadInputFile({ url: payload.input.audioFileUrl, runnerToken, job })
102 const inputPath = await downloadInputFile({ url: payload.input.previewFileUrl, runnerToken, job })
103
104 const outputPath = join(ConfigManager.Instance.getTranscodingDirectory(), `output-${buildUUID()}.mp4`)
105
106 const ffmpegVod = buildFFmpegVOD({ job, server, runnerToken })
107
108 await ffmpegVod.transcode({
109 type: 'merge-audio',
110
111 audioPath,
112 inputPath,
113
114 outputPath,
115
116 inputFileMutexReleaser: () => {},
117
118 resolution: payload.output.resolution,
119 fps: payload.output.fps
120 })
121
122 const successBody: VODAudioMergeTranscodingSuccess = {
123 videoFile: outputPath
124 }
125
126 await server.runnerJobs.success({
127 jobToken: job.jobToken,
128 jobUUID: job.uuid,
129 runnerToken,
130 payload: successBody
131 })
132
133 await remove(outputPath)
134 }