From 40298b02546e8225dd21bf6048fe7f224aefc32a Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Mon, 2 Oct 2017 12:20:26 +0200 Subject: Implement video transcoding on server side --- server/lib/jobs/handlers/index.ts | 6 +- server/lib/jobs/handlers/video-file-optimizer.ts | 78 +++++++++++++++++++++++ server/lib/jobs/handlers/video-file-transcoder.ts | 33 ++++++++++ server/lib/jobs/handlers/video-transcoder.ts | 34 ---------- 4 files changed, 115 insertions(+), 36 deletions(-) create mode 100644 server/lib/jobs/handlers/video-file-optimizer.ts create mode 100644 server/lib/jobs/handlers/video-file-transcoder.ts delete mode 100644 server/lib/jobs/handlers/video-transcoder.ts (limited to 'server/lib') diff --git a/server/lib/jobs/handlers/index.ts b/server/lib/jobs/handlers/index.ts index 8abddae35..5941427a1 100644 --- a/server/lib/jobs/handlers/index.ts +++ b/server/lib/jobs/handlers/index.ts @@ -1,4 +1,5 @@ -import * as videoTranscoder from './video-transcoder' +import * as videoFileOptimizer from './video-file-optimizer' +import * as videoFileTranscoder from './video-file-transcoder' export interface JobHandler { process (data: object): T @@ -7,7 +8,8 @@ export interface JobHandler { } const jobHandlers: { [ handlerName: string ]: JobHandler } = { - videoTranscoder + videoFileOptimizer, + videoFileTranscoder } export { diff --git a/server/lib/jobs/handlers/video-file-optimizer.ts b/server/lib/jobs/handlers/video-file-optimizer.ts new file mode 100644 index 000000000..a87ce52dc --- /dev/null +++ b/server/lib/jobs/handlers/video-file-optimizer.ts @@ -0,0 +1,78 @@ +import * as Promise from 'bluebird' + +import { database as db } from '../../../initializers/database' +import { logger, computeResolutionsToTranscode } from '../../../helpers' +import { VideoInstance } from '../../../models' +import { addVideoToFriends } from '../../friends' +import { JobScheduler } from '../job-scheduler' + +function process (data: { videoUUID: string }) { + return db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(data.videoUUID).then(video => { + return video.optimizeOriginalVideofile().then(() => video) + }) +} + +function onError (err: Error, jobId: number) { + logger.error('Error when optimized video file in job %d.', jobId, err) + return Promise.resolve() +} + +function onSuccess (jobId: number, video: VideoInstance) { + logger.info('Job %d is a success.', jobId) + + video.toAddRemoteJSON() + .then(remoteVideo => { + // Now we'll add the video's meta data to our friends + return addVideoToFriends(remoteVideo, null) + }) + .then(() => { + return video.getOriginalFileHeight() + }) + .then(originalFileHeight => { + // Create transcoding jobs if there are enabled resolutions + const resolutionsEnabled = computeResolutionsToTranscode(originalFileHeight) + logger.info( + 'Resolutions computed for video %s and origin file height of %d.', video.uuid, originalFileHeight, + { resolutions: resolutionsEnabled } + ) + + if (resolutionsEnabled.length === 0) return undefined + + return db.sequelize.transaction(t => { + const tasks: Promise[] = [] + + resolutionsEnabled.forEach(resolution => { + const dataInput = { + videoUUID: video.uuid, + resolution + } + + const p = JobScheduler.Instance.createJob(t, 'videoFileTranscoder', dataInput) + tasks.push(p) + }) + + return Promise.all(tasks).then(() => resolutionsEnabled) + }) + }) + .then(resolutionsEnabled => { + if (resolutionsEnabled === undefined) { + logger.info('No transcoding jobs created for video %s (no resolutions enabled).') + return undefined + } + + logger.info('Transcoding jobs created for uuid %s.', video.uuid, { resolutionsEnabled }) + }) + .catch((err: Error) => { + logger.debug('Cannot transcode the video.', err) + throw err + }) + +} + +// --------------------------------------------------------------------------- + +export { + process, + onError, + onSuccess +} diff --git a/server/lib/jobs/handlers/video-file-transcoder.ts b/server/lib/jobs/handlers/video-file-transcoder.ts new file mode 100644 index 000000000..0e45b4dca --- /dev/null +++ b/server/lib/jobs/handlers/video-file-transcoder.ts @@ -0,0 +1,33 @@ +import { database as db } from '../../../initializers/database' +import { updateVideoToFriends } from '../../friends' +import { logger } from '../../../helpers' +import { VideoInstance } from '../../../models' +import { VideoResolution } from '../../../../shared' + +function process (data: { videoUUID: string, resolution: VideoResolution }) { + return db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(data.videoUUID).then(video => { + return video.transcodeOriginalVideofile(data.resolution).then(() => video) + }) +} + +function onError (err: Error, jobId: number) { + logger.error('Error when transcoding video file in job %d.', jobId, err) + return Promise.resolve() +} + +function onSuccess (jobId: number, video: VideoInstance) { + logger.info('Job %d is a success.', jobId) + + const remoteVideo = video.toUpdateRemoteJSON() + + // Now we'll add the video's meta data to our friends + return updateVideoToFriends(remoteVideo, null) +} + +// --------------------------------------------------------------------------- + +export { + process, + onError, + onSuccess +} diff --git a/server/lib/jobs/handlers/video-transcoder.ts b/server/lib/jobs/handlers/video-transcoder.ts deleted file mode 100644 index 87d8ffa6a..000000000 --- a/server/lib/jobs/handlers/video-transcoder.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { database as db } from '../../../initializers/database' -import { logger } from '../../../helpers' -import { addVideoToFriends } from '../../../lib' -import { VideoInstance } from '../../../models' - -function process (data: { videoUUID: string }) { - return db.Video.loadByUUIDAndPopulateAuthorAndPodAndTags(data.videoUUID).then(video => { - // TODO: handle multiple resolutions - const videoFile = video.VideoFiles[0] - return video.transcodeVideofile(videoFile).then(() => video) - }) -} - -function onError (err: Error, jobId: number) { - logger.error('Error when transcoding video file in job %d.', jobId, err) - return Promise.resolve() -} - -function onSuccess (jobId: number, video: VideoInstance) { - logger.info('Job %d is a success.', jobId) - - video.toAddRemoteJSON().then(remoteVideo => { - // Now we'll add the video's meta data to our friends - return addVideoToFriends(remoteVideo, null) - }) -} - -// --------------------------------------------------------------------------- - -export { - process, - onError, - onSuccess -} -- cgit v1.2.3