diff options
Diffstat (limited to 'server/lib/job-queue')
-rw-r--r-- | server/lib/job-queue/handlers/video-live-ending.ts | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/server/lib/job-queue/handlers/video-live-ending.ts b/server/lib/job-queue/handlers/video-live-ending.ts index 447744224..0d2bcaa28 100644 --- a/server/lib/job-queue/handlers/video-live-ending.ts +++ b/server/lib/job-queue/handlers/video-live-ending.ts | |||
@@ -1,5 +1,5 @@ | |||
1 | import * as Bull from 'bull' | 1 | import * as Bull from 'bull' |
2 | import { readdir, remove } from 'fs-extra' | 2 | import { move, readdir, remove } from 'fs-extra' |
3 | import { join } from 'path' | 3 | import { join } from 'path' |
4 | import { hlsPlaylistToFragmentedMP4 } from '@server/helpers/ffmpeg-utils' | 4 | import { hlsPlaylistToFragmentedMP4 } from '@server/helpers/ffmpeg-utils' |
5 | import { getDurationFromVideoFile, getVideoFileResolution } from '@server/helpers/ffprobe-utils' | 5 | import { getDurationFromVideoFile, getVideoFileResolution } from '@server/helpers/ffprobe-utils' |
@@ -14,6 +14,7 @@ import { VideoStreamingPlaylistModel } from '@server/models/video/video-streamin | |||
14 | import { MStreamingPlaylist, MVideo, MVideoLive } from '@server/types/models' | 14 | import { MStreamingPlaylist, MVideo, MVideoLive } from '@server/types/models' |
15 | import { ThumbnailType, VideoLiveEndingPayload, VideoState } from '@shared/models' | 15 | import { ThumbnailType, VideoLiveEndingPayload, VideoState } from '@shared/models' |
16 | import { logger } from '../../../helpers/logger' | 16 | import { logger } from '../../../helpers/logger' |
17 | import { VIDEO_LIVE } from '@server/initializers/constants' | ||
17 | 18 | ||
18 | async function processVideoLiveEnding (job: Bull.Job) { | 19 | async function processVideoLiveEnding (job: Bull.Job) { |
19 | const payload = job.data as VideoLiveEndingPayload | 20 | const payload = job.data as VideoLiveEndingPayload |
@@ -53,24 +54,40 @@ export { | |||
53 | 54 | ||
54 | async function saveLive (video: MVideo, live: MVideoLive) { | 55 | async function saveLive (video: MVideo, live: MVideoLive) { |
55 | const hlsDirectory = getHLSDirectory(video, false) | 56 | const hlsDirectory = getHLSDirectory(video, false) |
56 | const files = await readdir(hlsDirectory) | 57 | const replayDirectory = join(hlsDirectory, VIDEO_LIVE.REPLAY_DIRECTORY) |
58 | |||
59 | const rootFiles = await readdir(hlsDirectory) | ||
60 | |||
61 | const playlistFiles: string[] = [] | ||
62 | |||
63 | for (const file of rootFiles) { | ||
64 | if (file.endsWith('.m3u8') !== true) continue | ||
65 | |||
66 | await move(join(hlsDirectory, file), join(replayDirectory, file)) | ||
67 | |||
68 | if (file !== 'master.m3u8') { | ||
69 | playlistFiles.push(file) | ||
70 | } | ||
71 | } | ||
72 | |||
73 | const replayFiles = await readdir(replayDirectory) | ||
57 | 74 | ||
58 | const playlistFiles = files.filter(f => f.endsWith('.m3u8') && f !== 'master.m3u8') | ||
59 | const resolutions: number[] = [] | 75 | const resolutions: number[] = [] |
60 | let duration: number | 76 | let duration: number |
61 | 77 | ||
62 | for (const playlistFile of playlistFiles) { | 78 | for (const playlistFile of playlistFiles) { |
63 | const playlistPath = join(hlsDirectory, playlistFile) | 79 | const playlistPath = join(replayDirectory, playlistFile) |
64 | const { videoFileResolution } = await getVideoFileResolution(playlistPath) | 80 | const { videoFileResolution } = await getVideoFileResolution(playlistPath) |
65 | 81 | ||
82 | // Put the final mp4 in the hls directory, and not in the replay directory | ||
66 | const mp4TmpPath = buildMP4TmpPath(hlsDirectory, videoFileResolution) | 83 | const mp4TmpPath = buildMP4TmpPath(hlsDirectory, videoFileResolution) |
67 | 84 | ||
68 | // Playlist name is for example 3.m3u8 | 85 | // Playlist name is for example 3.m3u8 |
69 | // Segments names are 3-0.ts 3-1.ts etc | 86 | // Segments names are 3-0.ts 3-1.ts etc |
70 | const shouldStartWith = playlistFile.replace(/\.m3u8$/, '') + '-' | 87 | const shouldStartWith = playlistFile.replace(/\.m3u8$/, '') + '-' |
71 | 88 | ||
72 | const segmentFiles = files.filter(f => f.startsWith(shouldStartWith) && f.endsWith('.ts')) | 89 | const segmentFiles = replayFiles.filter(f => f.startsWith(shouldStartWith) && f.endsWith('.ts')) |
73 | await hlsPlaylistToFragmentedMP4(hlsDirectory, segmentFiles, mp4TmpPath) | 90 | await hlsPlaylistToFragmentedMP4(replayDirectory, segmentFiles, mp4TmpPath) |
74 | 91 | ||
75 | if (!duration) { | 92 | if (!duration) { |
76 | duration = await getDurationFromVideoFile(mp4TmpPath) | 93 | duration = await getDurationFromVideoFile(mp4TmpPath) |
@@ -143,7 +160,8 @@ async function cleanupLiveFiles (hlsDirectory: string) { | |||
143 | filename.endsWith('.m3u8') || | 160 | filename.endsWith('.m3u8') || |
144 | filename.endsWith('.mpd') || | 161 | filename.endsWith('.mpd') || |
145 | filename.endsWith('.m4s') || | 162 | filename.endsWith('.m4s') || |
146 | filename.endsWith('.tmp') | 163 | filename.endsWith('.tmp') || |
164 | filename === VIDEO_LIVE.REPLAY_DIRECTORY | ||
147 | ) { | 165 | ) { |
148 | const p = join(hlsDirectory, filename) | 166 | const p = join(hlsDirectory, filename) |
149 | 167 | ||