diff options
Diffstat (limited to 'server/lib/transcoding')
-rw-r--r-- | server/lib/transcoding/video-transcoding.ts | 81 |
1 files changed, 46 insertions, 35 deletions
diff --git a/server/lib/transcoding/video-transcoding.ts b/server/lib/transcoding/video-transcoding.ts index 1ad63baf3..d2a556360 100644 --- a/server/lib/transcoding/video-transcoding.ts +++ b/server/lib/transcoding/video-transcoding.ts | |||
@@ -10,11 +10,18 @@ import { transcode, TranscodeOptions, TranscodeOptionsType } from '../../helpers | |||
10 | import { canDoQuickTranscode, getDurationFromVideoFile, getMetadataFromFile, getVideoFileFPS } from '../../helpers/ffprobe-utils' | 10 | import { canDoQuickTranscode, getDurationFromVideoFile, getMetadataFromFile, getVideoFileFPS } from '../../helpers/ffprobe-utils' |
11 | import { logger } from '../../helpers/logger' | 11 | import { logger } from '../../helpers/logger' |
12 | import { CONFIG } from '../../initializers/config' | 12 | import { CONFIG } from '../../initializers/config' |
13 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSERVER } from '../../initializers/constants' | 13 | import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION } from '../../initializers/constants' |
14 | import { VideoFileModel } from '../../models/video/video-file' | 14 | import { VideoFileModel } from '../../models/video/video-file' |
15 | import { VideoStreamingPlaylistModel } from '../../models/video/video-streaming-playlist' | 15 | import { VideoStreamingPlaylistModel } from '../../models/video/video-streaming-playlist' |
16 | import { updateMasterHLSPlaylist, updateSha256VODSegments } from '../hls' | 16 | import { updateMasterHLSPlaylist, updateSha256VODSegments } from '../hls' |
17 | import { generateVideoFilename, generateVideoStreamingPlaylistName, getVideoFilePath } from '../video-paths' | 17 | import { |
18 | generateHLSMasterPlaylistFilename, | ||
19 | generateHlsSha256SegmentsFilename, | ||
20 | generateHLSVideoFilename, | ||
21 | generateWebTorrentVideoFilename, | ||
22 | getHlsResolutionPlaylistFilename, | ||
23 | getVideoFilePath | ||
24 | } from '../video-paths' | ||
18 | import { VideoTranscodingProfilesManager } from './video-transcoding-profiles' | 25 | import { VideoTranscodingProfilesManager } from './video-transcoding-profiles' |
19 | 26 | ||
20 | /** | 27 | /** |
@@ -60,7 +67,7 @@ async function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile | |||
60 | 67 | ||
61 | // Important to do this before getVideoFilename() to take in account the new filename | 68 | // Important to do this before getVideoFilename() to take in account the new filename |
62 | inputVideoFile.extname = newExtname | 69 | inputVideoFile.extname = newExtname |
63 | inputVideoFile.filename = generateVideoFilename(video, false, resolution, newExtname) | 70 | inputVideoFile.filename = generateWebTorrentVideoFilename(resolution, newExtname) |
64 | 71 | ||
65 | const videoOutputPath = getVideoFilePath(video, inputVideoFile) | 72 | const videoOutputPath = getVideoFilePath(video, inputVideoFile) |
66 | 73 | ||
@@ -86,7 +93,7 @@ async function transcodeNewWebTorrentResolution (video: MVideoFullLight, resolut | |||
86 | const newVideoFile = new VideoFileModel({ | 93 | const newVideoFile = new VideoFileModel({ |
87 | resolution, | 94 | resolution, |
88 | extname, | 95 | extname, |
89 | filename: generateVideoFilename(video, false, resolution, extname), | 96 | filename: generateWebTorrentVideoFilename(resolution, extname), |
90 | size: 0, | 97 | size: 0, |
91 | videoId: video.id | 98 | videoId: video.id |
92 | }) | 99 | }) |
@@ -169,7 +176,7 @@ async function mergeAudioVideofile (video: MVideoFullLight, resolution: VideoRes | |||
169 | 176 | ||
170 | // Important to do this before getVideoFilename() to take in account the new file extension | 177 | // Important to do this before getVideoFilename() to take in account the new file extension |
171 | inputVideoFile.extname = newExtname | 178 | inputVideoFile.extname = newExtname |
172 | inputVideoFile.filename = generateVideoFilename(video, false, inputVideoFile.resolution, newExtname) | 179 | inputVideoFile.filename = generateWebTorrentVideoFilename(inputVideoFile.resolution, newExtname) |
173 | 180 | ||
174 | const videoOutputPath = getVideoFilePath(video, inputVideoFile) | 181 | const videoOutputPath = getVideoFilePath(video, inputVideoFile) |
175 | // ffmpeg generated a new video file, so update the video duration | 182 | // ffmpeg generated a new video file, so update the video duration |
@@ -271,15 +278,15 @@ async function generateHlsPlaylistCommon (options: { | |||
271 | const videoTranscodedBasePath = join(transcodeDirectory, type) | 278 | const videoTranscodedBasePath = join(transcodeDirectory, type) |
272 | await ensureDir(videoTranscodedBasePath) | 279 | await ensureDir(videoTranscodedBasePath) |
273 | 280 | ||
274 | const videoFilename = generateVideoStreamingPlaylistName(video.uuid, resolution) | 281 | const videoFilename = generateHLSVideoFilename(resolution) |
275 | const playlistFilename = VideoStreamingPlaylistModel.getHlsPlaylistFilename(resolution) | 282 | const resolutionPlaylistFilename = getHlsResolutionPlaylistFilename(videoFilename) |
276 | const playlistFileTranscodePath = join(videoTranscodedBasePath, playlistFilename) | 283 | const resolutionPlaylistFileTranscodePath = join(videoTranscodedBasePath, resolutionPlaylistFilename) |
277 | 284 | ||
278 | const transcodeOptions = { | 285 | const transcodeOptions = { |
279 | type, | 286 | type, |
280 | 287 | ||
281 | inputPath, | 288 | inputPath, |
282 | outputPath: playlistFileTranscodePath, | 289 | outputPath: resolutionPlaylistFileTranscodePath, |
283 | 290 | ||
284 | availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(), | 291 | availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(), |
285 | profile: CONFIG.TRANSCODING.PROFILE, | 292 | profile: CONFIG.TRANSCODING.PROFILE, |
@@ -299,19 +306,23 @@ async function generateHlsPlaylistCommon (options: { | |||
299 | 306 | ||
300 | await transcode(transcodeOptions) | 307 | await transcode(transcodeOptions) |
301 | 308 | ||
302 | const playlistUrl = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsMasterPlaylistStaticPath(video.uuid) | ||
303 | |||
304 | // Create or update the playlist | 309 | // Create or update the playlist |
305 | const [ videoStreamingPlaylist ] = await VideoStreamingPlaylistModel.upsert({ | 310 | const playlist = await VideoStreamingPlaylistModel.loadOrGenerate(video) |
306 | videoId: video.id, | 311 | |
307 | playlistUrl, | 312 | if (!playlist.playlistFilename) { |
308 | segmentsSha256Url: WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsSha256SegmentsStaticPath(video.uuid, video.isLive), | 313 | playlist.playlistFilename = generateHLSMasterPlaylistFilename(video.isLive) |
309 | p2pMediaLoaderInfohashes: [], | 314 | } |
310 | p2pMediaLoaderPeerVersion: P2P_MEDIA_LOADER_PEER_VERSION, | 315 | |
316 | if (!playlist.segmentsSha256Filename) { | ||
317 | playlist.segmentsSha256Filename = generateHlsSha256SegmentsFilename(video.isLive) | ||
318 | } | ||
319 | |||
320 | playlist.p2pMediaLoaderInfohashes = [] | ||
321 | playlist.p2pMediaLoaderPeerVersion = P2P_MEDIA_LOADER_PEER_VERSION | ||
311 | 322 | ||
312 | type: VideoStreamingPlaylistType.HLS | 323 | playlist.type = VideoStreamingPlaylistType.HLS |
313 | }, { returning: true }) as [ MStreamingPlaylistFilesVideo, boolean ] | 324 | |
314 | videoStreamingPlaylist.Video = video | 325 | await playlist.save() |
315 | 326 | ||
316 | // Build the new playlist file | 327 | // Build the new playlist file |
317 | const extname = extnameUtil(videoFilename) | 328 | const extname = extnameUtil(videoFilename) |
@@ -319,20 +330,20 @@ async function generateHlsPlaylistCommon (options: { | |||
319 | resolution, | 330 | resolution, |
320 | extname, | 331 | extname, |
321 | size: 0, | 332 | size: 0, |
322 | filename: generateVideoFilename(video, true, resolution, extname), | 333 | filename: videoFilename, |
323 | fps: -1, | 334 | fps: -1, |
324 | videoStreamingPlaylistId: videoStreamingPlaylist.id | 335 | videoStreamingPlaylistId: playlist.id |
325 | }) | 336 | }) |
326 | 337 | ||
327 | const videoFilePath = getVideoFilePath(videoStreamingPlaylist, newVideoFile) | 338 | const videoFilePath = getVideoFilePath(playlist, newVideoFile) |
328 | 339 | ||
329 | // Move files from tmp transcoded directory to the appropriate place | 340 | // Move files from tmp transcoded directory to the appropriate place |
330 | const baseHlsDirectory = join(HLS_STREAMING_PLAYLIST_DIRECTORY, video.uuid) | 341 | const baseHlsDirectory = join(HLS_STREAMING_PLAYLIST_DIRECTORY, video.uuid) |
331 | await ensureDir(baseHlsDirectory) | 342 | await ensureDir(baseHlsDirectory) |
332 | 343 | ||
333 | // Move playlist file | 344 | // Move playlist file |
334 | const playlistPath = join(baseHlsDirectory, playlistFilename) | 345 | const resolutionPlaylistPath = join(baseHlsDirectory, resolutionPlaylistFilename) |
335 | await move(playlistFileTranscodePath, playlistPath, { overwrite: true }) | 346 | await move(resolutionPlaylistFileTranscodePath, resolutionPlaylistPath, { overwrite: true }) |
336 | // Move video file | 347 | // Move video file |
337 | await move(join(videoTranscodedBasePath, videoFilename), videoFilePath, { overwrite: true }) | 348 | await move(join(videoTranscodedBasePath, videoFilename), videoFilePath, { overwrite: true }) |
338 | 349 | ||
@@ -342,20 +353,20 @@ async function generateHlsPlaylistCommon (options: { | |||
342 | newVideoFile.fps = await getVideoFileFPS(videoFilePath) | 353 | newVideoFile.fps = await getVideoFileFPS(videoFilePath) |
343 | newVideoFile.metadata = await getMetadataFromFile(videoFilePath) | 354 | newVideoFile.metadata = await getMetadataFromFile(videoFilePath) |
344 | 355 | ||
345 | await createTorrentAndSetInfoHash(videoStreamingPlaylist, newVideoFile) | 356 | await createTorrentAndSetInfoHash(playlist, newVideoFile) |
346 | 357 | ||
347 | await VideoFileModel.customUpsert(newVideoFile, 'streaming-playlist', undefined) | 358 | await VideoFileModel.customUpsert(newVideoFile, 'streaming-playlist', undefined) |
348 | videoStreamingPlaylist.VideoFiles = await videoStreamingPlaylist.$get('VideoFiles') | ||
349 | 359 | ||
350 | videoStreamingPlaylist.p2pMediaLoaderInfohashes = VideoStreamingPlaylistModel.buildP2PMediaLoaderInfoHashes( | 360 | const playlistWithFiles = playlist as MStreamingPlaylistFilesVideo |
351 | playlistUrl, videoStreamingPlaylist.VideoFiles | 361 | playlistWithFiles.VideoFiles = await playlist.$get('VideoFiles') |
352 | ) | 362 | playlist.assignP2PMediaLoaderInfoHashes(video, playlistWithFiles.VideoFiles) |
353 | await videoStreamingPlaylist.save() | 363 | |
364 | await playlist.save() | ||
354 | 365 | ||
355 | video.setHLSPlaylist(videoStreamingPlaylist) | 366 | video.setHLSPlaylist(playlist) |
356 | 367 | ||
357 | await updateMasterHLSPlaylist(video) | 368 | await updateMasterHLSPlaylist(video, playlistWithFiles) |
358 | await updateSha256VODSegments(video) | 369 | await updateSha256VODSegments(video, playlistWithFiles) |
359 | 370 | ||
360 | return playlistPath | 371 | return resolutionPlaylistPath |
361 | } | 372 | } |