diff --git a/server/lib/video-file.ts b/server/lib/video-file.ts index 8fcc3c253..88d48c945 100644 --- a/server/lib/video-file.ts +++ b/server/lib/video-file.ts @@ -8,6 +8,7 @@ import { ffprobePromise, getVideoStreamDimensionsInfo, getVideoStreamFPS, isAudi import { VideoFileMetadata, VideoResolution } from '@shared/models' import { lTags } from './object-storage/shared' import { generateHLSVideoFilename, generateWebTorrentVideoFilename } from './paths' +import { VideoPathManager } from './video-path-manager' async function buildNewFile (options: { path: string @@ -44,10 +45,16 @@ async function removeHLSPlaylist (video: MVideoWithAllFiles) { const hls = video.getHLSPlaylist() if (!hls) return - await video.removeStreamingPlaylistFiles(hls) - await hls.destroy() + const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) - video.VideoStreamingPlaylists = video.VideoStreamingPlaylists.filter(p => p.id !== hls.id) + try { + await video.removeStreamingPlaylistFiles(hls) + await hls.destroy() + + video.VideoStreamingPlaylists = video.VideoStreamingPlaylists.filter(p => p.id !== hls.id) + } finally { + videoFileMutexReleaser() + } } async function removeHLSFile (video: MVideoWithAllFiles, fileToDeleteId: number) { @@ -61,11 +68,17 @@ async function removeHLSFile (video: MVideoWithAllFiles, fileToDeleteId: number) return undefined } - const toDelete = files.find(f => f.id === fileToDeleteId) - await video.removeStreamingPlaylistVideoFile(video.getHLSPlaylist(), toDelete) - await toDelete.destroy() + const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) - hls.VideoFiles = hls.VideoFiles.filter(f => f.id !== toDelete.id) + try { + const toDelete = files.find(f => f.id === fileToDeleteId) + await video.removeStreamingPlaylistVideoFile(video.getHLSPlaylist(), toDelete) + await toDelete.destroy() + + hls.VideoFiles = hls.VideoFiles.filter(f => f.id !== toDelete.id) + } finally { + videoFileMutexReleaser() + } return hls } @@ -73,12 +86,18 @@ async function removeHLSFile (video: MVideoWithAllFiles, fileToDeleteId: number) // --------------------------------------------------------------------------- async function removeAllWebTorrentFiles (video: MVideoWithAllFiles) { - for (const file of video.VideoFiles) { - await video.removeWebTorrentFile(file) - await file.destroy() - } + const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) - video.VideoFiles = [] + try { + for (const file of video.VideoFiles) { + await video.removeWebTorrentFile(file) + await file.destroy() + } + + video.VideoFiles = [] + } finally { + videoFileMutexReleaser() + } return video } @@ -90,11 +109,16 @@ async function removeWebTorrentFile (video: MVideoWithAllFiles, fileToDeleteId: return removeAllWebTorrentFiles(video) } - const toDelete = files.find(f => f.id === fileToDeleteId) - await video.removeWebTorrentFile(toDelete) - await toDelete.destroy() + const videoFileMutexReleaser = await VideoPathManager.Instance.lockFiles(video.uuid) + try { + const toDelete = files.find(f => f.id === fileToDeleteId) + await video.removeWebTorrentFile(toDelete) + await toDelete.destroy() - video.VideoFiles = files.filter(f => f.id !== toDelete.id) + video.VideoFiles = files.filter(f => f.id !== toDelete.id) + } finally { + videoFileMutexReleaser() + } return video }