]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/lib/video-transcoding.ts
Cleanup
[github/Chocobozzz/PeerTube.git] / server / lib / video-transcoding.ts
index c4b3425d1e86edbac831d5f10362048337f74d98..c949dca2ef035c4b7eb4b4db78624b14f1105242 100644 (file)
@@ -2,7 +2,7 @@ import { Job } from 'bull'
 import { copyFile, ensureDir, move, remove, stat } from 'fs-extra'
 import { basename, extname as extnameUtil, join } from 'path'
 import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
-import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoWithAllFiles, MVideoWithFile } from '@server/types/models'
+import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models'
 import { VideoResolution } from '../../shared/models/videos'
 import { VideoStreamingPlaylistType } from '../../shared/models/videos/video-streaming-playlist.type'
 import { transcode, TranscodeOptions, TranscodeOptionsType } from '../helpers/ffmpeg-utils'
@@ -13,7 +13,7 @@ import { HLS_STREAMING_PLAYLIST_DIRECTORY, P2P_MEDIA_LOADER_PEER_VERSION, WEBSER
 import { VideoFileModel } from '../models/video/video-file'
 import { VideoStreamingPlaylistModel } from '../models/video/video-streaming-playlist'
 import { updateMasterHLSPlaylist, updateSha256VODSegments } from './hls'
-import { generateVideoStreamingPlaylistName, getVideoFilename, getVideoFilePath } from './video-paths'
+import { generateVideoFilename, generateVideoStreamingPlaylistName, getVideoFilePath } from './video-paths'
 import { VideoTranscodingProfilesManager } from './video-transcoding-profiles'
 
 /**
@@ -24,7 +24,7 @@ import { VideoTranscodingProfilesManager } from './video-transcoding-profiles'
  */
 
 // Optimize the original video file and replace it. The resolution is not changed.
-async function optimizeOriginalVideofile (video: MVideoWithFile, inputVideoFile: MVideoFile, job?: Job) {
+async function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile: MVideoFile, job?: Job) {
   const transcodeDirectory = CONFIG.STORAGE.TMP_DIR
   const newExtname = '.mp4'
 
@@ -42,7 +42,7 @@ async function optimizeOriginalVideofile (video: MVideoWithFile, inputVideoFile:
     outputPath: videoTranscodedPath,
 
     availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
-    profile: 'default',
+    profile: CONFIG.TRANSCODING.PROFILE,
 
     resolution: inputVideoFile.resolution,
 
@@ -55,8 +55,9 @@ async function optimizeOriginalVideofile (video: MVideoWithFile, inputVideoFile:
   try {
     await remove(videoInputPath)
 
-    // Important to do this before getVideoFilename() to take in account the new file extension
+    // Important to do this before getVideoFilename() to take in account the new filename
     inputVideoFile.extname = newExtname
+    inputVideoFile.filename = generateVideoFilename(video, false, inputVideoFile.resolution, newExtname)
 
     const videoOutputPath = getVideoFilePath(video, inputVideoFile)
 
@@ -72,7 +73,7 @@ async function optimizeOriginalVideofile (video: MVideoWithFile, inputVideoFile:
 }
 
 // Transcode the original video file to a lower resolution.
-async function transcodeNewWebTorrentResolution (video: MVideoWithFile, resolution: VideoResolution, isPortrait: boolean, job: Job) {
+async function transcodeNewWebTorrentResolution (video: MVideoFullLight, resolution: VideoResolution, isPortrait: boolean, job: Job) {
   const transcodeDirectory = CONFIG.STORAGE.TMP_DIR
   const extname = '.mp4'
 
@@ -82,11 +83,13 @@ async function transcodeNewWebTorrentResolution (video: MVideoWithFile, resoluti
   const newVideoFile = new VideoFileModel({
     resolution,
     extname,
+    filename: generateVideoFilename(video, false, resolution, extname),
     size: 0,
     videoId: video.id
   })
+
   const videoOutputPath = getVideoFilePath(video, newVideoFile)
-  const videoTranscodedPath = join(transcodeDirectory, getVideoFilename(video, newVideoFile))
+  const videoTranscodedPath = join(transcodeDirectory, newVideoFile.filename)
 
   const transcodeOptions = resolution === VideoResolution.H_NOVIDEO
     ? {
@@ -96,7 +99,7 @@ async function transcodeNewWebTorrentResolution (video: MVideoWithFile, resoluti
       outputPath: videoTranscodedPath,
 
       availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
-      profile: 'default',
+      profile: CONFIG.TRANSCODING.PROFILE,
 
       resolution,
 
@@ -108,7 +111,7 @@ async function transcodeNewWebTorrentResolution (video: MVideoWithFile, resoluti
       outputPath: videoTranscodedPath,
 
       availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
-      profile: 'default',
+      profile: CONFIG.TRANSCODING.PROFILE,
 
       resolution,
       isPortraitMode: isPortrait,
@@ -122,7 +125,7 @@ async function transcodeNewWebTorrentResolution (video: MVideoWithFile, resoluti
 }
 
 // Merge an image with an audio file to create a video
-async function mergeAudioVideofile (video: MVideoWithAllFiles, resolution: VideoResolution, job: Job) {
+async function mergeAudioVideofile (video: MVideoFullLight, resolution: VideoResolution, job: Job) {
   const transcodeDirectory = CONFIG.STORAGE.TMP_DIR
   const newExtname = '.mp4'
 
@@ -143,7 +146,7 @@ async function mergeAudioVideofile (video: MVideoWithAllFiles, resolution: Video
     outputPath: videoTranscodedPath,
 
     availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
-    profile: 'default',
+    profile: CONFIG.TRANSCODING.PROFILE,
 
     audioPath: audioInputPath,
     resolution,
@@ -163,6 +166,7 @@ async function mergeAudioVideofile (video: MVideoWithAllFiles, resolution: Video
 
   // Important to do this before getVideoFilename() to take in account the new file extension
   inputVideoFile.extname = newExtname
+  inputVideoFile.filename = generateVideoFilename(video, false, inputVideoFile.resolution, newExtname)
 
   const videoOutputPath = getVideoFilePath(video, inputVideoFile)
   // ffmpeg generated a new video file, so update the video duration
@@ -175,7 +179,7 @@ async function mergeAudioVideofile (video: MVideoWithAllFiles, resolution: Video
 
 // Concat TS segments from a live video to a fragmented mp4 HLS playlist
 async function generateHlsPlaylistResolutionFromTS (options: {
-  video: MVideoWithFile
+  video: MVideoFullLight
   concatenatedTsFilePath: string
   resolution: VideoResolution
   isPortraitMode: boolean
@@ -193,7 +197,7 @@ async function generateHlsPlaylistResolutionFromTS (options: {
 
 // Generate an HLS playlist from an input file, and update the master playlist
 function generateHlsPlaylistResolution (options: {
-  video: MVideoWithFile
+  video: MVideoFullLight
   videoInputPath: string
   resolution: VideoResolution
   copyCodecs: boolean
@@ -235,7 +239,7 @@ export {
 // ---------------------------------------------------------------------------
 
 async function onWebTorrentVideoFileTranscoding (
-  video: MVideoWithFile,
+  video: MVideoFullLight,
   videoFile: MVideoFile,
   transcodingPath: string,
   outputPath: string
@@ -260,7 +264,7 @@ async function onWebTorrentVideoFileTranscoding (
 
 async function generateHlsPlaylistCommon (options: {
   type: 'hls' | 'hls-from-ts'
-  video: MVideoWithFile
+  video: MVideoFullLight
   inputPath: string
   resolution: VideoResolution
   copyCodecs?: boolean
@@ -270,21 +274,23 @@ async function generateHlsPlaylistCommon (options: {
   job?: Job
 }) {
   const { type, video, inputPath, resolution, copyCodecs, isPortraitMode, isAAC, job } = options
+  const transcodeDirectory = CONFIG.STORAGE.TMP_DIR
 
-  const baseHlsDirectory = join(HLS_STREAMING_PLAYLIST_DIRECTORY, video.uuid)
-  await ensureDir(join(HLS_STREAMING_PLAYLIST_DIRECTORY, video.uuid))
+  const videoTranscodedBasePath = join(transcodeDirectory, type)
+  await ensureDir(videoTranscodedBasePath)
 
-  const outputPath = join(baseHlsDirectory, VideoStreamingPlaylistModel.getHlsPlaylistFilename(resolution))
   const videoFilename = generateVideoStreamingPlaylistName(video.uuid, resolution)
+  const playlistFilename = VideoStreamingPlaylistModel.getHlsPlaylistFilename(resolution)
+  const playlistFileTranscodePath = join(videoTranscodedBasePath, playlistFilename)
 
   const transcodeOptions = {
     type,
 
     inputPath,
-    outputPath,
+    outputPath: playlistFileTranscodePath,
 
     availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
-    profile: 'default',
+    profile: CONFIG.TRANSCODING.PROFILE,
 
     resolution,
     copyCodecs,
@@ -303,6 +309,7 @@ async function generateHlsPlaylistCommon (options: {
 
   const playlistUrl = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsMasterPlaylistStaticPath(video.uuid)
 
+  // Create or update the playlist
   const [ videoStreamingPlaylist ] = await VideoStreamingPlaylistModel.upsert({
     videoId: video.id,
     playlistUrl,
@@ -314,15 +321,29 @@ async function generateHlsPlaylistCommon (options: {
   }, { returning: true }) as [ MStreamingPlaylistFilesVideo, boolean ]
   videoStreamingPlaylist.Video = video
 
+  // Build the new playlist file
+  const extname = extnameUtil(videoFilename)
   const newVideoFile = new VideoFileModel({
     resolution,
-    extname: extnameUtil(videoFilename),
+    extname,
     size: 0,
+    filename: generateVideoFilename(video, true, resolution, extname),
     fps: -1,
     videoStreamingPlaylistId: videoStreamingPlaylist.id
   })
 
   const videoFilePath = getVideoFilePath(videoStreamingPlaylist, newVideoFile)
+
+  // Move files from tmp transcoded directory to the appropriate place
+  const baseHlsDirectory = join(HLS_STREAMING_PLAYLIST_DIRECTORY, video.uuid)
+  await ensureDir(baseHlsDirectory)
+
+  // Move playlist file
+  const playlistPath = join(baseHlsDirectory, playlistFilename)
+  await move(playlistFileTranscodePath, playlistPath, { overwrite: true })
+  // Move video file
+  await move(join(videoTranscodedBasePath, videoFilename), videoFilePath, { overwrite: true })
+
   const stats = await stat(videoFilePath)
 
   newVideoFile.size = stats.size
@@ -344,5 +365,5 @@ async function generateHlsPlaylistCommon (options: {
   await updateMasterHLSPlaylist(video)
   await updateSha256VODSegments(video)
 
-  return outputPath
+  return playlistPath
 }