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