aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/controllers/api/videos/index.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/controllers/api/videos/index.ts')
-rw-r--r--server/controllers/api/videos/index.ts55
1 files changed, 23 insertions, 32 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts
index 8d4ff07eb..8048c568c 100644
--- a/server/controllers/api/videos/index.ts
+++ b/server/controllers/api/videos/index.ts
@@ -1,10 +1,10 @@
1import * as express from 'express' 1import * as express from 'express'
2import { extname } from 'path' 2import { extname } from 'path'
3import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared' 3import { VideoCreate, VideoPrivacy, VideoState, VideoUpdate } from '../../../../shared'
4import { getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' 4import { getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
5import { logger } from '../../../helpers/logger' 5import { logger } from '../../../helpers/logger'
6import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' 6import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger'
7import { getFormattedObjects, getServerActor } from '../../../helpers/utils' 7import { getFormattedObjects } from '../../../helpers/utils'
8import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist' 8import { autoBlacklistVideoIfNeeded } from '../../../lib/video-blacklist'
9import { 9import {
10 DEFAULT_AUDIO_RESOLUTION, 10 DEFAULT_AUDIO_RESOLUTION,
@@ -14,12 +14,7 @@ import {
14 VIDEO_LICENCES, 14 VIDEO_LICENCES,
15 VIDEO_PRIVACIES 15 VIDEO_PRIVACIES
16} from '../../../initializers/constants' 16} from '../../../initializers/constants'
17import { 17import { federateVideoIfNeeded, fetchRemoteVideoDescription } from '../../../lib/activitypub/videos'
18 changeVideoChannelShare,
19 federateVideoIfNeeded,
20 fetchRemoteVideoDescription,
21 getVideoActivityPubUrl
22} from '../../../lib/activitypub'
23import { JobQueue } from '../../../lib/job-queue' 18import { JobQueue } from '../../../lib/job-queue'
24import { Redis } from '../../../lib/redis' 19import { Redis } from '../../../lib/redis'
25import { 20import {
@@ -32,6 +27,7 @@ import {
32 paginationValidator, 27 paginationValidator,
33 setDefaultPagination, 28 setDefaultPagination,
34 setDefaultSort, 29 setDefaultSort,
30 videoFileMetadataGetValidator,
35 videosAddValidator, 31 videosAddValidator,
36 videosCustomGetValidator, 32 videosCustomGetValidator,
37 videosGetValidator, 33 videosGetValidator,
@@ -61,11 +57,15 @@ import { CONFIG } from '../../../initializers/config'
61import { sequelizeTypescript } from '../../../initializers/database' 57import { sequelizeTypescript } from '../../../initializers/database'
62import { createVideoMiniatureFromExisting, generateVideoMiniature } from '../../../lib/thumbnail' 58import { createVideoMiniatureFromExisting, generateVideoMiniature } from '../../../lib/thumbnail'
63import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' 59import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type'
64import { VideoTranscodingPayload } from '../../../lib/job-queue/handlers/video-transcoding'
65import { Hooks } from '../../../lib/plugins/hooks' 60import { Hooks } from '../../../lib/plugins/hooks'
66import { MVideoDetails, MVideoFullLight } from '@server/typings/models' 61import { MVideoDetails, MVideoFullLight } from '@server/typings/models'
67import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent' 62import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
68import { getVideoFilePath } from '@server/lib/video-paths' 63import { getVideoFilePath } from '@server/lib/video-paths'
64import toInt from 'validator/lib/toInt'
65import { addOptimizeOrMergeAudioJob } from '@server/helpers/video'
66import { getServerActor } from '@server/models/application/application'
67import { changeVideoChannelShare } from '@server/lib/activitypub/share'
68import { getVideoActivityPubUrl } from '@server/lib/activitypub/url'
69 69
70const auditLogger = auditLoggerFactory('videos') 70const auditLogger = auditLoggerFactory('videos')
71const videosRouter = express.Router() 71const videosRouter = express.Router()
@@ -128,6 +128,10 @@ videosRouter.get('/:id/description',
128 asyncMiddleware(videosGetValidator), 128 asyncMiddleware(videosGetValidator),
129 asyncMiddleware(getVideoDescription) 129 asyncMiddleware(getVideoDescription)
130) 130)
131videosRouter.get('/:id/metadata/:videoFileId',
132 asyncMiddleware(videoFileMetadataGetValidator),
133 asyncMiddleware(getVideoFileMetadata)
134)
131videosRouter.get('/:id', 135videosRouter.get('/:id',
132 optionalAuthenticate, 136 optionalAuthenticate,
133 asyncMiddleware(videosCustomGetValidator('only-video-with-rights')), 137 asyncMiddleware(videosCustomGetValidator('only-video-with-rights')),
@@ -135,7 +139,7 @@ videosRouter.get('/:id',
135 asyncMiddleware(getVideo) 139 asyncMiddleware(getVideo)
136) 140)
137videosRouter.post('/:id/views', 141videosRouter.post('/:id/views',
138 asyncMiddleware(videosGetValidator), 142 asyncMiddleware(videosCustomGetValidator('only-immutable-attributes')),
139 asyncMiddleware(viewVideo) 143 asyncMiddleware(viewVideo)
140) 144)
141 145
@@ -206,7 +210,8 @@ async function addVideo (req: express.Request, res: express.Response) {
206 const videoFile = new VideoFileModel({ 210 const videoFile = new VideoFileModel({
207 extname: extname(videoPhysicalFile.filename), 211 extname: extname(videoPhysicalFile.filename),
208 size: videoPhysicalFile.size, 212 size: videoPhysicalFile.size,
209 videoStreamingPlaylistId: null 213 videoStreamingPlaylistId: null,
214 metadata: await getMetadataFromFile<any>(videoPhysicalFile.path)
210 }) 215 })
211 216
212 if (videoFile.isAudio()) { 217 if (videoFile.isAudio()) {
@@ -289,25 +294,7 @@ async function addVideo (req: express.Request, res: express.Response) {
289 Notifier.Instance.notifyOnNewVideoIfNeeded(videoCreated) 294 Notifier.Instance.notifyOnNewVideoIfNeeded(videoCreated)
290 295
291 if (video.state === VideoState.TO_TRANSCODE) { 296 if (video.state === VideoState.TO_TRANSCODE) {
292 // Put uuid because we don't have id auto incremented for now 297 await addOptimizeOrMergeAudioJob(videoCreated, videoFile)
293 let dataInput: VideoTranscodingPayload
294
295 if (videoFile.isAudio()) {
296 dataInput = {
297 type: 'merge-audio' as 'merge-audio',
298 resolution: DEFAULT_AUDIO_RESOLUTION,
299 videoUUID: videoCreated.uuid,
300 isNewVideo: true
301 }
302 } else {
303 dataInput = {
304 type: 'optimize' as 'optimize',
305 videoUUID: videoCreated.uuid,
306 isNewVideo: true
307 }
308 }
309
310 await JobQueue.Instance.createJob({ type: 'video-transcoding', payload: dataInput })
311 } 298 }
312 299
313 Hooks.runAction('action:api.video.uploaded', { video: videoCreated }) 300 Hooks.runAction('action:api.video.uploaded', { video: videoCreated })
@@ -452,14 +439,13 @@ async function getVideo (req: express.Request, res: express.Response) {
452 439
453 if (video.isOutdated()) { 440 if (video.isOutdated()) {
454 JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', url: video.url } }) 441 JobQueue.Instance.createJob({ type: 'activitypub-refresher', payload: { type: 'video', url: video.url } })
455 .catch(err => logger.error('Cannot create AP refresher job for video %s.', video.url, { err }))
456 } 442 }
457 443
458 return res.json(video.toFormattedDetailsJSON()) 444 return res.json(video.toFormattedDetailsJSON())
459} 445}
460 446
461async function viewVideo (req: express.Request, res: express.Response) { 447async function viewVideo (req: express.Request, res: express.Response) {
462 const videoInstance = res.locals.videoAll 448 const videoInstance = res.locals.onlyImmutableVideo
463 449
464 const ip = req.ip 450 const ip = req.ip
465 const exists = await Redis.Instance.doesVideoIPViewExist(ip, videoInstance.uuid) 451 const exists = await Redis.Instance.doesVideoIPViewExist(ip, videoInstance.uuid)
@@ -494,6 +480,11 @@ async function getVideoDescription (req: express.Request, res: express.Response)
494 return res.json({ description }) 480 return res.json({ description })
495} 481}
496 482
483async function getVideoFileMetadata (req: express.Request, res: express.Response) {
484 const videoFile = await VideoFileModel.loadWithMetadata(toInt(req.params.videoFileId))
485 return res.json(videoFile.metadata)
486}
487
497async function listVideos (req: express.Request, res: express.Response) { 488async function listVideos (req: express.Request, res: express.Response) {
498 const countVideos = getCountVideos(req) 489 const countVideos = getCountVideos(req)
499 490