From ad5db1044c8599eaaaa2a578b350777ae996b068 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 18 Nov 2021 14:35:08 +0100 Subject: Add ability to run transcoding jobs --- server/controllers/api/videos/files.ts | 5 ++- server/controllers/api/videos/index.ts | 2 + server/controllers/api/videos/transcoding.ts | 62 ++++++++++++++++++++++++++++ server/controllers/download.ts | 4 +- 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 server/controllers/api/videos/transcoding.ts (limited to 'server/controllers') diff --git a/server/controllers/api/videos/files.ts b/server/controllers/api/videos/files.ts index 2fe4b5a3f..a8b32411d 100644 --- a/server/controllers/api/videos/files.ts +++ b/server/controllers/api/videos/files.ts @@ -3,10 +3,11 @@ import toInt from 'validator/lib/toInt' import { logger, loggerTagsFactory } from '@server/helpers/logger' import { federateVideoIfNeeded } from '@server/lib/activitypub/videos' import { VideoFileModel } from '@server/models/video/video-file' -import { HttpStatusCode } from '@shared/models' +import { HttpStatusCode, UserRight } from '@shared/models' import { asyncMiddleware, authenticate, + ensureUserHasRight, videoFileMetadataGetValidator, videoFilesDeleteHLSValidator, videoFilesDeleteWebTorrentValidator @@ -22,12 +23,14 @@ filesRouter.get('/:id/metadata/:videoFileId', filesRouter.delete('/:id/hls', authenticate, + ensureUserHasRight(UserRight.MANAGE_VIDEO_FILES), asyncMiddleware(videoFilesDeleteHLSValidator), asyncMiddleware(removeHLSPlaylist) ) filesRouter.delete('/:id/webtorrent', authenticate, + ensureUserHasRight(UserRight.MANAGE_VIDEO_FILES), asyncMiddleware(videoFilesDeleteWebTorrentValidator), asyncMiddleware(removeWebTorrentFiles) ) diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index 2d088a73e..fc1bcc73d 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts @@ -40,6 +40,7 @@ import { videoImportsRouter } from './import' import { liveRouter } from './live' import { ownershipVideoRouter } from './ownership' import { rateVideoRouter } from './rate' +import { transcodingRouter } from './transcoding' import { updateRouter } from './update' import { uploadRouter } from './upload' import { watchingRouter } from './watching' @@ -58,6 +59,7 @@ videosRouter.use('/', liveRouter) videosRouter.use('/', uploadRouter) videosRouter.use('/', updateRouter) videosRouter.use('/', filesRouter) +videosRouter.use('/', transcodingRouter) videosRouter.get('/categories', openapiOperationDoc({ operationId: 'getCategories' }), diff --git a/server/controllers/api/videos/transcoding.ts b/server/controllers/api/videos/transcoding.ts new file mode 100644 index 000000000..dd6fbd3de --- /dev/null +++ b/server/controllers/api/videos/transcoding.ts @@ -0,0 +1,62 @@ +import express from 'express' +import { computeLowerResolutionsToTranscode } from '@server/helpers/ffprobe-utils' +import { logger, loggerTagsFactory } from '@server/helpers/logger' +import { addTranscodingJob } from '@server/lib/video' +import { HttpStatusCode, UserRight, VideoState, VideoTranscodingCreate } from '@shared/models' +import { asyncMiddleware, authenticate, createTranscodingValidator, ensureUserHasRight } from '../../../middlewares' + +const lTags = loggerTagsFactory('api', 'video') +const transcodingRouter = express.Router() + +transcodingRouter.post('/:videoId/transcoding', + authenticate, + ensureUserHasRight(UserRight.RUN_VIDEO_TRANSCODING), + asyncMiddleware(createTranscodingValidator), + asyncMiddleware(createTranscoding) +) + +// --------------------------------------------------------------------------- + +export { + transcodingRouter +} + +// --------------------------------------------------------------------------- + +async function createTranscoding (req: express.Request, res: express.Response) { + const video = res.locals.videoAll + logger.info('Creating %s transcoding job for %s.', req.body.type, video.url, lTags()) + + const body: VideoTranscodingCreate = req.body + + const { resolution: maxResolution, isPortraitMode } = await video.getMaxQualityResolution() + const resolutions = computeLowerResolutionsToTranscode(maxResolution, 'vod').concat([ maxResolution ]) + + video.state = VideoState.TO_TRANSCODE + await video.save() + + for (const resolution of resolutions) { + if (body.transcodingType === 'hls') { + await addTranscodingJob({ + type: 'new-resolution-to-hls', + videoUUID: video.uuid, + resolution, + isPortraitMode, + copyCodecs: false, + isNewVideo: false, + autoDeleteWebTorrentIfNeeded: false, + isMaxQuality: maxResolution === resolution + }) + } else if (body.transcodingType === 'webtorrent') { + await addTranscodingJob({ + type: 'new-resolution-to-webtorrent', + videoUUID: video.uuid, + isNewVideo: false, + resolution: resolution, + isPortraitMode + }) + } + } + + return res.sendStatus(HttpStatusCode.NO_CONTENT_204) +} diff --git a/server/controllers/download.ts b/server/controllers/download.ts index 8da710669..43d525f83 100644 --- a/server/controllers/download.ts +++ b/server/controllers/download.ts @@ -85,7 +85,7 @@ async function downloadVideoFile (req: express.Request, res: express.Response) { return res.redirect(videoFile.getObjectStorageUrl()) } - await VideoPathManager.Instance.makeAvailableVideoFile(video, videoFile, path => { + await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), path => { const filename = `${video.name}-${videoFile.resolution}p${videoFile.extname}` return res.download(path, filename) @@ -119,7 +119,7 @@ async function downloadHLSVideoFile (req: express.Request, res: express.Response return res.redirect(videoFile.getObjectStorageUrl()) } - await VideoPathManager.Instance.makeAvailableVideoFile(streamingPlaylist, videoFile, path => { + await VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(streamingPlaylist), path => { const filename = `${video.name}-${videoFile.resolution}p-${streamingPlaylist.getStringType()}${videoFile.extname}` return res.download(path, filename) -- cgit v1.2.3