diff options
Diffstat (limited to 'server/lib/video-transcoding.ts')
-rw-r--r-- | server/lib/video-transcoding.ts | 81 |
1 files changed, 41 insertions, 40 deletions
diff --git a/server/lib/video-transcoding.ts b/server/lib/video-transcoding.ts index 4460f46e4..0fe0ff12a 100644 --- a/server/lib/video-transcoding.ts +++ b/server/lib/video-transcoding.ts | |||
@@ -1,11 +1,15 @@ | |||
1 | import { CONFIG } from '../initializers' | 1 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSERVER } from '../initializers/constants' |
2 | import { extname, join } from 'path' | 2 | import { join } from 'path' |
3 | import { getVideoFileFPS, getVideoFileResolution, transcode } from '../helpers/ffmpeg-utils' | 3 | import { getVideoFileFPS, transcode } from '../helpers/ffmpeg-utils' |
4 | import { copy, remove, move, 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' |
7 | import { VideoFileModel } from '../models/video/video-file' | 7 | import { VideoFileModel } from '../models/video/video-file' |
8 | import { VideoModel } from '../models/video/video' | 8 | import { VideoModel } from '../models/video/video' |
9 | import { updateMasterHLSPlaylist, updateSha256Segments } from './hls' | ||
10 | import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist' | ||
11 | import { VideoStreamingPlaylistType } from '../../shared/models/videos/video-streaming-playlist.type' | ||
12 | import { CONFIG } from '../initializers/config' | ||
9 | 13 | ||
10 | async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFileModel) { | 14 | async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFileModel) { |
11 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR | 15 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR |
@@ -17,7 +21,8 @@ async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFi | |||
17 | 21 | ||
18 | const transcodeOptions = { | 22 | const transcodeOptions = { |
19 | inputPath: videoInputPath, | 23 | inputPath: videoInputPath, |
20 | outputPath: videoTranscodedPath | 24 | outputPath: videoTranscodedPath, |
25 | resolution: inputVideoFile.resolution | ||
21 | } | 26 | } |
22 | 27 | ||
23 | // Could be very long! | 28 | // Could be very long! |
@@ -47,7 +52,7 @@ async function optimizeVideofile (video: VideoModel, inputVideoFileArg?: VideoFi | |||
47 | } | 52 | } |
48 | } | 53 | } |
49 | 54 | ||
50 | async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoResolution, isPortraitMode: boolean) { | 55 | async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoResolution, isPortrait: boolean) { |
51 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR | 56 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR |
52 | const extname = '.mp4' | 57 | const extname = '.mp4' |
53 | 58 | ||
@@ -60,13 +65,13 @@ async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoR | |||
60 | size: 0, | 65 | size: 0, |
61 | videoId: video.id | 66 | videoId: video.id |
62 | }) | 67 | }) |
63 | const videoOutputPath = join(videosDirectory, video.getVideoFilename(newVideoFile)) | 68 | const videoOutputPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename(newVideoFile)) |
64 | 69 | ||
65 | const transcodeOptions = { | 70 | const transcodeOptions = { |
66 | inputPath: videoInputPath, | 71 | inputPath: videoInputPath, |
67 | outputPath: videoOutputPath, | 72 | outputPath: videoOutputPath, |
68 | resolution, | 73 | resolution, |
69 | isPortraitMode | 74 | isPortraitMode: isPortrait |
70 | } | 75 | } |
71 | 76 | ||
72 | await transcode(transcodeOptions) | 77 | await transcode(transcodeOptions) |
@@ -84,48 +89,44 @@ async function transcodeOriginalVideofile (video: VideoModel, resolution: VideoR | |||
84 | video.VideoFiles.push(newVideoFile) | 89 | video.VideoFiles.push(newVideoFile) |
85 | } | 90 | } |
86 | 91 | ||
87 | async function importVideoFile (video: VideoModel, inputFilePath: string) { | 92 | async function generateHlsPlaylist (video: VideoModel, resolution: VideoResolution, isPortraitMode: boolean) { |
88 | const { videoFileResolution } = await getVideoFileResolution(inputFilePath) | 93 | const baseHlsDirectory = join(HLS_STREAMING_PLAYLIST_DIRECTORY, video.uuid) |
89 | const { size } = await stat(inputFilePath) | 94 | await ensureDir(join(HLS_STREAMING_PLAYLIST_DIRECTORY, video.uuid)) |
90 | const fps = await getVideoFileFPS(inputFilePath) | ||
91 | 95 | ||
92 | let updatedVideoFile = new VideoFileModel({ | 96 | const videoInputPath = join(CONFIG.STORAGE.VIDEOS_DIR, video.getVideoFilename(video.getOriginalFile())) |
93 | resolution: videoFileResolution, | 97 | const outputPath = join(baseHlsDirectory, VideoStreamingPlaylistModel.getHlsPlaylistFilename(resolution)) |
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 | 98 | ||
102 | if (currentVideoFile) { | 99 | const transcodeOptions = { |
103 | // Remove old file and old torrent | 100 | inputPath: videoInputPath, |
104 | await video.removeFile(currentVideoFile) | 101 | outputPath, |
105 | await video.removeTorrent(currentVideoFile) | 102 | resolution, |
106 | // Remove the old video file from the array | 103 | isPortraitMode, |
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 | 104 | ||
114 | updatedVideoFile = currentVideoFile | 105 | hlsPlaylist: { |
106 | videoFilename: VideoStreamingPlaylistModel.getHlsVideoName(video.uuid, resolution) | ||
107 | } | ||
115 | } | 108 | } |
116 | 109 | ||
117 | const outputPath = video.getVideoFilePath(updatedVideoFile) | 110 | await transcode(transcodeOptions) |
118 | await copy(inputFilePath, outputPath) | ||
119 | 111 | ||
120 | await video.createTorrentAndSetInfoHash(updatedVideoFile) | 112 | await updateMasterHLSPlaylist(video) |
113 | await updateSha256Segments(video) | ||
121 | 114 | ||
122 | await updatedVideoFile.save() | 115 | const playlistUrl = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsMasterPlaylistStaticPath(video.uuid) |
123 | 116 | ||
124 | video.VideoFiles.push(updatedVideoFile) | 117 | await VideoStreamingPlaylistModel.upsert({ |
118 | videoId: video.id, | ||
119 | playlistUrl, | ||
120 | segmentsSha256Url: WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsSha256SegmentsStaticPath(video.uuid), | ||
121 | p2pMediaLoaderInfohashes: VideoStreamingPlaylistModel.buildP2PMediaLoaderInfoHashes(playlistUrl, video.VideoFiles), | ||
122 | p2pMediaLoaderPeerVersion: P2P_MEDIA_LOADER_PEER_VERSION, | ||
123 | |||
124 | type: VideoStreamingPlaylistType.HLS | ||
125 | }) | ||
125 | } | 126 | } |
126 | 127 | ||
127 | export { | 128 | export { |
129 | generateHlsPlaylist, | ||
128 | optimizeVideofile, | 130 | optimizeVideofile, |
129 | transcodeOriginalVideofile, | 131 | transcodeOriginalVideofile |
130 | importVideoFile | ||
131 | } | 132 | } |