X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Fjob-queue%2Fhandlers%2Fvideo-live-ending.ts;h=c6263f55ac3df3093c3e38054b49a442d2f46bfb;hb=849f0fd3b2d00056a2c6252230814d6c2e3e3919;hp=10507fb837fe8af85e3bf777b97fe00ef1ea68b7;hpb=c8fa571f32b10c083fab07f28d2ef55895ef40af;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/job-queue/handlers/video-live-ending.ts b/server/lib/job-queue/handlers/video-live-ending.ts index 10507fb83..c6263f55a 100644 --- a/server/lib/job-queue/handlers/video-live-ending.ts +++ b/server/lib/job-queue/handlers/video-live-ending.ts @@ -1,10 +1,10 @@ -import { Job } from 'bull' +import { Job } from 'bullmq' import { readdir, remove } from 'fs-extra' import { join } from 'path' -import { ffprobePromise, getAudioStream, getVideoStreamDimensionsInfo, getVideoStreamDuration } from '@server/helpers/ffmpeg' +import { ffprobePromise, getAudioStream, getVideoStreamDimensionsInfo } from '@server/helpers/ffmpeg' import { getLocalVideoActivityPubUrl } from '@server/lib/activitypub/url' import { federateVideoIfNeeded } from '@server/lib/activitypub/videos' -import { cleanupPermanentLive, cleanupTMPLiveFiles, cleanupUnsavedNormalLive } from '@server/lib/live' +import { cleanupAndDestroyPermanentLive, cleanupTMPLiveFiles, cleanupUnsavedNormalLive } from '@server/lib/live' import { generateHLSMasterPlaylistFilename, generateHlsSha256SegmentsFilename, getLiveReplayBaseDirectory } from '@server/lib/paths' import { generateVideoMiniature } from '@server/lib/thumbnail' import { generateHlsPlaylistResolutionFromTS } from '@server/lib/transcoding/transcoding' @@ -18,6 +18,7 @@ import { VideoStreamingPlaylistModel } from '@server/models/video/video-streamin import { MVideo, MVideoLive, MVideoLiveSession, MVideoWithAllFiles } from '@server/types/models' import { ThumbnailType, VideoLiveEndingPayload, VideoState } from '@shared/models' import { logger, loggerTagsFactory } from '../../../helpers/logger' +import { VideoPathManager } from '@server/lib/video-path-manager' const lTags = loggerTagsFactory('live', 'job') @@ -34,13 +35,13 @@ async function processVideoLiveEnding (job: Job) { const live = await VideoLiveModel.loadByVideoId(payload.videoId) const liveSession = await VideoLiveSessionModel.load(payload.liveSessionId) - const permanentLive = live.permanentLive - if (!video || !live || !liveSession) { logError() return } + const permanentLive = live.permanentLive + liveSession.endingProcessed = true await liveSession.save() @@ -141,23 +142,22 @@ async function replaceLiveByReplay (options: { }) { const { video, liveSession, live, permanentLive, replayDirectory } = options - await cleanupTMPLiveFiles(video) + const videoWithFiles = await VideoModel.loadFull(video.id) + const hlsPlaylist = videoWithFiles.getHLSPlaylist() + + await cleanupTMPLiveFiles(videoWithFiles, hlsPlaylist) await live.destroy() - video.isLive = false - video.waitTranscoding = true - video.state = VideoState.TO_TRANSCODE + videoWithFiles.isLive = false + videoWithFiles.waitTranscoding = true + videoWithFiles.state = VideoState.TO_TRANSCODE - await video.save() + await videoWithFiles.save() - liveSession.replayVideoId = video.id + liveSession.replayVideoId = videoWithFiles.id await liveSession.save() - // Remove old HLS playlist video files - const videoWithFiles = await VideoModel.loadFull(video.id) - - const hlsPlaylist = videoWithFiles.getHLSPlaylist() await VideoFileModel.removeHLSFilesOfVideoId(hlsPlaylist.id) // Reset playlist @@ -203,32 +203,30 @@ async function assignReplayFilesToVideo (options: { }) { const { video, replayDirectory } = options - let durationDone = false - const concatenatedTsFiles = await readdir(replayDirectory) for (const concatenatedTsFile of concatenatedTsFiles) { + const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) + const concatenatedTsFilePath = join(replayDirectory, concatenatedTsFile) const probe = await ffprobePromise(concatenatedTsFilePath) const { audioStream } = await getAudioStream(concatenatedTsFilePath, probe) - - const { resolution, isPortraitMode } = await getVideoStreamDimensionsInfo(concatenatedTsFilePath, probe) - - const { resolutionPlaylistPath: outputPath } = await generateHlsPlaylistResolutionFromTS({ - video, - concatenatedTsFilePath, - resolution, - isPortraitMode, - isAAC: audioStream?.codec_name === 'aac' - }) - - if (!durationDone) { - video.duration = await getVideoStreamDuration(outputPath) - await video.save() - - durationDone = true + const { resolution } = await getVideoStreamDimensionsInfo(concatenatedTsFilePath, probe) + + try { + await generateHlsPlaylistResolutionFromTS({ + video, + inputFileMutexReleaser, + concatenatedTsFilePath, + resolution, + isAAC: audioStream?.codec_name === 'aac' + }) + } catch (err) { + logger.error('Cannot generate HLS playlist resolution from TS files.', { err }) } + + inputFileMutexReleaser() } return video @@ -245,7 +243,7 @@ async function cleanupLiveAndFederate (options: { if (streamingPlaylist) { if (permanentLive) { - await cleanupPermanentLive(video, streamingPlaylist) + await cleanupAndDestroyPermanentLive(video, streamingPlaylist) } else { await cleanupUnsavedNormalLive(video, streamingPlaylist) }