diff options
author | Chocobozzz <me@florianbigard.com> | 2019-05-21 10:05:12 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2019-05-21 10:05:12 +0200 |
commit | 73b3aa6429dfb2e31628fa09a479dce318289d7d (patch) | |
tree | 88cf5c7c49ba89c18633a4a64a4acfc8d40b4a50 /server/lib/video-transcoding.ts | |
parent | fd822c1c699fb89bb1c3218e047e1d842bc1ba1a (diff) | |
parent | 618750486ee2732e0ad3525349e4d42f29e1803e (diff) | |
download | PeerTube-73b3aa6429dfb2e31628fa09a479dce318289d7d.tar.gz PeerTube-73b3aa6429dfb2e31628fa09a479dce318289d7d.tar.zst PeerTube-73b3aa6429dfb2e31628fa09a479dce318289d7d.zip |
Merge branch 'feature/audio-upload' into develop
Diffstat (limited to 'server/lib/video-transcoding.ts')
-rw-r--r-- | server/lib/video-transcoding.ts | 88 |
1 files changed, 64 insertions, 24 deletions
diff --git a/server/lib/video-transcoding.ts b/server/lib/video-transcoding.ts index d6b6b251a..8d786e0ef 100644 --- a/server/lib/video-transcoding.ts +++ b/server/lib/video-transcoding.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSERVER } from '../initializers/constants' | 1 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSERVER } from '../initializers/constants' |
2 | import { join } from 'path' | 2 | import { join } from 'path' |
3 | import { getVideoFileFPS, transcode, canDoQuickTranscode } from '../helpers/ffmpeg-utils' | 3 | import { canDoQuickTranscode, getVideoFileFPS, transcode, TranscodeOptions, TranscodeOptionsType } from '../helpers/ffmpeg-utils' |
4 | import { ensureDir, move, remove, stat } from 'fs-extra' | 4 | import { ensureDir, move, remove, stat } from 'fs-extra' |
5 | import { logger } from '../helpers/logger' | 5 | import { logger } from '../helpers/logger' |
6 | import { VideoResolution } from '../../shared/models/videos' | 6 | import { VideoResolution } from '../../shared/models/videos' |
@@ -23,13 +23,15 @@ async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFi | |||
23 | const videoInputPath = join(videosDirectory, video.getVideoFilename(inputVideoFile)) | 23 | const videoInputPath = join(videosDirectory, video.getVideoFilename(inputVideoFile)) |
24 | const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) | 24 | const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) |
25 | 25 | ||
26 | const doQuickTranscode = await(canDoQuickTranscode(videoInputPath)) | 26 | const transcodeType: TranscodeOptionsType = await canDoQuickTranscode(videoInputPath) |
27 | ? 'quick-transcode' | ||
28 | : 'video' | ||
27 | 29 | ||
28 | const transcodeOptions = { | 30 | const transcodeOptions: TranscodeOptions = { |
31 | type: transcodeType as any, // FIXME: typing issue | ||
29 | inputPath: videoInputPath, | 32 | inputPath: videoInputPath, |
30 | outputPath: videoTranscodedPath, | 33 | outputPath: videoTranscodedPath, |
31 | resolution: inputVideoFile.resolution, | 34 | resolution: inputVideoFile.resolution |
32 | doQuickTranscode | ||
33 | } | 35 | } |
34 | 36 | ||
35 | // Could be very long! | 37 | // Could be very long! |
@@ -39,19 +41,11 @@ async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFi | |||
39 | await remove(videoInputPath) | 41 | await remove(videoInputPath) |
40 | 42 | ||
41 | // Important to do this before getVideoFilename() to take in account the new file extension | 43 | // Important to do this before getVideoFilename() to take in account the new file extension |
42 | inputVideoFile.set('extname', newExtname) | 44 | inputVideoFile.extname = newExtname |
43 | |||
44 | const stats = await stat(videoTranscodedPath) | ||
45 | const fps = await getVideoFileFPS(videoTranscodedPath) | ||
46 | 45 | ||
47 | const videoOutputPath = video.getVideoFilePath(inputVideoFile) | 46 | const videoOutputPath = video.getVideoFilePath(inputVideoFile) |
48 | await move(videoTranscodedPath, videoOutputPath) | ||
49 | 47 | ||
50 | inputVideoFile.set('size', stats.size) | 48 | await onVideoFileTranscoding(video, inputVideoFile, videoTranscodedPath, videoOutputPath) |
51 | inputVideoFile.set('fps', fps) | ||
52 | |||
53 | await video.createTorrentAndSetInfoHash(inputVideoFile) | ||
54 | await inputVideoFile.save() | ||
55 | } catch (err) { | 49 | } catch (err) { |
56 | // Auto destruction... | 50 | // Auto destruction... |
57 | video.destroy().catch(err => logger.error('Cannot destruct video after transcoding failure.', { err })) | 51 | video.destroy().catch(err => logger.error('Cannot destruct video after transcoding failure.', { err })) |
@@ -81,6 +75,7 @@ async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoR | |||
81 | const videoTranscodedPath = join(transcodeDirectory, video.getVideoFilename(newVideoFile)) | 75 | const videoTranscodedPath = join(transcodeDirectory, video.getVideoFilename(newVideoFile)) |
82 | 76 | ||
83 | const transcodeOptions = { | 77 | const transcodeOptions = { |
78 | type: 'video' as 'video', | ||
84 | inputPath: videoInputPath, | 79 | inputPath: videoInputPath, |
85 | outputPath: videoTranscodedPath, | 80 | outputPath: videoTranscodedPath, |
86 | resolution, | 81 | resolution, |
@@ -89,19 +84,37 @@ async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoR | |||
89 | 84 | ||
90 | await transcode(transcodeOptions) | 85 | await transcode(transcodeOptions) |
91 | 86 | ||
92 | const stats = await stat(videoTranscodedPath) | 87 | return onVideoFileTranscoding(video, newVideoFile, videoTranscodedPath, videoOutputPath) |
93 | const fps = await getVideoFileFPS(videoTranscodedPath) | 88 | } |
89 | |||
90 | async function mergeAudioVideofile (video: VideoModel, resolution: VideoResolution) { | ||
91 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR | ||
92 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR | ||
93 | const newExtname = '.mp4' | ||
94 | |||
95 | const inputVideoFile = video.getOriginalFile() | ||
94 | 96 | ||
95 | await move(videoTranscodedPath, videoOutputPath) | 97 | const audioInputPath = join(videosDirectory, video.getVideoFilename(video.getOriginalFile())) |
98 | const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) | ||
96 | 99 | ||
97 | newVideoFile.set('size', stats.size) | 100 | const transcodeOptions = { |
98 | newVideoFile.set('fps', fps) | 101 | type: 'merge-audio' as 'merge-audio', |
102 | inputPath: video.getPreview().getPath(), | ||
103 | outputPath: videoTranscodedPath, | ||
104 | audioPath: audioInputPath, | ||
105 | resolution | ||
106 | } | ||
99 | 107 | ||
100 | await video.createTorrentAndSetInfoHash(newVideoFile) | 108 | await transcode(transcodeOptions) |
101 | 109 | ||
102 | await newVideoFile.save() | 110 | await remove(audioInputPath) |
103 | 111 | ||
104 | video.VideoFiles.push(newVideoFile) | 112 | // Important to do this before getVideoFilename() to take in account the new file extension |
113 | inputVideoFile.extname = newExtname | ||
114 | |||
115 | const videoOutputPath = video.getVideoFilePath(inputVideoFile) | ||
116 | |||
117 | return onVideoFileTranscoding(video, inputVideoFile, videoTranscodedPath, videoOutputPath) | ||
105 | } | 118 | } |
106 | 119 | ||
107 | async function generateHlsPlaylist (video: VideoModel, resolution: VideoResolution, isPortraitMode: boolean) { | 120 | async function generateHlsPlaylist (video: VideoModel, resolution: VideoResolution, isPortraitMode: boolean) { |
@@ -112,6 +125,7 @@ async function generateHlsPlaylist (video: VideoModel, resolution: VideoResoluti | |||
112 | const outputPath = join(baseHlsDirectory, VideoStreamingPlaylistModel.getHlsPlaylistFilename(resolution)) | 125 | const outputPath = join(baseHlsDirectory, VideoStreamingPlaylistModel.getHlsPlaylistFilename(resolution)) |
113 | 126 | ||
114 | const transcodeOptions = { | 127 | const transcodeOptions = { |
128 | type: 'hls' as 'hls', | ||
115 | inputPath: videoInputPath, | 129 | inputPath: videoInputPath, |
116 | outputPath, | 130 | outputPath, |
117 | resolution, | 131 | resolution, |
@@ -140,8 +154,34 @@ async function generateHlsPlaylist (video: VideoModel, resolution: VideoResoluti | |||
140 | }) | 154 | }) |
141 | } | 155 | } |
142 | 156 | ||
157 | // --------------------------------------------------------------------------- | ||
158 | |||
143 | export { | 159 | export { |
144 | generateHlsPlaylist, | 160 | generateHlsPlaylist, |
145 | optimizeVideofile, | 161 | optimizeVideofile, |
146 | transcodeOriginalVideofile | 162 | transcodeOriginalVideofile, |
163 | mergeAudioVideofile | ||
164 | } | ||
165 | |||
166 | // --------------------------------------------------------------------------- | ||
167 | |||
168 | async function onVideoFileTranscoding (video: VideoModel, videoFile: VideoFileModel, transcodingPath: string, outputPath: string) { | ||
169 | const stats = await stat(transcodingPath) | ||
170 | const fps = await getVideoFileFPS(transcodingPath) | ||
171 | |||
172 | await move(transcodingPath, outputPath) | ||
173 | |||
174 | videoFile.set('size', stats.size) | ||
175 | videoFile.set('fps', fps) | ||
176 | |||
177 | await video.createTorrentAndSetInfoHash(videoFile) | ||
178 | |||
179 | const updatedVideoFile = await videoFile.save() | ||
180 | |||
181 | // Add it if this is a new created file | ||
182 | if (video.VideoFiles.some(f => f.id === videoFile.id) === false) { | ||
183 | video.VideoFiles.push(updatedVideoFile) | ||
184 | } | ||
185 | |||
186 | return video | ||
147 | } | 187 | } |