diff options
Diffstat (limited to 'server/controllers')
-rw-r--r-- | server/controllers/api/videos/upload.ts | 34 | ||||
-rw-r--r-- | server/controllers/download.ts | 25 |
2 files changed, 42 insertions, 17 deletions
diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts index 89f50714d..5c740c041 100644 --- a/server/controllers/api/videos/upload.ts +++ b/server/controllers/api/videos/upload.ts | |||
@@ -1,12 +1,21 @@ | |||
1 | import * as express from 'express' | 1 | import * as express from 'express' |
2 | import { move } from 'fs-extra' | 2 | import { move } from 'fs-extra' |
3 | import { basename } from 'path' | ||
3 | import { getLowercaseExtension } from '@server/helpers/core-utils' | 4 | import { getLowercaseExtension } from '@server/helpers/core-utils' |
4 | import { deleteResumableUploadMetaFile, getResumableUploadPath } from '@server/helpers/upload' | 5 | import { deleteResumableUploadMetaFile, getResumableUploadPath } from '@server/helpers/upload' |
5 | import { uuidToShort } from '@server/helpers/uuid' | 6 | import { uuidToShort } from '@server/helpers/uuid' |
6 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 7 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
7 | import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' | 8 | import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' |
8 | import { addOptimizeOrMergeAudioJob, buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' | 9 | import { generateWebTorrentVideoFilename } from '@server/lib/paths' |
9 | import { generateWebTorrentVideoFilename, getVideoFilePath } from '@server/lib/video-paths' | 10 | import { |
11 | addMoveToObjectStorageJob, | ||
12 | addOptimizeOrMergeAudioJob, | ||
13 | buildLocalVideoFromReq, | ||
14 | buildVideoThumbnailsFromReq, | ||
15 | setVideoTags | ||
16 | } from '@server/lib/video' | ||
17 | import { VideoPathManager } from '@server/lib/video-path-manager' | ||
18 | import { buildNextVideoState } from '@server/lib/video-state' | ||
10 | import { openapiOperationDoc } from '@server/middlewares/doc' | 19 | import { openapiOperationDoc } from '@server/middlewares/doc' |
11 | import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' | 20 | import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' |
12 | import { uploadx } from '@uploadx/core' | 21 | import { uploadx } from '@uploadx/core' |
@@ -139,23 +148,20 @@ async function addVideo (options: { | |||
139 | 148 | ||
140 | const videoData = buildLocalVideoFromReq(videoInfo, videoChannel.id) | 149 | const videoData = buildLocalVideoFromReq(videoInfo, videoChannel.id) |
141 | 150 | ||
142 | videoData.state = CONFIG.TRANSCODING.ENABLED | 151 | videoData.state = buildNextVideoState() |
143 | ? VideoState.TO_TRANSCODE | ||
144 | : VideoState.PUBLISHED | ||
145 | |||
146 | videoData.duration = videoPhysicalFile.duration // duration was added by a previous middleware | 152 | videoData.duration = videoPhysicalFile.duration // duration was added by a previous middleware |
147 | 153 | ||
148 | const video = new VideoModel(videoData) as MVideoFullLight | 154 | const video = new VideoModel(videoData) as MVideoFullLight |
149 | video.VideoChannel = videoChannel | 155 | video.VideoChannel = videoChannel |
150 | video.url = getLocalVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object | 156 | video.url = getLocalVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object |
151 | 157 | ||
152 | const videoFile = await buildNewFile(video, videoPhysicalFile) | 158 | const videoFile = await buildNewFile(videoPhysicalFile) |
153 | 159 | ||
154 | // Move physical file | 160 | // Move physical file |
155 | const destination = getVideoFilePath(video, videoFile) | 161 | const destination = VideoPathManager.Instance.getFSVideoFileOutputPath(video, videoFile) |
156 | await move(videoPhysicalFile.path, destination) | 162 | await move(videoPhysicalFile.path, destination) |
157 | // This is important in case if there is another attempt in the retry process | 163 | // This is important in case if there is another attempt in the retry process |
158 | videoPhysicalFile.filename = getVideoFilePath(video, videoFile) | 164 | videoPhysicalFile.filename = basename(destination) |
159 | videoPhysicalFile.path = destination | 165 | videoPhysicalFile.path = destination |
160 | 166 | ||
161 | const [ thumbnailModel, previewModel ] = await buildVideoThumbnailsFromReq({ | 167 | const [ thumbnailModel, previewModel ] = await buildVideoThumbnailsFromReq({ |
@@ -210,9 +216,13 @@ async function addVideo (options: { | |||
210 | 216 | ||
211 | createTorrentFederate(video, videoFile) | 217 | createTorrentFederate(video, videoFile) |
212 | .then(() => { | 218 | .then(() => { |
213 | if (video.state !== VideoState.TO_TRANSCODE) return | 219 | if (video.state === VideoState.TO_MOVE_TO_EXTERNAL_STORAGE) { |
220 | return addMoveToObjectStorageJob(video) | ||
221 | } | ||
214 | 222 | ||
215 | return addOptimizeOrMergeAudioJob(videoCreated, videoFile, user) | 223 | if (video.state === VideoState.TO_TRANSCODE) { |
224 | return addOptimizeOrMergeAudioJob(videoCreated, videoFile, user) | ||
225 | } | ||
216 | }) | 226 | }) |
217 | .catch(err => logger.error('Cannot add optimize/merge audio job for %s.', videoCreated.uuid, { err, ...lTags(videoCreated.uuid) })) | 227 | .catch(err => logger.error('Cannot add optimize/merge audio job for %s.', videoCreated.uuid, { err, ...lTags(videoCreated.uuid) })) |
218 | 228 | ||
@@ -227,7 +237,7 @@ async function addVideo (options: { | |||
227 | }) | 237 | }) |
228 | } | 238 | } |
229 | 239 | ||
230 | async function buildNewFile (video: MVideo, videoPhysicalFile: express.VideoUploadFile) { | 240 | async function buildNewFile (videoPhysicalFile: express.VideoUploadFile) { |
231 | const videoFile = new VideoFileModel({ | 241 | const videoFile = new VideoFileModel({ |
232 | extname: getLowercaseExtension(videoPhysicalFile.filename), | 242 | extname: getLowercaseExtension(videoPhysicalFile.filename), |
233 | size: videoPhysicalFile.size, | 243 | size: videoPhysicalFile.size, |
diff --git a/server/controllers/download.ts b/server/controllers/download.ts index ddacc1b68..ffe40d57e 100644 --- a/server/controllers/download.ts +++ b/server/controllers/download.ts | |||
@@ -3,9 +3,9 @@ import * as express from 'express' | |||
3 | import { logger } from '@server/helpers/logger' | 3 | import { logger } from '@server/helpers/logger' |
4 | import { VideosTorrentCache } from '@server/lib/files-cache/videos-torrent-cache' | 4 | import { VideosTorrentCache } from '@server/lib/files-cache/videos-torrent-cache' |
5 | import { Hooks } from '@server/lib/plugins/hooks' | 5 | import { Hooks } from '@server/lib/plugins/hooks' |
6 | import { getVideoFilePath } from '@server/lib/video-paths' | 6 | import { VideoPathManager } from '@server/lib/video-path-manager' |
7 | import { MStreamingPlaylist, MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' | 7 | import { MStreamingPlaylist, MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' |
8 | import { HttpStatusCode, VideoStreamingPlaylistType } from '@shared/models' | 8 | import { HttpStatusCode, VideoStorage, VideoStreamingPlaylistType } from '@shared/models' |
9 | import { STATIC_DOWNLOAD_PATHS } from '../initializers/constants' | 9 | import { STATIC_DOWNLOAD_PATHS } from '../initializers/constants' |
10 | import { asyncMiddleware, videosDownloadValidator } from '../middlewares' | 10 | import { asyncMiddleware, videosDownloadValidator } from '../middlewares' |
11 | 11 | ||
@@ -81,7 +81,15 @@ async function downloadVideoFile (req: express.Request, res: express.Response) { | |||
81 | 81 | ||
82 | if (!checkAllowResult(res, allowParameters, allowedResult)) return | 82 | if (!checkAllowResult(res, allowParameters, allowedResult)) return |
83 | 83 | ||
84 | return res.download(getVideoFilePath(video, videoFile), `${video.name}-${videoFile.resolution}p${videoFile.extname}`) | 84 | if (videoFile.storage === VideoStorage.OBJECT_STORAGE) { |
85 | return res.redirect(videoFile.getObjectStorageUrl()) | ||
86 | } | ||
87 | |||
88 | await VideoPathManager.Instance.makeAvailableVideoFile(video, videoFile, path => { | ||
89 | const filename = `${video.name}-${videoFile.resolution}p${videoFile.extname}` | ||
90 | |||
91 | return res.download(path, filename) | ||
92 | }) | ||
85 | } | 93 | } |
86 | 94 | ||
87 | async function downloadHLSVideoFile (req: express.Request, res: express.Response) { | 95 | async function downloadHLSVideoFile (req: express.Request, res: express.Response) { |
@@ -107,8 +115,15 @@ async function downloadHLSVideoFile (req: express.Request, res: express.Response | |||
107 | 115 | ||
108 | if (!checkAllowResult(res, allowParameters, allowedResult)) return | 116 | if (!checkAllowResult(res, allowParameters, allowedResult)) return |
109 | 117 | ||
110 | const filename = `${video.name}-${videoFile.resolution}p-${streamingPlaylist.getStringType()}${videoFile.extname}` | 118 | if (videoFile.storage === VideoStorage.OBJECT_STORAGE) { |
111 | return res.download(getVideoFilePath(streamingPlaylist, videoFile), filename) | 119 | return res.redirect(videoFile.getObjectStorageUrl()) |
120 | } | ||
121 | |||
122 | await VideoPathManager.Instance.makeAvailableVideoFile(streamingPlaylist, videoFile, path => { | ||
123 | const filename = `${video.name}-${videoFile.resolution}p-${streamingPlaylist.getStringType()}${videoFile.extname}` | ||
124 | |||
125 | return res.download(path, filename) | ||
126 | }) | ||
112 | } | 127 | } |
113 | 128 | ||
114 | function getVideoFile (req: express.Request, files: MVideoFile[]) { | 129 | function getVideoFile (req: express.Request, files: MVideoFile[]) { |