aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/job-queue/handlers/video-live-ending.ts
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-11-30 15:59:22 +0100
committerChocobozzz <me@florianbigard.com>2020-11-30 15:59:22 +0100
commit937581b8f61fe82fdac044e11740b9a4cb6d96b0 (patch)
tree9b9274e2e4696cf167a86691dfc35c024cd254ba /server/lib/job-queue/handlers/video-live-ending.ts
parentd605328a300dca095fa93d7f03fa104573e5a3fa (diff)
downloadPeerTube-937581b8f61fe82fdac044e11740b9a4cb6d96b0.tar.gz
PeerTube-937581b8f61fe82fdac044e11740b9a4cb6d96b0.tar.zst
PeerTube-937581b8f61fe82fdac044e11740b9a4cb6d96b0.zip
Fix high CPU with long live when save replay is true
Diffstat (limited to 'server/lib/job-queue/handlers/video-live-ending.ts')
-rw-r--r--server/lib/job-queue/handlers/video-live-ending.ts32
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 @@
1import * as Bull from 'bull' 1import * as Bull from 'bull'
2import { readdir, remove } from 'fs-extra' 2import { move, readdir, remove } from 'fs-extra'
3import { join } from 'path' 3import { join } from 'path'
4import { hlsPlaylistToFragmentedMP4 } from '@server/helpers/ffmpeg-utils' 4import { hlsPlaylistToFragmentedMP4 } from '@server/helpers/ffmpeg-utils'
5import { getDurationFromVideoFile, getVideoFileResolution } from '@server/helpers/ffprobe-utils' 5import { getDurationFromVideoFile, getVideoFileResolution } from '@server/helpers/ffprobe-utils'
@@ -14,6 +14,7 @@ import { VideoStreamingPlaylistModel } from '@server/models/video/video-streamin
14import { MStreamingPlaylist, MVideo, MVideoLive } from '@server/types/models' 14import { MStreamingPlaylist, MVideo, MVideoLive } from '@server/types/models'
15import { ThumbnailType, VideoLiveEndingPayload, VideoState } from '@shared/models' 15import { ThumbnailType, VideoLiveEndingPayload, VideoState } from '@shared/models'
16import { logger } from '../../../helpers/logger' 16import { logger } from '../../../helpers/logger'
17import { VIDEO_LIVE } from '@server/initializers/constants'
17 18
18async function processVideoLiveEnding (job: Bull.Job) { 19async 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
54async function saveLive (video: MVideo, live: MVideoLive) { 55async 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