diff options
Diffstat (limited to 'server/lib/video-studio.ts')
-rw-r--r-- | server/lib/video-studio.ts | 130 |
1 files changed, 0 insertions, 130 deletions
diff --git a/server/lib/video-studio.ts b/server/lib/video-studio.ts deleted file mode 100644 index f549a7084..000000000 --- a/server/lib/video-studio.ts +++ /dev/null | |||
@@ -1,130 +0,0 @@ | |||
1 | import { move, remove } from 'fs-extra' | ||
2 | import { join } from 'path' | ||
3 | import { logger, loggerTagsFactory } from '@server/helpers/logger' | ||
4 | import { createTorrentAndSetInfoHashFromPath } from '@server/helpers/webtorrent' | ||
5 | import { CONFIG } from '@server/initializers/config' | ||
6 | import { UserModel } from '@server/models/user/user' | ||
7 | import { MUser, MVideo, MVideoFile, MVideoFullLight, MVideoWithAllFiles } from '@server/types/models' | ||
8 | import { getVideoStreamDuration } from '@shared/ffmpeg' | ||
9 | import { VideoStudioEditionPayload, VideoStudioTask, VideoStudioTaskPayload } from '@shared/models' | ||
10 | import { federateVideoIfNeeded } from './activitypub/videos' | ||
11 | import { JobQueue } from './job-queue' | ||
12 | import { VideoStudioTranscodingJobHandler } from './runners' | ||
13 | import { createOptimizeOrMergeAudioJobs } from './transcoding/create-transcoding-job' | ||
14 | import { getTranscodingJobPriority } from './transcoding/transcoding-priority' | ||
15 | import { buildNewFile, removeHLSPlaylist, removeWebVideoFile } from './video-file' | ||
16 | import { VideoPathManager } from './video-path-manager' | ||
17 | |||
18 | const lTags = loggerTagsFactory('video-studio') | ||
19 | |||
20 | export function buildTaskFileFieldname (indice: number, fieldName = 'file') { | ||
21 | return `tasks[${indice}][options][${fieldName}]` | ||
22 | } | ||
23 | |||
24 | export function getTaskFileFromReq (files: Express.Multer.File[], indice: number, fieldName = 'file') { | ||
25 | return files.find(f => f.fieldname === buildTaskFileFieldname(indice, fieldName)) | ||
26 | } | ||
27 | |||
28 | export function getStudioTaskFilePath (filename: string) { | ||
29 | return join(CONFIG.STORAGE.TMP_PERSISTENT_DIR, filename) | ||
30 | } | ||
31 | |||
32 | export async function safeCleanupStudioTMPFiles (tasks: VideoStudioTaskPayload[]) { | ||
33 | logger.info('Removing studio task files', { tasks, ...lTags() }) | ||
34 | |||
35 | for (const task of tasks) { | ||
36 | try { | ||
37 | if (task.name === 'add-intro' || task.name === 'add-outro') { | ||
38 | await remove(task.options.file) | ||
39 | } else if (task.name === 'add-watermark') { | ||
40 | await remove(task.options.file) | ||
41 | } | ||
42 | } catch (err) { | ||
43 | logger.error('Cannot remove studio file', { err }) | ||
44 | } | ||
45 | } | ||
46 | } | ||
47 | |||
48 | // --------------------------------------------------------------------------- | ||
49 | |||
50 | export async function approximateIntroOutroAdditionalSize ( | ||
51 | video: MVideoFullLight, | ||
52 | tasks: VideoStudioTask[], | ||
53 | fileFinder: (i: number) => string | ||
54 | ) { | ||
55 | let additionalDuration = 0 | ||
56 | |||
57 | for (let i = 0; i < tasks.length; i++) { | ||
58 | const task = tasks[i] | ||
59 | |||
60 | if (task.name !== 'add-intro' && task.name !== 'add-outro') continue | ||
61 | |||
62 | const filePath = fileFinder(i) | ||
63 | additionalDuration += await getVideoStreamDuration(filePath) | ||
64 | } | ||
65 | |||
66 | return (video.getMaxQualityFile().size / video.duration) * additionalDuration | ||
67 | } | ||
68 | |||
69 | // --------------------------------------------------------------------------- | ||
70 | |||
71 | export async function createVideoStudioJob (options: { | ||
72 | video: MVideo | ||
73 | user: MUser | ||
74 | payload: VideoStudioEditionPayload | ||
75 | }) { | ||
76 | const { video, user, payload } = options | ||
77 | |||
78 | const priority = await getTranscodingJobPriority({ user, type: 'studio', fallback: 0 }) | ||
79 | |||
80 | if (CONFIG.VIDEO_STUDIO.REMOTE_RUNNERS.ENABLED) { | ||
81 | await new VideoStudioTranscodingJobHandler().create({ video, tasks: payload.tasks, priority }) | ||
82 | return | ||
83 | } | ||
84 | |||
85 | await JobQueue.Instance.createJob({ type: 'video-studio-edition', payload, priority }) | ||
86 | } | ||
87 | |||
88 | export async function onVideoStudioEnded (options: { | ||
89 | editionResultPath: string | ||
90 | tasks: VideoStudioTaskPayload[] | ||
91 | video: MVideoFullLight | ||
92 | }) { | ||
93 | const { video, tasks, editionResultPath } = options | ||
94 | |||
95 | const newFile = await buildNewFile({ path: editionResultPath, mode: 'web-video' }) | ||
96 | newFile.videoId = video.id | ||
97 | |||
98 | const outputPath = VideoPathManager.Instance.getFSVideoFileOutputPath(video, newFile) | ||
99 | await move(editionResultPath, outputPath) | ||
100 | |||
101 | await safeCleanupStudioTMPFiles(tasks) | ||
102 | |||
103 | await createTorrentAndSetInfoHashFromPath(video, newFile, outputPath) | ||
104 | await removeAllFiles(video, newFile) | ||
105 | |||
106 | await newFile.save() | ||
107 | |||
108 | video.duration = await getVideoStreamDuration(outputPath) | ||
109 | await video.save() | ||
110 | |||
111 | await federateVideoIfNeeded(video, false, undefined) | ||
112 | |||
113 | const user = await UserModel.loadByVideoId(video.id) | ||
114 | |||
115 | await createOptimizeOrMergeAudioJobs({ video, videoFile: newFile, isNewVideo: false, user, videoFileAlreadyLocked: false }) | ||
116 | } | ||
117 | |||
118 | // --------------------------------------------------------------------------- | ||
119 | // Private | ||
120 | // --------------------------------------------------------------------------- | ||
121 | |||
122 | async function removeAllFiles (video: MVideoWithAllFiles, webVideoFileException: MVideoFile) { | ||
123 | await removeHLSPlaylist(video) | ||
124 | |||
125 | for (const file of video.VideoFiles) { | ||
126 | if (file.id === webVideoFileException.id) continue | ||
127 | |||
128 | await removeWebVideoFile(video, file.id) | ||
129 | } | ||
130 | } | ||