mirror of
https://github.com/Chocobozzz/PeerTube.git
synced 2025-02-25 18:55:32 -06:00
Lock video files when generating storyboard
This commit is contained in:
parent
d299afeb2c
commit
1c9dc98c27
@ -21,75 +21,81 @@ async function processGenerateStoryboard (job: Job): Promise<void> {
|
|||||||
|
|
||||||
logger.info('Processing generate storyboard of %s in job %s.', payload.videoUUID, job.id, lTags)
|
logger.info('Processing generate storyboard of %s in job %s.', payload.videoUUID, job.id, lTags)
|
||||||
|
|
||||||
const video = await VideoModel.loadFull(payload.videoUUID)
|
const inputFileMutexReleaser = await VideoPathManager.Instance.lockFiles(payload.videoUUID)
|
||||||
if (!video) {
|
|
||||||
logger.info('Video %s does not exist anymore, skipping storyboard generation.', payload.videoUUID, lTags)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const inputFile = video.getMaxQualityFile()
|
try {
|
||||||
|
const video = await VideoModel.loadFull(payload.videoUUID)
|
||||||
await VideoPathManager.Instance.makeAvailableVideoFile(inputFile, async videoPath => {
|
if (!video) {
|
||||||
const isAudio = await isAudioFile(videoPath)
|
logger.info('Video %s does not exist anymore, skipping storyboard generation.', payload.videoUUID, lTags)
|
||||||
|
|
||||||
if (isAudio) {
|
|
||||||
logger.info('Do not generate a storyboard of %s since the video does not have a video stream', payload.videoUUID, lTags)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const ffmpeg = new FFmpegImage(getFFmpegCommandWrapperOptions('thumbnail'))
|
const inputFile = video.getMaxQualityFile()
|
||||||
|
|
||||||
const filename = generateImageFilename()
|
await VideoPathManager.Instance.makeAvailableVideoFile(inputFile, async videoPath => {
|
||||||
const destination = join(CONFIG.STORAGE.STORYBOARDS_DIR, filename)
|
const isAudio = await isAudioFile(videoPath)
|
||||||
|
|
||||||
const totalSprites = buildTotalSprites(video)
|
if (isAudio) {
|
||||||
if (totalSprites === 0) {
|
logger.info('Do not generate a storyboard of %s since the video does not have a video stream', payload.videoUUID, lTags)
|
||||||
logger.info('Do not generate a storyboard of %s because the video is not long enough', payload.videoUUID, lTags)
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const spriteDuration = Math.round(video.duration / totalSprites)
|
|
||||||
|
|
||||||
const spritesCount = findGridSize({
|
|
||||||
toFind: totalSprites,
|
|
||||||
maxEdgeCount: STORYBOARD.SPRITES_MAX_EDGE_COUNT
|
|
||||||
})
|
|
||||||
|
|
||||||
logger.debug(
|
|
||||||
'Generating storyboard from video of %s to %s', video.uuid, destination,
|
|
||||||
{ ...lTags, spritesCount, spriteDuration, videoDuration: video.duration }
|
|
||||||
)
|
|
||||||
|
|
||||||
await ffmpeg.generateStoryboardFromVideo({
|
|
||||||
destination,
|
|
||||||
path: videoPath,
|
|
||||||
sprites: {
|
|
||||||
size: STORYBOARD.SPRITE_SIZE,
|
|
||||||
count: spritesCount,
|
|
||||||
duration: spriteDuration
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ffmpeg = new FFmpegImage(getFFmpegCommandWrapperOptions('thumbnail'))
|
||||||
|
|
||||||
|
const filename = generateImageFilename()
|
||||||
|
const destination = join(CONFIG.STORAGE.STORYBOARDS_DIR, filename)
|
||||||
|
|
||||||
|
const totalSprites = buildTotalSprites(video)
|
||||||
|
if (totalSprites === 0) {
|
||||||
|
logger.info('Do not generate a storyboard of %s because the video is not long enough', payload.videoUUID, lTags)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const spriteDuration = Math.round(video.duration / totalSprites)
|
||||||
|
|
||||||
|
const spritesCount = findGridSize({
|
||||||
|
toFind: totalSprites,
|
||||||
|
maxEdgeCount: STORYBOARD.SPRITES_MAX_EDGE_COUNT
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.debug(
|
||||||
|
'Generating storyboard from video of %s to %s', video.uuid, destination,
|
||||||
|
{ ...lTags, spritesCount, spriteDuration, videoDuration: video.duration }
|
||||||
|
)
|
||||||
|
|
||||||
|
await ffmpeg.generateStoryboardFromVideo({
|
||||||
|
destination,
|
||||||
|
path: videoPath,
|
||||||
|
sprites: {
|
||||||
|
size: STORYBOARD.SPRITE_SIZE,
|
||||||
|
count: spritesCount,
|
||||||
|
duration: spriteDuration
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const imageSize = await getImageSize(destination)
|
||||||
|
|
||||||
|
const existing = await StoryboardModel.loadByVideo(video.id)
|
||||||
|
if (existing) await existing.destroy()
|
||||||
|
|
||||||
|
await StoryboardModel.create({
|
||||||
|
filename,
|
||||||
|
totalHeight: imageSize.height,
|
||||||
|
totalWidth: imageSize.width,
|
||||||
|
spriteHeight: STORYBOARD.SPRITE_SIZE.height,
|
||||||
|
spriteWidth: STORYBOARD.SPRITE_SIZE.width,
|
||||||
|
spriteDuration,
|
||||||
|
videoId: video.id
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.info('Storyboard generation %s ended for video %s.', destination, video.uuid, lTags)
|
||||||
})
|
})
|
||||||
|
|
||||||
const imageSize = await getImageSize(destination)
|
if (payload.federate) {
|
||||||
|
await federateVideoIfNeeded(video, false)
|
||||||
const existing = await StoryboardModel.loadByVideo(video.id)
|
}
|
||||||
if (existing) await existing.destroy()
|
} finally {
|
||||||
|
inputFileMutexReleaser()
|
||||||
await StoryboardModel.create({
|
|
||||||
filename,
|
|
||||||
totalHeight: imageSize.height,
|
|
||||||
totalWidth: imageSize.width,
|
|
||||||
spriteHeight: STORYBOARD.SPRITE_SIZE.height,
|
|
||||||
spriteWidth: STORYBOARD.SPRITE_SIZE.width,
|
|
||||||
spriteDuration,
|
|
||||||
videoId: video.id
|
|
||||||
})
|
|
||||||
|
|
||||||
logger.info('Storyboard generation %s ended for video %s.', destination, video.uuid, lTags)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (payload.federate) {
|
|
||||||
await federateVideoIfNeeded(video, false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user