Stronger model typings
[oweals/peertube.git] / server / lib / job-queue / handlers / video-file-import.ts
1 import * as Bull from 'bull'
2 import { logger } from '../../../helpers/logger'
3 import { VideoModel } from '../../../models/video/video'
4 import { publishNewResolutionIfNeeded } from './video-transcoding'
5 import { getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffmpeg-utils'
6 import { copy, stat } from 'fs-extra'
7 import { VideoFileModel } from '../../../models/video/video-file'
8 import { extname } from 'path'
9 import { MVideoFile, MVideoWithFile } from '@server/typings/models'
10
11 export type VideoFileImportPayload = {
12   videoUUID: string,
13   filePath: string
14 }
15
16 async function processVideoFileImport (job: Bull.Job) {
17   const payload = job.data as VideoFileImportPayload
18   logger.info('Processing video file import in job %d.', job.id)
19
20   const video = await VideoModel.loadAndPopulateAccountAndServerAndTags(payload.videoUUID)
21   // No video, maybe deleted?
22   if (!video) {
23     logger.info('Do not process job %d, video does not exist.', job.id)
24     return undefined
25   }
26
27   await updateVideoFile(video, payload.filePath)
28
29   await publishNewResolutionIfNeeded(video)
30   return video
31 }
32
33 // ---------------------------------------------------------------------------
34
35 export {
36   processVideoFileImport
37 }
38
39 // ---------------------------------------------------------------------------
40
41 async function updateVideoFile (video: MVideoWithFile, inputFilePath: string) {
42   const { videoFileResolution } = await getVideoFileResolution(inputFilePath)
43   const { size } = await stat(inputFilePath)
44   const fps = await getVideoFileFPS(inputFilePath)
45
46   let updatedVideoFile = new VideoFileModel({
47     resolution: videoFileResolution,
48     extname: extname(inputFilePath),
49     size,
50     fps,
51     videoId: video.id
52   }) as MVideoFile
53
54   const currentVideoFile = video.VideoFiles.find(videoFile => videoFile.resolution === updatedVideoFile.resolution)
55
56   if (currentVideoFile) {
57     // Remove old file and old torrent
58     await video.removeFile(currentVideoFile)
59     await video.removeTorrent(currentVideoFile)
60     // Remove the old video file from the array
61     video.VideoFiles = video.VideoFiles.filter(f => f !== currentVideoFile)
62
63     // Update the database
64     currentVideoFile.extname = updatedVideoFile.extname
65     currentVideoFile.size = updatedVideoFile.size
66     currentVideoFile.fps = updatedVideoFile.fps
67
68     updatedVideoFile = currentVideoFile
69   }
70
71   const outputPath = video.getVideoFilePath(updatedVideoFile)
72   await copy(inputFilePath, outputPath)
73
74   await video.createTorrentAndSetInfoHash(updatedVideoFile)
75
76   await updatedVideoFile.save()
77
78   video.VideoFiles.push(updatedVideoFile)
79 }