diff options
Diffstat (limited to 'server/controllers/api/videos/index.ts')
-rw-r--r-- | server/controllers/api/videos/index.ts | 78 |
1 files changed, 24 insertions, 54 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 94f0361ee..1539afc35 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -6,11 +6,11 @@ import { addOptimizeOrMergeAudioJob } from '@server/helpers/video' | |||
6 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' | 6 | import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' |
7 | import { changeVideoChannelShare } from '@server/lib/activitypub/share' | 7 | import { changeVideoChannelShare } from '@server/lib/activitypub/share' |
8 | import { getVideoActivityPubUrl } from '@server/lib/activitypub/url' | 8 | import { getVideoActivityPubUrl } from '@server/lib/activitypub/url' |
9 | import { buildLocalVideoFromReq, buildVideoThumbnailsFromReq, setVideoTags } from '@server/lib/video' | ||
9 | import { getVideoFilePath } from '@server/lib/video-paths' | 10 | import { getVideoFilePath } from '@server/lib/video-paths' |
10 | import { getServerActor } from '@server/models/application/application' | 11 | import { getServerActor } from '@server/models/application/application' |
11 | import { MVideoDetails, MVideoFullLight } from '@server/types/models' | 12 | import { MVideoDetails, MVideoFullLight } from '@server/types/models' |
12 | import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared' | 13 | import { VideoCreate, VideoState, VideoUpdate } from '../../../../shared' |
13 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' | ||
14 | import { VideoFilter } from '../../../../shared/models/videos/video-query.type' | 14 | import { VideoFilter } from '../../../../shared/models/videos/video-query.type' |
15 | import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' | 15 | import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' |
16 | import { resetSequelizeInstance } from '../../../helpers/database-utils' | 16 | import { resetSequelizeInstance } from '../../../helpers/database-utils' |
@@ -34,7 +34,7 @@ import { JobQueue } from '../../../lib/job-queue' | |||
34 | import { Notifier } from '../../../lib/notifier' | 34 | import { Notifier } from '../../../lib/notifier' |
35 | import { Hooks } from '../../../lib/plugins/hooks' | 35 | import { Hooks } from '../../../lib/plugins/hooks' |
36 | import { Redis } from '../../../lib/redis' | 36 | import { Redis } from '../../../lib/redis' |
37 | import { createVideoMiniatureFromExisting, generateVideoMiniature } from '../../../lib/thumbnail' | 37 | import { generateVideoMiniature } from '../../../lib/thumbnail' |
38 | import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' | 38 | import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' |
39 | import { | 39 | import { |
40 | asyncMiddleware, | 40 | asyncMiddleware, |
@@ -186,25 +186,9 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
186 | const videoPhysicalFile = req.files['videofile'][0] | 186 | const videoPhysicalFile = req.files['videofile'][0] |
187 | const videoInfo: VideoCreate = req.body | 187 | const videoInfo: VideoCreate = req.body |
188 | 188 | ||
189 | // Prepare data so we don't block the transaction | 189 | const videoData = buildLocalVideoFromReq(videoInfo, res.locals.videoChannel.id) |
190 | const videoData = { | 190 | videoData.state = CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED |
191 | name: videoInfo.name, | 191 | videoData.duration = videoPhysicalFile['duration'] // duration was added by a previous middleware |
192 | remote: false, | ||
193 | category: videoInfo.category, | ||
194 | licence: videoInfo.licence, | ||
195 | language: videoInfo.language, | ||
196 | commentsEnabled: videoInfo.commentsEnabled !== false, // If the value is not "false", the default is "true" | ||
197 | downloadEnabled: videoInfo.downloadEnabled !== false, | ||
198 | waitTranscoding: videoInfo.waitTranscoding || false, | ||
199 | state: CONFIG.TRANSCODING.ENABLED ? VideoState.TO_TRANSCODE : VideoState.PUBLISHED, | ||
200 | nsfw: videoInfo.nsfw || false, | ||
201 | description: videoInfo.description, | ||
202 | support: videoInfo.support, | ||
203 | privacy: videoInfo.privacy || VideoPrivacy.PRIVATE, | ||
204 | duration: videoPhysicalFile['duration'], // duration was added by a previous middleware | ||
205 | channelId: res.locals.videoChannel.id, | ||
206 | originallyPublishedAt: videoInfo.originallyPublishedAt | ||
207 | } | ||
208 | 192 | ||
209 | const video = new VideoModel(videoData) as MVideoDetails | 193 | const video = new VideoModel(videoData) as MVideoDetails |
210 | video.url = getVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object | 194 | video.url = getVideoActivityPubUrl(video) // We use the UUID, so set the URL after building the object |
@@ -230,17 +214,11 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
230 | videoPhysicalFile.filename = getVideoFilePath(video, videoFile) | 214 | videoPhysicalFile.filename = getVideoFilePath(video, videoFile) |
231 | videoPhysicalFile.path = destination | 215 | videoPhysicalFile.path = destination |
232 | 216 | ||
233 | // Process thumbnail or create it from the video | 217 | const [ thumbnailModel, previewModel ] = await buildVideoThumbnailsFromReq({ |
234 | const thumbnailField = req.files['thumbnailfile'] | 218 | video, |
235 | const thumbnailModel = thumbnailField | 219 | files: req.files, |
236 | ? await createVideoMiniatureFromExisting(thumbnailField[0].path, video, ThumbnailType.MINIATURE, false) | 220 | fallback: type => generateVideoMiniature(video, videoFile, type) |
237 | : await generateVideoMiniature(video, videoFile, ThumbnailType.MINIATURE) | 221 | }) |
238 | |||
239 | // Process preview or create it from the video | ||
240 | const previewField = req.files['previewfile'] | ||
241 | const previewModel = previewField | ||
242 | ? await createVideoMiniatureFromExisting(previewField[0].path, video, ThumbnailType.PREVIEW, false) | ||
243 | : await generateVideoMiniature(video, videoFile, ThumbnailType.PREVIEW) | ||
244 | 222 | ||
245 | // Create the torrent file | 223 | // Create the torrent file |
246 | await createTorrentAndSetInfoHash(video, videoFile) | 224 | await createTorrentAndSetInfoHash(video, videoFile) |
@@ -261,13 +239,7 @@ async function addVideo (req: express.Request, res: express.Response) { | |||
261 | 239 | ||
262 | video.VideoFiles = [ videoFile ] | 240 | video.VideoFiles = [ videoFile ] |
263 | 241 | ||
264 | // Create tags | 242 | await setVideoTags({ video, tags: videoInfo.tags, transaction: t }) |
265 | if (videoInfo.tags !== undefined) { | ||
266 | const tagInstances = await TagModel.findOrCreateTags(videoInfo.tags, t) | ||
267 | |||
268 | await video.$set('Tags', tagInstances, sequelizeOptions) | ||
269 | video.Tags = tagInstances | ||
270 | } | ||
271 | 243 | ||
272 | // Schedule an update in the future? | 244 | // Schedule an update in the future? |
273 | if (videoInfo.scheduleUpdate) { | 245 | if (videoInfo.scheduleUpdate) { |
@@ -318,14 +290,12 @@ async function updateVideo (req: express.Request, res: express.Response) { | |||
318 | const wasConfidentialVideo = videoInstance.isConfidential() | 290 | const wasConfidentialVideo = videoInstance.isConfidential() |
319 | const hadPrivacyForFederation = videoInstance.hasPrivacyForFederation() | 291 | const hadPrivacyForFederation = videoInstance.hasPrivacyForFederation() |
320 | 292 | ||
321 | // Process thumbnail or create it from the video | 293 | const [ thumbnailModel, previewModel ] = await buildVideoThumbnailsFromReq({ |
322 | const thumbnailModel = req.files?.['thumbnailfile'] | 294 | video: videoInstance, |
323 | ? await createVideoMiniatureFromExisting(req.files['thumbnailfile'][0].path, videoInstance, ThumbnailType.MINIATURE, false) | 295 | files: req.files, |
324 | : undefined | 296 | fallback: () => Promise.resolve(undefined), |
325 | 297 | automaticallyGenerated: false | |
326 | const previewModel = req.files?.['previewfile'] | 298 | }) |
327 | ? await createVideoMiniatureFromExisting(req.files['previewfile'][0].path, videoInstance, ThumbnailType.PREVIEW, false) | ||
328 | : undefined | ||
329 | 299 | ||
330 | try { | 300 | try { |
331 | const videoInstanceUpdated = await sequelizeTypescript.transaction(async t => { | 301 | const videoInstanceUpdated = await sequelizeTypescript.transaction(async t => { |
@@ -366,12 +336,12 @@ async function updateVideo (req: express.Request, res: express.Response) { | |||
366 | if (previewModel) await videoInstanceUpdated.addAndSaveThumbnail(previewModel, t) | 336 | if (previewModel) await videoInstanceUpdated.addAndSaveThumbnail(previewModel, t) |
367 | 337 | ||
368 | // Video tags update? | 338 | // Video tags update? |
369 | if (videoInfoToUpdate.tags !== undefined) { | 339 | await setVideoTags({ |
370 | const tagInstances = await TagModel.findOrCreateTags(videoInfoToUpdate.tags, t) | 340 | video: videoInstanceUpdated, |
371 | 341 | tags: videoInfoToUpdate.tags, | |
372 | await videoInstanceUpdated.$set('Tags', tagInstances, sequelizeOptions) | 342 | transaction: t, |
373 | videoInstanceUpdated.Tags = tagInstances | 343 | defaultValue: videoInstanceUpdated.Tags |
374 | } | 344 | }) |
375 | 345 | ||
376 | // Video channel update? | 346 | // Video channel update? |
377 | if (res.locals.videoChannel && videoInstanceUpdated.channelId !== res.locals.videoChannel.id) { | 347 | if (res.locals.videoChannel && videoInstanceUpdated.channelId !== res.locals.videoChannel.id) { |