diff options
author | Chocobozzz <me@florianbigard.com> | 2021-11-18 14:35:08 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-11-18 15:20:57 +0100 |
commit | ad5db1044c8599eaaaa2a578b350777ae996b068 (patch) | |
tree | 3e003cccf021152405d49b21c6c91b703c8ae96c /server/lib | |
parent | b46cf4b920984492df598c1b61179acfc7f6f22e (diff) | |
download | PeerTube-ad5db1044c8599eaaaa2a578b350777ae996b068.tar.gz PeerTube-ad5db1044c8599eaaaa2a578b350777ae996b068.tar.zst PeerTube-ad5db1044c8599eaaaa2a578b350777ae996b068.zip |
Add ability to run transcoding jobs
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/hls.ts | 7 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/move-to-object-storage.ts | 11 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-transcoding.ts | 10 | ||||
-rw-r--r-- | server/lib/live/live-manager.ts | 4 | ||||
-rw-r--r-- | server/lib/object-storage/keys.ts | 10 | ||||
-rw-r--r-- | server/lib/object-storage/videos.ts | 16 | ||||
-rw-r--r-- | server/lib/thumbnail.ts | 2 | ||||
-rw-r--r-- | server/lib/transcoding/video-transcoding.ts | 6 | ||||
-rw-r--r-- | server/lib/video-path-manager.ts | 26 | ||||
-rw-r--r-- | server/lib/video-state.ts | 2 | ||||
-rw-r--r-- | server/lib/video.ts | 2 |
11 files changed, 56 insertions, 40 deletions
diff --git a/server/lib/hls.ts b/server/lib/hls.ts index 8160e7949..d969549b8 100644 --- a/server/lib/hls.ts +++ b/server/lib/hls.ts | |||
@@ -37,7 +37,7 @@ async function updateMasterHLSPlaylist (video: MVideo, playlist: MStreamingPlayl | |||
37 | for (const file of playlist.VideoFiles) { | 37 | for (const file of playlist.VideoFiles) { |
38 | const playlistFilename = getHlsResolutionPlaylistFilename(file.filename) | 38 | const playlistFilename = getHlsResolutionPlaylistFilename(file.filename) |
39 | 39 | ||
40 | await VideoPathManager.Instance.makeAvailableVideoFile(playlist, file, async videoFilePath => { | 40 | await VideoPathManager.Instance.makeAvailableVideoFile(file.withVideoOrPlaylist(playlist), async videoFilePath => { |
41 | const size = await getVideoStreamSize(videoFilePath) | 41 | const size = await getVideoStreamSize(videoFilePath) |
42 | 42 | ||
43 | const bandwidth = 'BANDWIDTH=' + video.getBandwidthBits(file) | 43 | const bandwidth = 'BANDWIDTH=' + video.getBandwidthBits(file) |
@@ -69,10 +69,11 @@ async function updateSha256VODSegments (video: MVideoUUID, playlist: MStreamingP | |||
69 | // For all the resolutions available for this video | 69 | // For all the resolutions available for this video |
70 | for (const file of playlist.VideoFiles) { | 70 | for (const file of playlist.VideoFiles) { |
71 | const rangeHashes: { [range: string]: string } = {} | 71 | const rangeHashes: { [range: string]: string } = {} |
72 | const fileWithPlaylist = file.withVideoOrPlaylist(playlist) | ||
72 | 73 | ||
73 | await VideoPathManager.Instance.makeAvailableVideoFile(playlist, file, videoPath => { | 74 | await VideoPathManager.Instance.makeAvailableVideoFile(fileWithPlaylist, videoPath => { |
74 | 75 | ||
75 | return VideoPathManager.Instance.makeAvailableResolutionPlaylistFile(playlist, file, async resolutionPlaylistPath => { | 76 | return VideoPathManager.Instance.makeAvailableResolutionPlaylistFile(fileWithPlaylist, async resolutionPlaylistPath => { |
76 | const playlistContent = await readFile(resolutionPlaylistPath) | 77 | const playlistContent = await readFile(resolutionPlaylistPath) |
77 | const ranges = getRangesFromPlaylist(playlistContent.toString()) | 78 | const ranges = getRangesFromPlaylist(playlistContent.toString()) |
78 | 79 | ||
diff --git a/server/lib/job-queue/handlers/move-to-object-storage.ts b/server/lib/job-queue/handlers/move-to-object-storage.ts index 4beca3d75..54a7c566b 100644 --- a/server/lib/job-queue/handlers/move-to-object-storage.ts +++ b/server/lib/job-queue/handlers/move-to-object-storage.ts | |||
@@ -56,16 +56,17 @@ async function moveWebTorrentFiles (video: MVideoWithAllFiles) { | |||
56 | 56 | ||
57 | async function moveHLSFiles (video: MVideoWithAllFiles) { | 57 | async function moveHLSFiles (video: MVideoWithAllFiles) { |
58 | for (const playlist of video.VideoStreamingPlaylists) { | 58 | for (const playlist of video.VideoStreamingPlaylists) { |
59 | const playlistWithVideo = playlist.withVideo(video) | ||
59 | 60 | ||
60 | for (const file of playlist.VideoFiles) { | 61 | for (const file of playlist.VideoFiles) { |
61 | if (file.storage !== VideoStorage.FILE_SYSTEM) continue | 62 | if (file.storage !== VideoStorage.FILE_SYSTEM) continue |
62 | 63 | ||
63 | // Resolution playlist | 64 | // Resolution playlist |
64 | const playlistFilename = getHlsResolutionPlaylistFilename(file.filename) | 65 | const playlistFilename = getHlsResolutionPlaylistFilename(file.filename) |
65 | await storeHLSFile(playlist, video, playlistFilename) | 66 | await storeHLSFile(playlistWithVideo, playlistFilename) |
66 | 67 | ||
67 | // Resolution fragmented file | 68 | // Resolution fragmented file |
68 | const fileUrl = await storeHLSFile(playlist, video, file.filename) | 69 | const fileUrl = await storeHLSFile(playlistWithVideo, file.filename) |
69 | 70 | ||
70 | const oldPath = join(getHLSDirectory(video), file.filename) | 71 | const oldPath = join(getHLSDirectory(video), file.filename) |
71 | 72 | ||
@@ -78,10 +79,12 @@ async function doAfterLastJob (video: MVideoWithAllFiles, isNewVideo: boolean) { | |||
78 | for (const playlist of video.VideoStreamingPlaylists) { | 79 | for (const playlist of video.VideoStreamingPlaylists) { |
79 | if (playlist.storage === VideoStorage.OBJECT_STORAGE) continue | 80 | if (playlist.storage === VideoStorage.OBJECT_STORAGE) continue |
80 | 81 | ||
82 | const playlistWithVideo = playlist.withVideo(video) | ||
83 | |||
81 | // Master playlist | 84 | // Master playlist |
82 | playlist.playlistUrl = await storeHLSFile(playlist, video, playlist.playlistFilename) | 85 | playlist.playlistUrl = await storeHLSFile(playlistWithVideo, playlist.playlistFilename) |
83 | // Sha256 segments file | 86 | // Sha256 segments file |
84 | playlist.segmentsSha256Url = await storeHLSFile(playlist, video, playlist.segmentsSha256Filename) | 87 | playlist.segmentsSha256Url = await storeHLSFile(playlistWithVideo, playlist.segmentsSha256Filename) |
85 | 88 | ||
86 | playlist.storage = VideoStorage.OBJECT_STORAGE | 89 | playlist.storage = VideoStorage.OBJECT_STORAGE |
87 | 90 | ||
diff --git a/server/lib/job-queue/handlers/video-transcoding.ts b/server/lib/job-queue/handlers/video-transcoding.ts index 904ef2e3c..2d0798e12 100644 --- a/server/lib/job-queue/handlers/video-transcoding.ts +++ b/server/lib/job-queue/handlers/video-transcoding.ts | |||
@@ -14,7 +14,7 @@ import { | |||
14 | VideoTranscodingPayload | 14 | VideoTranscodingPayload |
15 | } from '../../../../shared' | 15 | } from '../../../../shared' |
16 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 16 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
17 | import { computeResolutionsToTranscode } from '../../../helpers/ffprobe-utils' | 17 | import { computeLowerResolutionsToTranscode } from '../../../helpers/ffprobe-utils' |
18 | import { logger, loggerTagsFactory } from '../../../helpers/logger' | 18 | import { logger, loggerTagsFactory } from '../../../helpers/logger' |
19 | import { CONFIG } from '../../../initializers/config' | 19 | import { CONFIG } from '../../../initializers/config' |
20 | import { VideoModel } from '../../../models/video/video' | 20 | import { VideoModel } from '../../../models/video/video' |
@@ -81,7 +81,7 @@ async function handleHLSJob (job: Job, payload: HLSTranscodingPayload, video: MV | |||
81 | 81 | ||
82 | const videoOrStreamingPlaylist = videoFileInput.getVideoOrStreamingPlaylist() | 82 | const videoOrStreamingPlaylist = videoFileInput.getVideoOrStreamingPlaylist() |
83 | 83 | ||
84 | await VideoPathManager.Instance.makeAvailableVideoFile(videoOrStreamingPlaylist, videoFileInput, videoInputPath => { | 84 | await VideoPathManager.Instance.makeAvailableVideoFile(videoFileInput.withVideoOrPlaylist(videoOrStreamingPlaylist), videoInputPath => { |
85 | return generateHlsPlaylistResolution({ | 85 | return generateHlsPlaylistResolution({ |
86 | video, | 86 | video, |
87 | videoInputPath, | 87 | videoInputPath, |
@@ -135,7 +135,7 @@ async function handleWebTorrentOptimizeJob (job: Job, payload: OptimizeTranscodi | |||
135 | // --------------------------------------------------------------------------- | 135 | // --------------------------------------------------------------------------- |
136 | 136 | ||
137 | async function onHlsPlaylistGeneration (video: MVideoFullLight, user: MUser, payload: HLSTranscodingPayload) { | 137 | async function onHlsPlaylistGeneration (video: MVideoFullLight, user: MUser, payload: HLSTranscodingPayload) { |
138 | if (payload.isMaxQuality && CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false) { | 138 | if (payload.isMaxQuality && payload.autoDeleteWebTorrentIfNeeded && CONFIG.TRANSCODING.WEBTORRENT.ENABLED === false) { |
139 | // Remove webtorrent files if not enabled | 139 | // Remove webtorrent files if not enabled |
140 | for (const file of video.VideoFiles) { | 140 | for (const file of video.VideoFiles) { |
141 | await video.removeWebTorrentFileAndTorrent(file) | 141 | await video.removeWebTorrentFileAndTorrent(file) |
@@ -232,6 +232,7 @@ async function createHlsJobIfEnabled (user: MUserId, payload: { | |||
232 | isPortraitMode: payload.isPortraitMode, | 232 | isPortraitMode: payload.isPortraitMode, |
233 | copyCodecs: payload.copyCodecs, | 233 | copyCodecs: payload.copyCodecs, |
234 | isMaxQuality: payload.isMaxQuality, | 234 | isMaxQuality: payload.isMaxQuality, |
235 | autoDeleteWebTorrentIfNeeded: true, | ||
235 | isNewVideo: payload.isNewVideo | 236 | isNewVideo: payload.isNewVideo |
236 | } | 237 | } |
237 | 238 | ||
@@ -261,7 +262,7 @@ async function createLowerResolutionsJobs (options: { | |||
261 | const { video, user, videoFileResolution, isPortraitMode, isNewVideo, type } = options | 262 | const { video, user, videoFileResolution, isPortraitMode, isNewVideo, type } = options |
262 | 263 | ||
263 | // Create transcoding jobs if there are enabled resolutions | 264 | // Create transcoding jobs if there are enabled resolutions |
264 | const resolutionsEnabled = computeResolutionsToTranscode(videoFileResolution, 'vod') | 265 | const resolutionsEnabled = computeLowerResolutionsToTranscode(videoFileResolution, 'vod') |
265 | const resolutionCreated: string[] = [] | 266 | const resolutionCreated: string[] = [] |
266 | 267 | ||
267 | for (const resolution of resolutionsEnabled) { | 268 | for (const resolution of resolutionsEnabled) { |
@@ -288,6 +289,7 @@ async function createLowerResolutionsJobs (options: { | |||
288 | isPortraitMode, | 289 | isPortraitMode, |
289 | copyCodecs: false, | 290 | copyCodecs: false, |
290 | isMaxQuality: false, | 291 | isMaxQuality: false, |
292 | autoDeleteWebTorrentIfNeeded: true, | ||
291 | isNewVideo | 293 | isNewVideo |
292 | } | 294 | } |
293 | 295 | ||
diff --git a/server/lib/live/live-manager.ts b/server/lib/live/live-manager.ts index 2562edb75..b3bf5a999 100644 --- a/server/lib/live/live-manager.ts +++ b/server/lib/live/live-manager.ts | |||
@@ -3,7 +3,7 @@ import { readFile } from 'fs-extra' | |||
3 | import { createServer, Server } from 'net' | 3 | import { createServer, Server } from 'net' |
4 | import { createServer as createServerTLS, Server as ServerTLS } from 'tls' | 4 | import { createServer as createServerTLS, Server as ServerTLS } from 'tls' |
5 | import { | 5 | import { |
6 | computeResolutionsToTranscode, | 6 | computeLowerResolutionsToTranscode, |
7 | ffprobePromise, | 7 | ffprobePromise, |
8 | getVideoFileBitrate, | 8 | getVideoFileBitrate, |
9 | getVideoFileFPS, | 9 | getVideoFileFPS, |
@@ -402,7 +402,7 @@ class LiveManager { | |||
402 | 402 | ||
403 | private buildAllResolutionsToTranscode (originResolution: number) { | 403 | private buildAllResolutionsToTranscode (originResolution: number) { |
404 | const resolutionsEnabled = CONFIG.LIVE.TRANSCODING.ENABLED | 404 | const resolutionsEnabled = CONFIG.LIVE.TRANSCODING.ENABLED |
405 | ? computeResolutionsToTranscode(originResolution, 'live') | 405 | ? computeLowerResolutionsToTranscode(originResolution, 'live') |
406 | : [] | 406 | : [] |
407 | 407 | ||
408 | return resolutionsEnabled.concat([ originResolution ]) | 408 | return resolutionsEnabled.concat([ originResolution ]) |
diff --git a/server/lib/object-storage/keys.ts b/server/lib/object-storage/keys.ts index 12acb3aec..4f17073f4 100644 --- a/server/lib/object-storage/keys.ts +++ b/server/lib/object-storage/keys.ts | |||
@@ -1,12 +1,12 @@ | |||
1 | import { join } from 'path' | 1 | import { join } from 'path' |
2 | import { MStreamingPlaylist, MVideoUUID } from '@server/types/models' | 2 | import { MStreamingPlaylistVideo } from '@server/types/models' |
3 | 3 | ||
4 | function generateHLSObjectStorageKey (playlist: MStreamingPlaylist, video: MVideoUUID, filename: string) { | 4 | function generateHLSObjectStorageKey (playlist: MStreamingPlaylistVideo, filename: string) { |
5 | return join(generateHLSObjectBaseStorageKey(playlist, video), filename) | 5 | return join(generateHLSObjectBaseStorageKey(playlist), filename) |
6 | } | 6 | } |
7 | 7 | ||
8 | function generateHLSObjectBaseStorageKey (playlist: MStreamingPlaylist, video: MVideoUUID) { | 8 | function generateHLSObjectBaseStorageKey (playlist: MStreamingPlaylistVideo) { |
9 | return join(playlist.getStringType(), video.uuid) | 9 | return join(playlist.getStringType(), playlist.Video.uuid) |
10 | } | 10 | } |
11 | 11 | ||
12 | function generateWebTorrentObjectStorageKey (filename: string) { | 12 | function generateWebTorrentObjectStorageKey (filename: string) { |
diff --git a/server/lib/object-storage/videos.ts b/server/lib/object-storage/videos.ts index 15b8f58d5..8988f3e2a 100644 --- a/server/lib/object-storage/videos.ts +++ b/server/lib/object-storage/videos.ts | |||
@@ -1,17 +1,17 @@ | |||
1 | import { join } from 'path' | 1 | import { join } from 'path' |
2 | import { logger } from '@server/helpers/logger' | 2 | import { logger } from '@server/helpers/logger' |
3 | import { CONFIG } from '@server/initializers/config' | 3 | import { CONFIG } from '@server/initializers/config' |
4 | import { MStreamingPlaylist, MVideoFile, MVideoUUID } from '@server/types/models' | 4 | import { MStreamingPlaylistVideo, MVideoFile } from '@server/types/models' |
5 | import { getHLSDirectory } from '../paths' | 5 | import { getHLSDirectory } from '../paths' |
6 | import { generateHLSObjectBaseStorageKey, generateHLSObjectStorageKey, generateWebTorrentObjectStorageKey } from './keys' | 6 | import { generateHLSObjectBaseStorageKey, generateHLSObjectStorageKey, generateWebTorrentObjectStorageKey } from './keys' |
7 | import { lTags, makeAvailable, removeObject, removePrefix, storeObject } from './shared' | 7 | import { lTags, makeAvailable, removeObject, removePrefix, storeObject } from './shared' |
8 | 8 | ||
9 | function storeHLSFile (playlist: MStreamingPlaylist, video: MVideoUUID, filename: string) { | 9 | function storeHLSFile (playlist: MStreamingPlaylistVideo, filename: string) { |
10 | const baseHlsDirectory = getHLSDirectory(video) | 10 | const baseHlsDirectory = getHLSDirectory(playlist.Video) |
11 | 11 | ||
12 | return storeObject({ | 12 | return storeObject({ |
13 | inputPath: join(baseHlsDirectory, filename), | 13 | inputPath: join(baseHlsDirectory, filename), |
14 | objectStorageKey: generateHLSObjectStorageKey(playlist, video, filename), | 14 | objectStorageKey: generateHLSObjectStorageKey(playlist, filename), |
15 | bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS | 15 | bucketInfo: CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS |
16 | }) | 16 | }) |
17 | } | 17 | } |
@@ -24,16 +24,16 @@ function storeWebTorrentFile (filename: string) { | |||
24 | }) | 24 | }) |
25 | } | 25 | } |
26 | 26 | ||
27 | function removeHLSObjectStorage (playlist: MStreamingPlaylist, video: MVideoUUID) { | 27 | function removeHLSObjectStorage (playlist: MStreamingPlaylistVideo) { |
28 | return removePrefix(generateHLSObjectBaseStorageKey(playlist, video), CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS) | 28 | return removePrefix(generateHLSObjectBaseStorageKey(playlist), CONFIG.OBJECT_STORAGE.STREAMING_PLAYLISTS) |
29 | } | 29 | } |
30 | 30 | ||
31 | function removeWebTorrentObjectStorage (videoFile: MVideoFile) { | 31 | function removeWebTorrentObjectStorage (videoFile: MVideoFile) { |
32 | return removeObject(generateWebTorrentObjectStorageKey(videoFile.filename), CONFIG.OBJECT_STORAGE.VIDEOS) | 32 | return removeObject(generateWebTorrentObjectStorageKey(videoFile.filename), CONFIG.OBJECT_STORAGE.VIDEOS) |
33 | } | 33 | } |
34 | 34 | ||
35 | async function makeHLSFileAvailable (playlist: MStreamingPlaylist, video: MVideoUUID, filename: string, destination: string) { | 35 | async function makeHLSFileAvailable (playlist: MStreamingPlaylistVideo, filename: string, destination: string) { |
36 | const key = generateHLSObjectStorageKey(playlist, video, filename) | 36 | const key = generateHLSObjectStorageKey(playlist, filename) |
37 | 37 | ||
38 | logger.info('Fetching HLS file %s from object storage to %s.', key, destination, lTags()) | 38 | logger.info('Fetching HLS file %s from object storage to %s.', key, destination, lTags()) |
39 | 39 | ||
diff --git a/server/lib/thumbnail.ts b/server/lib/thumbnail.ts index d2384f53c..36270e5c1 100644 --- a/server/lib/thumbnail.ts +++ b/server/lib/thumbnail.ts | |||
@@ -115,7 +115,7 @@ function generateVideoMiniature (options: { | |||
115 | }) { | 115 | }) { |
116 | const { video, videoFile, type } = options | 116 | const { video, videoFile, type } = options |
117 | 117 | ||
118 | return VideoPathManager.Instance.makeAvailableVideoFile(video, videoFile, input => { | 118 | return VideoPathManager.Instance.makeAvailableVideoFile(videoFile.withVideoOrPlaylist(video), input => { |
119 | const { filename, basePath, height, width, existingThumbnail, outputPath } = buildMetadataFromVideo(video, type) | 119 | const { filename, basePath, height, width, existingThumbnail, outputPath } = buildMetadataFromVideo(video, type) |
120 | 120 | ||
121 | const thumbnailCreator = videoFile.isAudio() | 121 | const thumbnailCreator = videoFile.isAudio() |
diff --git a/server/lib/transcoding/video-transcoding.ts b/server/lib/transcoding/video-transcoding.ts index 250a678eb..d0db05216 100644 --- a/server/lib/transcoding/video-transcoding.ts +++ b/server/lib/transcoding/video-transcoding.ts | |||
@@ -35,7 +35,7 @@ function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile: MVid | |||
35 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR | 35 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR |
36 | const newExtname = '.mp4' | 36 | const newExtname = '.mp4' |
37 | 37 | ||
38 | return VideoPathManager.Instance.makeAvailableVideoFile(video, inputVideoFile, async videoInputPath => { | 38 | return VideoPathManager.Instance.makeAvailableVideoFile(inputVideoFile.withVideoOrPlaylist(video), async videoInputPath => { |
39 | const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) | 39 | const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) |
40 | 40 | ||
41 | const transcodeType: TranscodeOptionsType = await canDoQuickTranscode(videoInputPath) | 41 | const transcodeType: TranscodeOptionsType = await canDoQuickTranscode(videoInputPath) |
@@ -81,7 +81,7 @@ function transcodeNewWebTorrentResolution (video: MVideoFullLight, resolution: V | |||
81 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR | 81 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR |
82 | const extname = '.mp4' | 82 | const extname = '.mp4' |
83 | 83 | ||
84 | return VideoPathManager.Instance.makeAvailableVideoFile(video, video.getMaxQualityFile(), async videoInputPath => { | 84 | return VideoPathManager.Instance.makeAvailableVideoFile(video.getMaxQualityFile().withVideoOrPlaylist(video), async videoInputPath => { |
85 | const newVideoFile = new VideoFileModel({ | 85 | const newVideoFile = new VideoFileModel({ |
86 | resolution, | 86 | resolution, |
87 | extname, | 87 | extname, |
@@ -134,7 +134,7 @@ function mergeAudioVideofile (video: MVideoFullLight, resolution: VideoResolutio | |||
134 | 134 | ||
135 | const inputVideoFile = video.getMinQualityFile() | 135 | const inputVideoFile = video.getMinQualityFile() |
136 | 136 | ||
137 | return VideoPathManager.Instance.makeAvailableVideoFile(video, inputVideoFile, async audioInputPath => { | 137 | return VideoPathManager.Instance.makeAvailableVideoFile(inputVideoFile.withVideoOrPlaylist(video), async audioInputPath => { |
138 | const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) | 138 | const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) |
139 | 139 | ||
140 | // If the user updates the video preview during transcoding | 140 | // If the user updates the video preview during transcoding |
diff --git a/server/lib/video-path-manager.ts b/server/lib/video-path-manager.ts index 4c5d0c89d..27058005c 100644 --- a/server/lib/video-path-manager.ts +++ b/server/lib/video-path-manager.ts | |||
@@ -3,7 +3,14 @@ import { extname, join } from 'path' | |||
3 | import { buildUUID } from '@server/helpers/uuid' | 3 | import { buildUUID } from '@server/helpers/uuid' |
4 | import { extractVideo } from '@server/helpers/video' | 4 | import { extractVideo } from '@server/helpers/video' |
5 | import { CONFIG } from '@server/initializers/config' | 5 | import { CONFIG } from '@server/initializers/config' |
6 | import { MStreamingPlaylistVideo, MVideo, MVideoFile, MVideoUUID } from '@server/types/models' | 6 | import { |
7 | MStreamingPlaylistVideo, | ||
8 | MVideo, | ||
9 | MVideoFile, | ||
10 | MVideoFileStreamingPlaylistVideo, | ||
11 | MVideoFileVideo, | ||
12 | MVideoUUID | ||
13 | } from '@server/types/models' | ||
7 | import { VideoStorage } from '@shared/models' | 14 | import { VideoStorage } from '@shared/models' |
8 | import { makeHLSFileAvailable, makeWebTorrentFileAvailable } from './object-storage' | 15 | import { makeHLSFileAvailable, makeWebTorrentFileAvailable } from './object-storage' |
9 | import { getHLSDirectory, getHLSRedundancyDirectory, getHlsResolutionPlaylistFilename } from './paths' | 16 | import { getHLSDirectory, getHLSRedundancyDirectory, getHlsResolutionPlaylistFilename } from './paths' |
@@ -43,10 +50,10 @@ class VideoPathManager { | |||
43 | return join(CONFIG.STORAGE.VIDEOS_DIR, videoFile.filename) | 50 | return join(CONFIG.STORAGE.VIDEOS_DIR, videoFile.filename) |
44 | } | 51 | } |
45 | 52 | ||
46 | async makeAvailableVideoFile <T> (videoOrPlaylist: MVideo | MStreamingPlaylistVideo, videoFile: MVideoFile, cb: MakeAvailableCB<T>) { | 53 | async makeAvailableVideoFile <T> (videoFile: MVideoFileVideo | MVideoFileStreamingPlaylistVideo, cb: MakeAvailableCB<T>) { |
47 | if (videoFile.storage === VideoStorage.FILE_SYSTEM) { | 54 | if (videoFile.storage === VideoStorage.FILE_SYSTEM) { |
48 | return this.makeAvailableFactory( | 55 | return this.makeAvailableFactory( |
49 | () => this.getFSVideoFileOutputPath(videoOrPlaylist, videoFile), | 56 | () => this.getFSVideoFileOutputPath(videoFile.getVideoOrStreamingPlaylist(), videoFile), |
50 | false, | 57 | false, |
51 | cb | 58 | cb |
52 | ) | 59 | ) |
@@ -55,10 +62,10 @@ class VideoPathManager { | |||
55 | const destination = this.buildTMPDestination(videoFile.filename) | 62 | const destination = this.buildTMPDestination(videoFile.filename) |
56 | 63 | ||
57 | if (videoFile.isHLS()) { | 64 | if (videoFile.isHLS()) { |
58 | const video = extractVideo(videoOrPlaylist) | 65 | const playlist = (videoFile as MVideoFileStreamingPlaylistVideo).VideoStreamingPlaylist |
59 | 66 | ||
60 | return this.makeAvailableFactory( | 67 | return this.makeAvailableFactory( |
61 | () => makeHLSFileAvailable(videoOrPlaylist as MStreamingPlaylistVideo, video, videoFile.filename, destination), | 68 | () => makeHLSFileAvailable(playlist, videoFile.filename, destination), |
62 | true, | 69 | true, |
63 | cb | 70 | cb |
64 | ) | 71 | ) |
@@ -71,19 +78,20 @@ class VideoPathManager { | |||
71 | ) | 78 | ) |
72 | } | 79 | } |
73 | 80 | ||
74 | async makeAvailableResolutionPlaylistFile <T> (playlist: MStreamingPlaylistVideo, videoFile: MVideoFile, cb: MakeAvailableCB<T>) { | 81 | async makeAvailableResolutionPlaylistFile <T> (videoFile: MVideoFileStreamingPlaylistVideo, cb: MakeAvailableCB<T>) { |
75 | const filename = getHlsResolutionPlaylistFilename(videoFile.filename) | 82 | const filename = getHlsResolutionPlaylistFilename(videoFile.filename) |
76 | 83 | ||
77 | if (videoFile.storage === VideoStorage.FILE_SYSTEM) { | 84 | if (videoFile.storage === VideoStorage.FILE_SYSTEM) { |
78 | return this.makeAvailableFactory( | 85 | return this.makeAvailableFactory( |
79 | () => join(getHLSDirectory(playlist.Video), filename), | 86 | () => join(getHLSDirectory(videoFile.getVideo()), filename), |
80 | false, | 87 | false, |
81 | cb | 88 | cb |
82 | ) | 89 | ) |
83 | } | 90 | } |
84 | 91 | ||
92 | const playlist = videoFile.VideoStreamingPlaylist | ||
85 | return this.makeAvailableFactory( | 93 | return this.makeAvailableFactory( |
86 | () => makeHLSFileAvailable(playlist, playlist.Video, filename, this.buildTMPDestination(filename)), | 94 | () => makeHLSFileAvailable(playlist, filename, this.buildTMPDestination(filename)), |
87 | true, | 95 | true, |
88 | cb | 96 | cb |
89 | ) | 97 | ) |
@@ -99,7 +107,7 @@ class VideoPathManager { | |||
99 | } | 107 | } |
100 | 108 | ||
101 | return this.makeAvailableFactory( | 109 | return this.makeAvailableFactory( |
102 | () => makeHLSFileAvailable(playlist, playlist.Video, filename, this.buildTMPDestination(filename)), | 110 | () => makeHLSFileAvailable(playlist, filename, this.buildTMPDestination(filename)), |
103 | true, | 111 | true, |
104 | cb | 112 | cb |
105 | ) | 113 | ) |
diff --git a/server/lib/video-state.ts b/server/lib/video-state.ts index 0b51f5c6b..bf6dd4bc8 100644 --- a/server/lib/video-state.ts +++ b/server/lib/video-state.ts | |||
@@ -80,6 +80,8 @@ async function moveToExternalStorageState (video: MVideoFullLight, isNewVideo: b | |||
80 | } | 80 | } |
81 | 81 | ||
82 | function moveToFailedTranscodingState (video: MVideoFullLight) { | 82 | function moveToFailedTranscodingState (video: MVideoFullLight) { |
83 | if (video.state === VideoState.TRANSCODING_FAILED) return | ||
84 | |||
83 | return video.setNewState(VideoState.TRANSCODING_FAILED, false, undefined) | 85 | return video.setNewState(VideoState.TRANSCODING_FAILED, false, undefined) |
84 | } | 86 | } |
85 | 87 | ||
diff --git a/server/lib/video.ts b/server/lib/video.ts index 0a2b93cc0..1cfe4f27c 100644 --- a/server/lib/video.ts +++ b/server/lib/video.ts | |||
@@ -105,7 +105,7 @@ async function addOptimizeOrMergeAudioJob (video: MVideoUUID, videoFile: MVideoF | |||
105 | return addTranscodingJob(dataInput, jobOptions) | 105 | return addTranscodingJob(dataInput, jobOptions) |
106 | } | 106 | } |
107 | 107 | ||
108 | async function addTranscodingJob (payload: VideoTranscodingPayload, options: CreateJobOptions) { | 108 | async function addTranscodingJob (payload: VideoTranscodingPayload, options: CreateJobOptions = {}) { |
109 | await VideoJobInfoModel.increaseOrCreate(payload.videoUUID, 'pendingTranscode') | 109 | await VideoJobInfoModel.increaseOrCreate(payload.videoUUID, 'pendingTranscode') |
110 | 110 | ||
111 | return JobQueue.Instance.createJobWithPromise({ type: 'video-transcoding', payload: payload }, options) | 111 | return JobQueue.Instance.createJobWithPromise({ type: 'video-transcoding', payload: payload }, options) |