]>
Commit | Line | Data |
---|---|---|
098eb377 C |
1 | import { CONFIG } from '../initializers' |
2 | import { join, extname } from 'path' | |
3 | import { getVideoFileFPS, getVideoFileResolution, transcode } from '../helpers/ffmpeg-utils' | |
4 | import { copy, remove, rename, stat } from 'fs-extra' | |
5 | import { logger } from '../helpers/logger' | |
6 | import { VideoResolution } from '../../shared/models/videos' | |
7 | import { VideoFileModel } from '../models/video/video-file' | |
8 | import { VideoModel } from '../models/video/video' | |
9 | ||
10 | async function optimizeOriginalVideofile (video: VideoModel) { | |
11 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR | |
12 | const newExtname = '.mp4' | |
13 | const inputVideoFile = video.getOriginalFile() | |
14 | const videoInputPath = join(videosDirectory, video.getVideoFilename(inputVideoFile)) | |
15 | const videoTranscodedPath = join(videosDirectory, video.id + '-transcoded' + newExtname) | |
16 | ||
17 | const transcodeOptions = { | |
18 | inputPath: videoInputPath, | |
19 | outputPath: videoTranscodedPath | |
20 | } | |
21 | ||
22 | // Could be very long! | |
23 | await transcode(transcodeOptions) | |
24 | ||
25 | try { | |
26 | await remove(videoInputPath) | |
27 | ||
28 | // Important to do this before getVideoFilename() to take in account the new file extension | |
29 | inputVideoFile.set('extname', newExtname) | |
30 | ||
31 | const videoOutputPath = video.getVideoFilePath(inputVideoFile) | |
32 | await rename(videoTranscodedPath, videoOutputPath) | |
33 | const stats = await stat(videoOutputPath) | |
34 | const fps = await getVideoFileFPS(videoOutputPath) | |
35 | ||
36 | inputVideoFile.set('size', stats.size) | |
37 | inputVideoFile.set('fps', fps) | |
38 | ||
39 | await video.createTorrentAndSetInfoHash(inputVideoFile) | |
40 | await inputVideoFile.save() | |
41 | } catch (err) { | |
42 | // Auto destruction... | |
43 | video.destroy().catch(err => logger.error('Cannot destruct video after transcoding failure.', { err })) | |
44 | ||
45 | throw err | |
46 | } | |
47 | } | |
48 | ||
49 | async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoResolution, isPortraitMode: boolean) { | |
50 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR | |
51 | const extname = '.mp4' | |
52 | ||
53 | // We are sure it's x264 in mp4 because optimizeOriginalVideofile was already executed | |
54 | const videoInputPath = join(videosDirectory, video.getVideoFilename(video.getOriginalFile())) | |
55 | ||
56 | const newVideoFile = new VideoFileModel({ | |
57 | resolution, | |
58 | extname, | |
59 | size: 0, | |
60 | videoId: video.id | |
61 | }) | |
62 | const videoOutputPath = join(videosDirectory, video.getVideoFilename(newVideoFile)) | |
63 | ||
64 | const transcodeOptions = { | |
65 | inputPath: videoInputPath, | |
66 | outputPath: videoOutputPath, | |
67 | resolution, | |
68 | isPortraitMode | |
69 | } | |
70 | ||
71 | await transcode(transcodeOptions) | |
72 | ||
73 | const stats = await stat(videoOutputPath) | |
74 | const fps = await getVideoFileFPS(videoOutputPath) | |
75 | ||
76 | newVideoFile.set('size', stats.size) | |
77 | newVideoFile.set('fps', fps) | |
78 | ||
79 | await video.createTorrentAndSetInfoHash(newVideoFile) | |
80 | ||
81 | await newVideoFile.save() | |
82 | ||
83 | video.VideoFiles.push(newVideoFile) | |
84 | } | |
85 | ||
86 | async function importVideoFile (video: VideoModel, inputFilePath: string) { | |
87 | const { videoFileResolution } = await getVideoFileResolution(inputFilePath) | |
88 | const { size } = await stat(inputFilePath) | |
89 | const fps = await getVideoFileFPS(inputFilePath) | |
90 | ||
91 | let updatedVideoFile = new VideoFileModel({ | |
92 | resolution: videoFileResolution, | |
93 | extname: extname(inputFilePath), | |
94 | size, | |
95 | fps, | |
96 | videoId: video.id | |
97 | }) | |
98 | ||
99 | const currentVideoFile = video.VideoFiles.find(videoFile => videoFile.resolution === updatedVideoFile.resolution) | |
100 | ||
101 | if (currentVideoFile) { | |
102 | // Remove old file and old torrent | |
103 | await video.removeFile(currentVideoFile) | |
104 | await video.removeTorrent(currentVideoFile) | |
105 | // Remove the old video file from the array | |
106 | video.VideoFiles = video.VideoFiles.filter(f => f !== currentVideoFile) | |
107 | ||
108 | // Update the database | |
109 | currentVideoFile.set('extname', updatedVideoFile.extname) | |
110 | currentVideoFile.set('size', updatedVideoFile.size) | |
111 | currentVideoFile.set('fps', updatedVideoFile.fps) | |
112 | ||
113 | updatedVideoFile = currentVideoFile | |
114 | } | |
115 | ||
116 | const outputPath = video.getVideoFilePath(updatedVideoFile) | |
117 | await copy(inputFilePath, outputPath) | |
118 | ||
119 | await video.createTorrentAndSetInfoHash(updatedVideoFile) | |
120 | ||
121 | await updatedVideoFile.save() | |
122 | ||
123 | video.VideoFiles.push(updatedVideoFile) | |
124 | } | |
125 | ||
126 | export { | |
127 | optimizeOriginalVideofile, | |
128 | transcodeOriginalVideofile, | |
129 | importVideoFile | |
130 | } |