diff --git a/server/lib/job-queue/handlers/video-file-import.ts b/server/lib/job-queue/handlers/video-file-import.ts new file mode 100644 index 000000000..921d9a083 --- /dev/null +++ b/server/lib/job-queue/handlers/video-file-import.ts @@ -0,0 +1,78 @@ +import * as Bull from 'bull' +import { logger } from '../../../helpers/logger' +import { VideoModel } from '../../../models/video/video' +import { publishVideoIfNeeded } from './video-transcoding' +import { getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils' +import { copy, stat } from 'fs-extra' +import { VideoFileModel } from '../../../models/video/video-file' +import { extname } from 'path' + +export type VideoFileImportPayload = { + videoUUID: string, + filePath: string +} + +async function processVideoFileImport (job: Bull.Job) { + const payload = job.data as VideoFileImportPayload + logger.info('Processing video file import in job %d.', job.id) + + const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(payload.videoUUID) + // No video, maybe deleted? + if (!video) { + logger.info('Do not process job %d, video does not exist.', job.id) + return undefined + } + + await updateVideoFile(video, payload.filePath) + + await publishVideoIfNeeded(video) + return video +} + +// --------------------------------------------------------------------------- + +export { + processVideoFileImport +} + +// --------------------------------------------------------------------------- + +async function updateVideoFile (video: VideoModel, inputFilePath: string) { + const { videoFileResolution } = await getVideoFileResolution(inputFilePath) + const { size } = await stat(inputFilePath) + const fps = await getVideoFileFPS(inputFilePath) + + let updatedVideoFile = new VideoFileModel({ + resolution: videoFileResolution, + extname: extname(inputFilePath), + size, + fps, + videoId: video.id + }) + + const currentVideoFile = video.VideoFiles.find(videoFile => videoFile.resolution === updatedVideoFile.resolution) + + if (currentVideoFile) { + // Remove old file and old torrent + await video.removeFile(currentVideoFile) + await video.removeTorrent(currentVideoFile) + // Remove the old video file from the array + video.VideoFiles = video.VideoFiles.filter(f => f !== currentVideoFile) + + // Update the database + currentVideoFile.set('extname', updatedVideoFile.extname) + currentVideoFile.set('size', updatedVideoFile.size) + currentVideoFile.set('fps', updatedVideoFile.fps) + + updatedVideoFile = currentVideoFile + } + + const outputPath = video.getVideoFilePath(updatedVideoFile) + await copy(inputFilePath, outputPath) + + await video.createTorrentAndSetInfoHash(updatedVideoFile) + + await updatedVideoFile.save() + + video.VideoFiles.push(updatedVideoFile) +} diff --git a/server/lib/job-queue/handlers/video-transcoding.ts b/server/lib/job-queue/handlers/video-transcoding.ts index ceee83f13..d9dad795e 100644 --- a/server/lib/job-queue/handlers/video-transcoding.ts +++ b/server/lib/job-queue/handlers/video-transcoding.ts @@ -5,10 +5,10 @@ import { VideoModel } from '../../../models/video/video' import { JobQueue } from '../job-queue' import { federateVideoIfNeeded } from '../../activitypub' import { retryTransactionWrapper } from '../../../helpers/database-utils' -import { sequelizeTypescript, CONFIG } from '../../../initializers' +import { CONFIG, sequelizeTypescript } from '../../../initializers' import * as Bluebird from 'bluebird' import { computeResolutionsToTranscode } from '../../../helpers/ffmpeg-utils' -import { generateHlsPlaylist, importVideoFile, optimizeVideofile, transcodeOriginalVideofile } from '../../video-transcoding' +import { generateHlsPlaylist, optimizeVideofile, transcodeOriginalVideofile } from '../../video-transcoding' import { Notifier } from '../../notifier' export type VideoTranscodingPayload = { @@ -19,28 +19,6 @@ export type VideoTranscodingPayload = { generateHlsPlaylist?: boolean } -export type VideoFileImportPayload = { - videoUUID: string, - filePath: string -} - -async function processVideoFileImport (job: Bull.Job) { - const payload = job.data as VideoFileImportPayload - logger.info('Processing video file import in job %d.', job.id) - - const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(payload.videoUUID) - // No video, maybe deleted? - if (!video) { - logger.info('Do not process job %d, video does not exist.', job.id) - return undefined - } - - await importVideoFile(video, payload.filePath) - - await onVideoFileTranscoderOrImportSuccess(video) - return video -} - async function processVideoTranscoding (job: Bull.Job) { const payload = job.data as VideoTranscodingPayload logger.info('Processing video file in job %d.', job.id) @@ -59,7 +37,7 @@ async function processVideoTranscoding (job: Bull.Job) { } else if (payload.resolution) { // Transcoding in other resolution await transcodeOriginalVideofile(video, payload.resolution, payload.isPortraitMode || false) - await retryTransactionWrapper(onVideoFileTranscoderOrImportSuccess, video, payload) + await retryTransactionWrapper(publishVideoIfNeeded, video, payload) } else { await optimizeVideofile(video) @@ -83,9 +61,7 @@ async function onHlsPlaylistGenerationSuccess (video: VideoModel) { }) } -async function onVideoFileTranscoderOrImportSuccess (video: VideoModel, payload?: VideoTranscodingPayload) { - if (video === undefined) return undefined - +async function publishVideoIfNeeded (video: VideoModel, payload?: VideoTranscodingPayload) { const { videoDatabase, videoPublished } = await sequelizeTypescript.transaction(async t => { // Maybe the video changed in database, refresh it let videoDatabase = await VideoModel.loadAndPopulateAccountAndServerAndTags(video.uuid, t) @@ -183,7 +159,7 @@ async function onVideoFileOptimizerSuccess (videoArg: VideoModel, payload: Video export { processVideoTranscoding, - processVideoFileImport + publishVideoIfNeeded } // --------------------------------------------------------------------------- diff --git a/server/lib/job-queue/job-queue.ts b/server/lib/job-queue/job-queue.ts index e73042163..cee0941c7 100644 --- a/server/lib/job-queue/job-queue.ts +++ b/server/lib/job-queue/job-queue.ts @@ -7,16 +7,12 @@ import { ActivitypubHttpBroadcastPayload, processActivityPubHttpBroadcast } from import { ActivitypubHttpFetcherPayload, processActivityPubHttpFetcher } from './handlers/activitypub-http-fetcher' import { ActivitypubHttpUnicastPayload, processActivityPubHttpUnicast } from './handlers/activitypub-http-unicast' import { EmailPayload, processEmail } from './handlers/email' -import { - processVideoFileImport, - processVideoTranscoding, - VideoFileImportPayload, - VideoTranscodingPayload -} from './handlers/video-transcoding' +import { processVideoTranscoding, VideoTranscodingPayload } from './handlers/video-transcoding' import { ActivitypubFollowPayload, processActivityPubFollow } from './handlers/activitypub-follow' import { processVideoImport, VideoImportPayload } from './handlers/video-import' import { processVideosViews } from './handlers/video-views' import { refreshAPObject, RefreshPayload } from './handlers/activitypub-refresher' +import { processVideoFileImport, VideoFileImportPayload } from './handlers/video-file-import' type CreateJobArgument = { type: 'activitypub-http-broadcast', payload: ActivitypubHttpBroadcastPayload } | diff --git a/server/lib/video-transcoding.ts b/server/lib/video-transcoding.ts index e932c0e55..c29e34ab5 100644 --- a/server/lib/video-transcoding.ts +++ b/server/lib/video-transcoding.ts @@ -1,7 +1,7 @@ import { CONFIG, HLS_STREAMING_PLAYLIST_DIRECTORY } from '../initializers' -import { extname, join } from 'path' -import { getVideoFileFPS, getVideoFileResolution, transcode } from '../helpers/ffmpeg-utils' -import { copy, ensureDir, move, remove, stat } from 'fs-extra' +import { join } from 'path' +import { getVideoFileFPS, transcode } from '../helpers/ffmpeg-utils' +import { ensureDir, move, remove, stat } from 'fs-extra' import { logger } from '../helpers/logger' import { VideoResolution } from '../../shared/models/videos' import { VideoFileModel } from '../models/video/video-file' @@ -123,49 +123,8 @@ async function generateHlsPlaylist (video: VideoModel, resolution: VideoResoluti }) } -async function importVideoFile (video: VideoModel, inputFilePath: string) { - const { videoFileResolution } = await getVideoFileResolution(inputFilePath) - const { size } = await stat(inputFilePath) - const fps = await getVideoFileFPS(inputFilePath) - - let updatedVideoFile = new VideoFileModel({ - resolution: videoFileResolution, - extname: extname(inputFilePath), - size, - fps, - videoId: video.id - }) - - const currentVideoFile = video.VideoFiles.find(videoFile => videoFile.resolution === updatedVideoFile.resolution) - - if (currentVideoFile) { - // Remove old file and old torrent - await video.removeFile(currentVideoFile) - await video.removeTorrent(currentVideoFile) - // Remove the old video file from the array - video.VideoFiles = video.VideoFiles.filter(f => f !== currentVideoFile) - - // Update the database - currentVideoFile.set('extname', updatedVideoFile.extname) - currentVideoFile.set('size', updatedVideoFile.size) - currentVideoFile.set('fps', updatedVideoFile.fps) - - updatedVideoFile = currentVideoFile - } - - const outputPath = video.getVideoFilePath(updatedVideoFile) - await copy(inputFilePath, outputPath) - - await video.createTorrentAndSetInfoHash(updatedVideoFile) - - await updatedVideoFile.save() - - video.VideoFiles.push(updatedVideoFile) -} - export { generateHlsPlaylist, optimizeVideofile, - transcodeOriginalVideofile, - importVideoFile + transcodeOriginalVideofile }