diff options
author | Chocobozzz <me@florianbigard.com> | 2020-11-30 15:59:22 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2020-11-30 15:59:22 +0100 |
commit | 937581b8f61fe82fdac044e11740b9a4cb6d96b0 (patch) | |
tree | 9b9274e2e4696cf167a86691dfc35c024cd254ba /server/lib/live-manager.ts | |
parent | d605328a300dca095fa93d7f03fa104573e5a3fa (diff) | |
download | PeerTube-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/live-manager.ts')
-rw-r--r-- | server/lib/live-manager.ts | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/server/lib/live-manager.ts b/server/lib/live-manager.ts index d63e79dfc..d201465fa 100644 --- a/server/lib/live-manager.ts +++ b/server/lib/live-manager.ts | |||
@@ -1,8 +1,8 @@ | |||
1 | 1 | ||
2 | import * as chokidar from 'chokidar' | 2 | import * as chokidar from 'chokidar' |
3 | import { FfmpegCommand } from 'fluent-ffmpeg' | 3 | import { FfmpegCommand } from 'fluent-ffmpeg' |
4 | import { ensureDir, stat } from 'fs-extra' | 4 | import { copy, ensureDir, stat } from 'fs-extra' |
5 | import { basename } from 'path' | 5 | import { basename, join } from 'path' |
6 | import { isTestInstance } from '@server/helpers/core-utils' | 6 | import { isTestInstance } from '@server/helpers/core-utils' |
7 | import { getLiveMuxingCommand, getLiveTranscodingCommand } from '@server/helpers/ffmpeg-utils' | 7 | import { getLiveMuxingCommand, getLiveTranscodingCommand } from '@server/helpers/ffmpeg-utils' |
8 | import { computeResolutionsToTranscode, getVideoFileFPS, getVideoFileResolution } from '@server/helpers/ffprobe-utils' | 8 | import { computeResolutionsToTranscode, getVideoFileFPS, getVideoFileResolution } from '@server/helpers/ffprobe-utils' |
@@ -25,6 +25,7 @@ import { getHLSDirectory } from './video-paths' | |||
25 | import { availableEncoders } from './video-transcoding-profiles' | 25 | import { availableEncoders } from './video-transcoding-profiles' |
26 | 26 | ||
27 | import memoizee = require('memoizee') | 27 | import memoizee = require('memoizee') |
28 | import { mkdir } from 'fs' | ||
28 | const NodeRtmpServer = require('node-media-server/node_rtmp_server') | 29 | const NodeRtmpServer = require('node-media-server/node_rtmp_server') |
29 | const context = require('node-media-server/node_core_ctx') | 30 | const context = require('node-media-server/node_core_ctx') |
30 | const nodeMediaServerLogger = require('node-media-server/node_core_logger') | 31 | const nodeMediaServerLogger = require('node-media-server/node_core_logger') |
@@ -261,8 +262,13 @@ class LiveManager { | |||
261 | const outPath = getHLSDirectory(videoLive.Video) | 262 | const outPath = getHLSDirectory(videoLive.Video) |
262 | await ensureDir(outPath) | 263 | await ensureDir(outPath) |
263 | 264 | ||
265 | const replayDirectory = join(outPath, VIDEO_LIVE.REPLAY_DIRECTORY) | ||
266 | |||
267 | if (videoLive.saveReplay === true) { | ||
268 | await ensureDir(replayDirectory) | ||
269 | } | ||
270 | |||
264 | const videoUUID = videoLive.Video.uuid | 271 | const videoUUID = videoLive.Video.uuid |
265 | const deleteSegments = videoLive.saveReplay === false | ||
266 | 272 | ||
267 | const ffmpegExec = CONFIG.LIVE.TRANSCODING.ENABLED | 273 | const ffmpegExec = CONFIG.LIVE.TRANSCODING.ENABLED |
268 | ? await getLiveTranscodingCommand({ | 274 | ? await getLiveTranscodingCommand({ |
@@ -270,11 +276,10 @@ class LiveManager { | |||
270 | outPath, | 276 | outPath, |
271 | resolutions: allResolutions, | 277 | resolutions: allResolutions, |
272 | fps, | 278 | fps, |
273 | deleteSegments, | ||
274 | availableEncoders, | 279 | availableEncoders, |
275 | profile: 'default' | 280 | profile: 'default' |
276 | }) | 281 | }) |
277 | : getLiveMuxingCommand(rtmpUrl, outPath, deleteSegments) | 282 | : getLiveMuxingCommand(rtmpUrl, outPath) |
278 | 283 | ||
279 | logger.info('Running live muxing/transcoding for %s.', videoUUID) | 284 | logger.info('Running live muxing/transcoding for %s.', videoUUID) |
280 | this.transSessions.set(sessionId, ffmpegExec) | 285 | this.transSessions.set(sessionId, ffmpegExec) |
@@ -284,11 +289,18 @@ class LiveManager { | |||
284 | const segmentsToProcessPerPlaylist: { [playlistId: string]: string[] } = {} | 289 | const segmentsToProcessPerPlaylist: { [playlistId: string]: string[] } = {} |
285 | const playlistIdMatcher = /^([\d+])-/ | 290 | const playlistIdMatcher = /^([\d+])-/ |
286 | 291 | ||
287 | const processHashSegments = (segmentsToProcess: string[]) => { | 292 | const processSegments = (segmentsToProcess: string[]) => { |
288 | // Add sha hash of previous segments, because ffmpeg should have finished generating them | 293 | // Add sha hash of previous segments, because ffmpeg should have finished generating them |
289 | for (const previousSegment of segmentsToProcess) { | 294 | for (const previousSegment of segmentsToProcess) { |
290 | this.addSegmentSha(videoUUID, previousSegment) | 295 | this.addSegmentSha(videoUUID, previousSegment) |
291 | .catch(err => logger.error('Cannot add sha segment of video %s -> %s.', videoUUID, previousSegment, { err })) | 296 | .catch(err => logger.error('Cannot add sha segment of video %s -> %s.', videoUUID, previousSegment, { err })) |
297 | |||
298 | if (videoLive.saveReplay) { | ||
299 | const segmentName = basename(previousSegment) | ||
300 | |||
301 | copy(previousSegment, join(outPath, VIDEO_LIVE.REPLAY_DIRECTORY, segmentName)) | ||
302 | .catch(err => logger.error('Cannot copy segment %s to repay directory.', previousSegment, { err })) | ||
303 | } | ||
292 | } | 304 | } |
293 | } | 305 | } |
294 | 306 | ||
@@ -298,7 +310,7 @@ class LiveManager { | |||
298 | const playlistId = basename(segmentPath).match(playlistIdMatcher)[0] | 310 | const playlistId = basename(segmentPath).match(playlistIdMatcher)[0] |
299 | 311 | ||
300 | const segmentsToProcess = segmentsToProcessPerPlaylist[playlistId] || [] | 312 | const segmentsToProcess = segmentsToProcessPerPlaylist[playlistId] || [] |
301 | processHashSegments(segmentsToProcess) | 313 | processSegments(segmentsToProcess) |
302 | 314 | ||
303 | segmentsToProcessPerPlaylist[playlistId] = [ segmentPath ] | 315 | segmentsToProcessPerPlaylist[playlistId] = [ segmentPath ] |
304 | 316 | ||
@@ -369,7 +381,7 @@ class LiveManager { | |||
369 | .then(() => { | 381 | .then(() => { |
370 | // Process remaining segments hash | 382 | // Process remaining segments hash |
371 | for (const key of Object.keys(segmentsToProcessPerPlaylist)) { | 383 | for (const key of Object.keys(segmentsToProcessPerPlaylist)) { |
372 | processHashSegments(segmentsToProcessPerPlaylist[key]) | 384 | processSegments(segmentsToProcessPerPlaylist[key]) |
373 | } | 385 | } |
374 | }) | 386 | }) |
375 | .catch(err => logger.error('Cannot close watchers of %s or process remaining hash segments.', outPath, { err })) | 387 | .catch(err => logger.error('Cannot close watchers of %s or process remaining hash segments.', outPath, { err })) |