X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=server%2Flib%2Flive-manager.ts;h=ef50e3cdb758d79e07fb91e2baabc00ddbf7f6da;hb=5b9b403a206e84342edfff536f0b30167976e80e;hp=dcf0161694afaf6750a432bf103c388d89f7fe79;hpb=bb4ba6d94c5051fdd665ebe63fffcc105778b8be;p=github%2FChocobozzz%2FPeerTube.git diff --git a/server/lib/live-manager.ts b/server/lib/live-manager.ts index dcf016169..ef50e3cdb 100644 --- a/server/lib/live-manager.ts +++ b/server/lib/live-manager.ts @@ -1,7 +1,8 @@ +import * as Bluebird from 'bluebird' import * as chokidar from 'chokidar' import { FfmpegCommand } from 'fluent-ffmpeg' -import { copy, ensureDir, stat } from 'fs-extra' +import { appendFile, ensureDir, readFile, stat } from 'fs-extra' import { basename, join } from 'path' import { isTestInstance } from '@server/helpers/core-utils' import { getLiveMuxingCommand, getLiveTranscodingCommand } from '@server/helpers/ffmpeg-utils' @@ -158,6 +159,32 @@ class LiveManager { this.segmentsSha256.delete(videoUUID) } + addSegmentToReplay (hlsVideoPath: string, segmentPath: string) { + const segmentName = basename(segmentPath) + const dest = join(hlsVideoPath, VIDEO_LIVE.REPLAY_DIRECTORY, this.buildConcatenatedName(segmentName)) + + return readFile(segmentPath) + .then(data => appendFile(dest, data)) + .catch(err => logger.error('Cannot copy segment %s to repay directory.', segmentPath, { err })) + } + + buildConcatenatedName (segmentOrPlaylistPath: string) { + const num = basename(segmentOrPlaylistPath).match(/^(\d+)(-|\.)/) + + return 'concat-' + num[1] + '.ts' + } + + private processSegments (hlsVideoPath: string, videoUUID: string, videoLive: MVideoLive, segmentPaths: string[]) { + Bluebird.mapSeries(segmentPaths, async previousSegment => { + // Add sha hash of previous segments, because ffmpeg should have finished generating them + await this.addSegmentSha(videoUUID, previousSegment) + + if (videoLive.saveReplay) { + await this.addSegmentToReplay(hlsVideoPath, previousSegment) + } + }).catch(err => logger.error('Cannot process segments in %s', hlsVideoPath, { err })) + } + private getContext () { return context } @@ -302,28 +329,13 @@ class LiveManager { const segmentsToProcessPerPlaylist: { [playlistId: string]: string[] } = {} const playlistIdMatcher = /^([\d+])-/ - const processSegments = (segmentsToProcess: string[]) => { - // Add sha hash of previous segments, because ffmpeg should have finished generating them - for (const previousSegment of segmentsToProcess) { - this.addSegmentSha(videoUUID, previousSegment) - .catch(err => logger.error('Cannot add sha segment of video %s -> %s.', videoUUID, previousSegment, { err })) - - if (videoLive.saveReplay) { - const segmentName = basename(previousSegment) - - copy(previousSegment, join(outPath, VIDEO_LIVE.REPLAY_DIRECTORY, segmentName)) - .catch(err => logger.error('Cannot copy segment %s to repay directory.', previousSegment, { err })) - } - } - } - const addHandler = segmentPath => { logger.debug('Live add handler of %s.', segmentPath) const playlistId = basename(segmentPath).match(playlistIdMatcher)[0] const segmentsToProcess = segmentsToProcessPerPlaylist[playlistId] || [] - processSegments(segmentsToProcess) + this.processSegments(outPath, videoUUID, videoLive, segmentsToProcess) segmentsToProcessPerPlaylist[playlistId] = [ segmentPath ] @@ -400,7 +412,7 @@ class LiveManager { .then(() => { // Process remaining segments hash for (const key of Object.keys(segmentsToProcessPerPlaylist)) { - processSegments(segmentsToProcessPerPlaylist[key]) + this.processSegments(outPath, videoUUID, videoLive, segmentsToProcessPerPlaylist[key]) } }) .catch(err => logger.error('Cannot close watchers of %s or process remaining hash segments.', outPath, { err }))