X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Ftranscoding%2Ftranscoding.ts;h=44e26754d52954e06fab0236ea3f98b8c3fe1a36;hb=367a9dc69975a0db01962dbb7106635fb8eb1696;hp=924141d1c6bfc39f7f9116dec2c37c137fb863f8;hpb=1bb4c9ab2e8b3b3022351b33a82a5e527fa5d4d7;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/transcoding/transcoding.ts b/server/lib/transcoding/transcoding.ts index 924141d1c..44e26754d 100644 --- a/server/lib/transcoding/transcoding.ts +++ b/server/lib/transcoding/transcoding.ts @@ -1,4 +1,4 @@ -import { Job } from 'bull' +import { Job } from 'bullmq' import { copyFile, ensureDir, move, remove, stat } from 'fs-extra' import { basename, extname as extnameUtil, join } from 'path' import { toEven } from '@server/helpers/core-utils' @@ -10,6 +10,7 @@ import { VideoResolution, VideoStorage } from '../../../shared/models/videos' import { buildFileMetadata, canDoQuickTranscode, + computeResolutionsToTranscode, getVideoStreamDuration, getVideoStreamFPS, transcodeVOD, @@ -32,7 +33,13 @@ import { VideoTranscodingProfilesManager } from './default-transcoding-profiles' */ // Optimize the original video file and replace it. The resolution is not changed. -function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile: MVideoFile, job?: Job) { +function optimizeOriginalVideofile (options: { + video: MVideoFullLight + inputVideoFile: MVideoFile + job: Job +}) { + const { video, inputVideoFile, job } = options + const transcodeDirectory = CONFIG.STORAGE.TMP_DIR const newExtname = '.mp4' @@ -43,7 +50,7 @@ function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile: MVid ? 'quick-transcode' : 'video' - const resolution = toEven(inputVideoFile.resolution) + const resolution = buildOriginalFileResolution(inputVideoFile.resolution) const transcodeOptions: TranscodeVODOptions = { type: transcodeType, @@ -63,6 +70,7 @@ function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile: MVid await transcodeVOD(transcodeOptions) // Important to do this before getVideoFilename() to take in account the new filename + inputVideoFile.resolution = resolution inputVideoFile.extname = newExtname inputVideoFile.filename = generateWebTorrentVideoFilename(resolution, newExtname) inputVideoFile.storage = VideoStorage.FILE_SYSTEM @@ -76,17 +84,22 @@ function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile: MVid }) } -// Transcode the original video file to a lower resolution -// We are sure it's x264 in mp4 because optimizeOriginalVideofile was already executed -function transcodeNewWebTorrentResolution (video: MVideoFullLight, resolution: VideoResolution, isPortrait: boolean, job: Job) { +// Transcode the original video file to a lower resolution compatible with WebTorrent +function transcodeNewWebTorrentResolution (options: { + video: MVideoFullLight + resolution: VideoResolution + job: Job +}) { + const { video, resolution, job } = options + const transcodeDirectory = CONFIG.STORAGE.TMP_DIR - const extname = '.mp4' + const newExtname = '.mp4' return VideoPathManager.Instance.makeAvailableVideoFile(video.getMaxQualityFile().withVideoOrPlaylist(video), async videoInputPath => { const newVideoFile = new VideoFileModel({ resolution, - extname, - filename: generateWebTorrentVideoFilename(resolution, extname), + extname: newExtname, + filename: generateWebTorrentVideoFilename(resolution, newExtname), size: 0, videoId: video.id }) @@ -117,7 +130,6 @@ function transcodeNewWebTorrentResolution (video: MVideoFullLight, resolution: V profile: CONFIG.TRANSCODING.PROFILE, resolution, - isPortraitMode: isPortrait, job } @@ -129,7 +141,13 @@ function transcodeNewWebTorrentResolution (video: MVideoFullLight, resolution: V } // Merge an image with an audio file to create a video -function mergeAudioVideofile (video: MVideoFullLight, resolution: VideoResolution, job: Job) { +function mergeAudioVideofile (options: { + video: MVideoFullLight + resolution: VideoResolution + job: Job +}) { + const { video, resolution, job } = options + const transcodeDirectory = CONFIG.STORAGE.TMP_DIR const newExtname = '.mp4' @@ -188,13 +206,11 @@ async function generateHlsPlaylistResolutionFromTS (options: { video: MVideo concatenatedTsFilePath: string resolution: VideoResolution - isPortraitMode: boolean isAAC: boolean }) { return generateHlsPlaylistCommon({ video: options.video, resolution: options.resolution, - isPortraitMode: options.isPortraitMode, inputPath: options.concatenatedTsFilePath, type: 'hls-from-ts' as 'hls-from-ts', isAAC: options.isAAC @@ -207,14 +223,12 @@ function generateHlsPlaylistResolution (options: { videoInputPath: string resolution: VideoResolution copyCodecs: boolean - isPortraitMode: boolean job?: Job }) { return generateHlsPlaylistCommon({ video: options.video, resolution: options.resolution, copyCodecs: options.copyCodecs, - isPortraitMode: options.isPortraitMode, inputPath: options.videoInputPath, type: 'hls' as 'hls', job: options.job @@ -267,11 +281,10 @@ async function generateHlsPlaylistCommon (options: { resolution: VideoResolution copyCodecs?: boolean isAAC?: boolean - isPortraitMode: boolean job?: Job }) { - const { type, video, inputPath, resolution, copyCodecs, isPortraitMode, isAAC, job } = options + const { type, video, inputPath, resolution, copyCodecs, isAAC, job } = options const transcodeDirectory = CONFIG.STORAGE.TMP_DIR const videoTranscodedBasePath = join(transcodeDirectory, type) @@ -292,7 +305,6 @@ async function generateHlsPlaylistCommon (options: { resolution, copyCodecs, - isPortraitMode, isAAC, @@ -330,6 +342,12 @@ async function generateHlsPlaylistCommon (options: { // Move video file await move(join(videoTranscodedBasePath, videoFilename), videoFilePath, { overwrite: true }) + // Update video duration if it was not set (in case of a live for example) + if (!video.duration) { + video.duration = await getVideoStreamDuration(videoFilePath) + await video.save() + } + const stats = await stat(videoFilePath) newVideoFile.size = stats.size @@ -350,3 +368,12 @@ async function generateHlsPlaylistCommon (options: { return { resolutionPlaylistPath, videoFile: savedVideoFile } } + +function buildOriginalFileResolution (inputResolution: number) { + if (CONFIG.TRANSCODING.ALWAYS_TRANSCODE_ORIGINAL_RESOLUTION === true) return toEven(inputResolution) + + const resolutions = computeResolutionsToTranscode({ input: inputResolution, type: 'vod', includeInput: false, strictLower: false }) + if (resolutions.length === 0) return toEven(inputResolution) + + return Math.max(...resolutions) +}