diff options
Diffstat (limited to 'server/controllers/api/videos/upload.ts')
-rw-r--r-- | server/controllers/api/videos/upload.ts | 71 |
1 files changed, 25 insertions, 46 deletions
diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts index 43313a143..885ac8b81 100644 --- a/server/controllers/api/videos/upload.ts +++ b/server/controllers/api/videos/upload.ts | |||
@@ -3,28 +3,20 @@ import { move } from 'fs-extra' | |||
3 | import { basename } from 'path' | 3 | import { basename } from 'path' |
4 | import { getResumableUploadPath } from '@server/helpers/upload' | 4 | import { getResumableUploadPath } from '@server/helpers/upload' |
5 | import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' | 5 | import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' |
6 | import { JobQueue } from '@server/lib/job-queue' | 6 | import { CreateJobArgument, CreateJobOptions, JobQueue } from '@server/lib/job-queue' |
7 | import { generateWebTorrentVideoFilename } from '@server/lib/paths' | ||
8 | import { Redis } from '@server/lib/redis' | 7 | import { Redis } from '@server/lib/redis' |
9 | import { uploadx } from '@server/lib/uploadx' | 8 | import { uploadx } from '@server/lib/uploadx' |
10 | import { | 9 | import { buildLocalVideoFromReq, buildMoveToObjectStorageJob, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' |
11 | buildLocalVideoFromReq, | 10 | import { buildNewFile } from '@server/lib/video-file' |
12 | buildMoveToObjectStorageJob, | ||
13 | buildOptimizeOrMergeAudioJob, | ||
14 | buildVideoThumbnailsFromReq, | ||
15 | setVideoTags | ||
16 | } from '@server/lib/video' | ||
17 | import { VideoPathManager } from '@server/lib/video-path-manager' | 11 | import { VideoPathManager } from '@server/lib/video-path-manager' |
18 | import { buildNextVideoState } from '@server/lib/video-state' | 12 | import { buildNextVideoState } from '@server/lib/video-state' |
19 | import { openapiOperationDoc } from '@server/middlewares/doc' | 13 | import { openapiOperationDoc } from '@server/middlewares/doc' |
20 | import { VideoSourceModel } from '@server/models/video/video-source' | 14 | import { VideoSourceModel } from '@server/models/video/video-source' |
21 | import { MUserId, MVideoFile, MVideoFullLight } from '@server/types/models' | 15 | import { MUserId, MVideoFile, MVideoFullLight } from '@server/types/models' |
22 | import { getLowercaseExtension } from '@shared/core-utils' | 16 | import { uuidToShort } from '@shared/extra-utils' |
23 | import { isAudioFile, uuidToShort } from '@shared/extra-utils' | 17 | import { HttpStatusCode, VideoCreate, VideoState } from '@shared/models' |
24 | import { HttpStatusCode, VideoCreate, VideoResolution, VideoState } from '@shared/models' | ||
25 | import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' | 18 | import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' |
26 | import { createReqFiles } from '../../../helpers/express-utils' | 19 | import { createReqFiles } from '../../../helpers/express-utils' |
27 | import { buildFileMetadata, ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamFPS } from '../../../helpers/ffmpeg' | ||
28 | import { logger, loggerTagsFactory } from '../../../helpers/logger' | 20 | import { logger, loggerTagsFactory } from '../../../helpers/logger' |
29 | import { MIMETYPES } from '../../../initializers/constants' | 21 | import { MIMETYPES } from '../../../initializers/constants' |
30 | import { sequelizeTypescript } from '../../../initializers/database' | 22 | import { sequelizeTypescript } from '../../../initializers/database' |
@@ -41,7 +33,6 @@ import { | |||
41 | } from '../../../middlewares' | 33 | } from '../../../middlewares' |
42 | import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update' | 34 | import { ScheduleVideoUpdateModel } from '../../../models/video/schedule-video-update' |
43 | import { VideoModel } from '../../../models/video/video' | 35 | import { VideoModel } from '../../../models/video/video' |
44 | import { VideoFileModel } from '../../../models/video/video-file' | ||
45 | 36 | ||
46 | const lTags = loggerTagsFactory('api', 'video') | 37 | const lTags = loggerTagsFactory('api', 'video') |
47 | const auditLogger = auditLoggerFactory('videos') | 38 | const auditLogger = auditLoggerFactory('videos') |
@@ -148,7 +139,7 @@ async function addVideo (options: { | |||
148 | video.VideoChannel = videoChannel | 139 | video.VideoChannel = videoChannel |
149 | video.url = getLocalVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object | 140 | video.url = getLocalVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object |
150 | 141 | ||
151 | const videoFile = await buildNewFile(videoPhysicalFile) | 142 | const videoFile = await buildNewFile({ path: videoPhysicalFile.path, mode: 'web-video' }) |
152 | const originalFilename = videoPhysicalFile.originalname | 143 | const originalFilename = videoPhysicalFile.originalname |
153 | 144 | ||
154 | // Move physical file | 145 | // Move physical file |
@@ -227,30 +218,8 @@ async function addVideo (options: { | |||
227 | } | 218 | } |
228 | } | 219 | } |
229 | 220 | ||
230 | async function buildNewFile (videoPhysicalFile: express.VideoUploadFile) { | ||
231 | const videoFile = new VideoFileModel({ | ||
232 | extname: getLowercaseExtension(videoPhysicalFile.filename), | ||
233 | size: videoPhysicalFile.size, | ||
234 | videoStreamingPlaylistId: null, | ||
235 | metadata: await buildFileMetadata(videoPhysicalFile.path) | ||
236 | }) | ||
237 | |||
238 | const probe = await ffprobePromise(videoPhysicalFile.path) | ||
239 | |||
240 | if (await isAudioFile(videoPhysicalFile.path, probe)) { | ||
241 | videoFile.resolution = VideoResolution.H_NOVIDEO | ||
242 | } else { | ||
243 | videoFile.fps = await getVideoStreamFPS(videoPhysicalFile.path, probe) | ||
244 | videoFile.resolution = (await getVideoStreamDimensionsInfo(videoPhysicalFile.path, probe)).resolution | ||
245 | } | ||
246 | |||
247 | videoFile.filename = generateWebTorrentVideoFilename(videoFile.resolution, videoFile.extname) | ||
248 | |||
249 | return videoFile | ||
250 | } | ||
251 | |||
252 | async function addVideoJobsAfterUpload (video: MVideoFullLight, videoFile: MVideoFile, user: MUserId) { | 221 | async function addVideoJobsAfterUpload (video: MVideoFullLight, videoFile: MVideoFile, user: MUserId) { |
253 | return JobQueue.Instance.createSequentialJobFlow( | 222 | const jobs: (CreateJobArgument & CreateJobOptions)[] = [ |
254 | { | 223 | { |
255 | type: 'manage-video-torrent' as 'manage-video-torrent', | 224 | type: 'manage-video-torrent' as 'manage-video-torrent', |
256 | payload: { | 225 | payload: { |
@@ -274,16 +243,26 @@ async function addVideoJobsAfterUpload (video: MVideoFullLight, videoFile: MVide | |||
274 | videoUUID: video.uuid, | 243 | videoUUID: video.uuid, |
275 | isNewVideo: true | 244 | isNewVideo: true |
276 | } | 245 | } |
277 | }, | 246 | } |
247 | ] | ||
278 | 248 | ||
279 | video.state === VideoState.TO_MOVE_TO_EXTERNAL_STORAGE | 249 | if (video.state === VideoState.TO_MOVE_TO_EXTERNAL_STORAGE) { |
280 | ? await buildMoveToObjectStorageJob({ video, previousVideoState: undefined }) | 250 | jobs.push(await buildMoveToObjectStorageJob({ video, previousVideoState: undefined })) |
281 | : undefined, | 251 | } |
252 | |||
253 | if (video.state === VideoState.TO_TRANSCODE) { | ||
254 | jobs.push({ | ||
255 | type: 'transcoding-job-builder' as 'transcoding-job-builder', | ||
256 | payload: { | ||
257 | videoUUID: video.uuid, | ||
258 | optimizeJob: { | ||
259 | isNewVideo: true | ||
260 | } | ||
261 | } | ||
262 | }) | ||
263 | } | ||
282 | 264 | ||
283 | video.state === VideoState.TO_TRANSCODE | 265 | return JobQueue.Instance.createSequentialJobFlow(...jobs) |
284 | ? await buildOptimizeOrMergeAudioJob({ video, videoFile, user }) | ||
285 | : undefined | ||
286 | ) | ||
287 | } | 266 | } |
288 | 267 | ||
289 | async function deleteUploadResumableCache (req: express.Request, res: express.Response, next: express.NextFunction) { | 268 | async function deleteUploadResumableCache (req: express.Request, res: express.Response, next: express.NextFunction) { |