diff options
Diffstat (limited to 'server/lib/job-queue')
-rw-r--r-- | server/lib/job-queue/handlers/video-live-ending.ts | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/server/lib/job-queue/handlers/video-live-ending.ts b/server/lib/job-queue/handlers/video-live-ending.ts index 1a9a36129..cd5bb1d1c 100644 --- a/server/lib/job-queue/handlers/video-live-ending.ts +++ b/server/lib/job-queue/handlers/video-live-ending.ts | |||
@@ -7,7 +7,7 @@ import { generateHlsPlaylist } from '@server/lib/video-transcoding' | |||
7 | import { VideoModel } from '@server/models/video/video' | 7 | import { VideoModel } from '@server/models/video/video' |
8 | import { VideoLiveModel } from '@server/models/video/video-live' | 8 | import { VideoLiveModel } from '@server/models/video/video-live' |
9 | import { VideoStreamingPlaylistModel } from '@server/models/video/video-streaming-playlist' | 9 | import { VideoStreamingPlaylistModel } from '@server/models/video/video-streaming-playlist' |
10 | import { MStreamingPlaylist, MVideo } from '@server/types/models' | 10 | import { MStreamingPlaylist, MVideo, MVideoLive } from '@server/types/models' |
11 | import { VideoLiveEndingPayload, VideoState } from '@shared/models' | 11 | import { VideoLiveEndingPayload, VideoState } from '@shared/models' |
12 | import { logger } from '../../../helpers/logger' | 12 | import { logger } from '../../../helpers/logger' |
13 | 13 | ||
@@ -27,7 +27,7 @@ async function processVideoLiveEnding (job: Bull.Job) { | |||
27 | return cleanupLive(video, streamingPlaylist) | 27 | return cleanupLive(video, streamingPlaylist) |
28 | } | 28 | } |
29 | 29 | ||
30 | return saveLive(video, streamingPlaylist) | 30 | return saveLive(video, live) |
31 | } | 31 | } |
32 | 32 | ||
33 | // --------------------------------------------------------------------------- | 33 | // --------------------------------------------------------------------------- |
@@ -38,33 +38,47 @@ export { | |||
38 | 38 | ||
39 | // --------------------------------------------------------------------------- | 39 | // --------------------------------------------------------------------------- |
40 | 40 | ||
41 | async function saveLive (video: MVideo, streamingPlaylist: MStreamingPlaylist) { | 41 | async function saveLive (video: MVideo, live: MVideoLive) { |
42 | const videoFiles = await streamingPlaylist.get('VideoFiles') | ||
43 | const hlsDirectory = getHLSDirectory(video, false) | 42 | const hlsDirectory = getHLSDirectory(video, false) |
43 | const files = await readdir(hlsDirectory) | ||
44 | |||
45 | const playlistFiles = files.filter(f => f.endsWith('.m3u8') && f !== 'master.m3u8') | ||
46 | const resolutions: number[] = [] | ||
47 | |||
48 | for (const playlistFile of playlistFiles) { | ||
49 | const playlistPath = join(hlsDirectory, playlistFile) | ||
50 | const { videoFileResolution } = await getVideoFileResolution(playlistPath) | ||
44 | 51 | ||
45 | for (const videoFile of videoFiles) { | 52 | const mp4TmpName = buildMP4TmpName(videoFileResolution) |
46 | const playlistPath = join(hlsDirectory, VideoStreamingPlaylistModel.getHlsPlaylistFilename(videoFile.resolution)) | ||
47 | 53 | ||
48 | const mp4TmpName = buildMP4TmpName(videoFile.resolution) | 54 | // Playlist name is for example 3.m3u8 |
49 | await hlsPlaylistToFragmentedMP4(playlistPath, mp4TmpName) | 55 | // Segments names are 3-0.ts 3-1.ts etc |
56 | const shouldStartWith = playlistFile.replace(/\.m3u8$/, '') + '-' | ||
57 | |||
58 | const segmentFiles = files.filter(f => f.startsWith(shouldStartWith) && f.endsWith('.ts')) | ||
59 | await hlsPlaylistToFragmentedMP4(hlsDirectory, segmentFiles, mp4TmpName) | ||
60 | |||
61 | resolutions.push(videoFileResolution) | ||
50 | } | 62 | } |
51 | 63 | ||
52 | await cleanupLiveFiles(hlsDirectory) | 64 | await cleanupLiveFiles(hlsDirectory) |
53 | 65 | ||
66 | await live.destroy() | ||
67 | |||
54 | video.isLive = false | 68 | video.isLive = false |
55 | video.state = VideoState.TO_TRANSCODE | 69 | video.state = VideoState.TO_TRANSCODE |
56 | await video.save() | 70 | await video.save() |
57 | 71 | ||
58 | const videoWithFiles = await VideoModel.loadWithFiles(video.id) | 72 | const videoWithFiles = await VideoModel.loadWithFiles(video.id) |
59 | 73 | ||
60 | for (const videoFile of videoFiles) { | 74 | for (const resolution of resolutions) { |
61 | const videoInputPath = buildMP4TmpName(videoFile.resolution) | 75 | const videoInputPath = buildMP4TmpName(resolution) |
62 | const { isPortraitMode } = await getVideoFileResolution(videoInputPath) | 76 | const { isPortraitMode } = await getVideoFileResolution(videoInputPath) |
63 | 77 | ||
64 | await generateHlsPlaylist({ | 78 | await generateHlsPlaylist({ |
65 | video: videoWithFiles, | 79 | video: videoWithFiles, |
66 | videoInputPath, | 80 | videoInputPath, |
67 | resolution: videoFile.resolution, | 81 | resolution: resolution, |
68 | copyCodecs: true, | 82 | copyCodecs: true, |
69 | isPortraitMode | 83 | isPortraitMode |
70 | }) | 84 | }) |
@@ -103,5 +117,5 @@ async function cleanupLiveFiles (hlsDirectory: string) { | |||
103 | } | 117 | } |
104 | 118 | ||
105 | function buildMP4TmpName (resolution: number) { | 119 | function buildMP4TmpName (resolution: number) { |
106 | return resolution + 'tmp.mp4' | 120 | return resolution + '-tmp.mp4' |
107 | } | 121 | } |