aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/live-manager.ts
diff options
context:
space:
mode:
Diffstat (limited to 'server/lib/live-manager.ts')
-rw-r--r--server/lib/live-manager.ts42
1 files changed, 25 insertions, 17 deletions
diff --git a/server/lib/live-manager.ts b/server/lib/live-manager.ts
index 2d8f906e9..6eb05c9d6 100644
--- a/server/lib/live-manager.ts
+++ b/server/lib/live-manager.ts
@@ -4,7 +4,7 @@ import * as chokidar from 'chokidar'
4import { FfmpegCommand } from 'fluent-ffmpeg' 4import { FfmpegCommand } from 'fluent-ffmpeg'
5import { ensureDir, stat } from 'fs-extra' 5import { ensureDir, stat } from 'fs-extra'
6import { basename } from 'path' 6import { basename } from 'path'
7import { computeResolutionsToTranscode, runLiveMuxing, runLiveTranscoding } from '@server/helpers/ffmpeg-utils' 7import { computeResolutionsToTranscode, getVideoFileFPS, getVideoFileResolution, getVideoStreamCodec, getVideoStreamSize, runLiveMuxing, runLiveTranscoding } from '@server/helpers/ffmpeg-utils'
8import { logger } from '@server/helpers/logger' 8import { logger } from '@server/helpers/logger'
9import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config' 9import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config'
10import { MEMOIZE_TTL, P2P_MEDIA_LOADER_PEER_VERSION, VIDEO_LIVE, WEBSERVER } from '@server/initializers/constants' 10import { MEMOIZE_TTL, P2P_MEDIA_LOADER_PEER_VERSION, VIDEO_LIVE, WEBSERVER } from '@server/initializers/constants'
@@ -137,6 +137,13 @@ class LiveManager {
137 this.abortSession(sessionId) 137 this.abortSession(sessionId)
138 } 138 }
139 139
140 getLiveQuotaUsedByUser (userId: number) {
141 const currentLives = this.livesPerUser.get(userId)
142 if (!currentLives) return 0
143
144 return currentLives.reduce((sum, obj) => sum + obj.size, 0)
145 }
146
140 private getContext () { 147 private getContext () {
141 return context 148 return context
142 } 149 }
@@ -173,8 +180,15 @@ class LiveManager {
173 const playlistUrl = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsMasterPlaylistStaticPath(video.uuid) 180 const playlistUrl = WEBSERVER.URL + VideoStreamingPlaylistModel.getHlsMasterPlaylistStaticPath(video.uuid)
174 181
175 const session = this.getContext().sessions.get(sessionId) 182 const session = this.getContext().sessions.get(sessionId)
183 const rtmpUrl = 'rtmp://127.0.0.1:' + config.rtmp.port + streamPath
184
185 const [ resolutionResult, fps ] = await Promise.all([
186 getVideoFileResolution(rtmpUrl),
187 getVideoFileFPS(rtmpUrl)
188 ])
189
176 const resolutionsEnabled = CONFIG.LIVE.TRANSCODING.ENABLED 190 const resolutionsEnabled = CONFIG.LIVE.TRANSCODING.ENABLED
177 ? computeResolutionsToTranscode(session.videoHeight, 'live') 191 ? computeResolutionsToTranscode(resolutionResult.videoFileResolution, 'live')
178 : [] 192 : []
179 193
180 logger.info('Will mux/transcode live video of original resolution %d.', session.videoHeight, { resolutionsEnabled }) 194 logger.info('Will mux/transcode live video of original resolution %d.', session.videoHeight, { resolutionsEnabled })
@@ -193,8 +207,9 @@ class LiveManager {
193 sessionId, 207 sessionId,
194 videoLive, 208 videoLive,
195 playlist: videoStreamingPlaylist, 209 playlist: videoStreamingPlaylist,
196 streamPath,
197 originalResolution: session.videoHeight, 210 originalResolution: session.videoHeight,
211 rtmpUrl,
212 fps,
198 resolutionsEnabled 213 resolutionsEnabled
199 }) 214 })
200 } 215 }
@@ -203,11 +218,12 @@ class LiveManager {
203 sessionId: string 218 sessionId: string
204 videoLive: MVideoLiveVideo 219 videoLive: MVideoLiveVideo
205 playlist: MStreamingPlaylist 220 playlist: MStreamingPlaylist
206 streamPath: string 221 rtmpUrl: string
222 fps: number
207 resolutionsEnabled: number[] 223 resolutionsEnabled: number[]
208 originalResolution: number 224 originalResolution: number
209 }) { 225 }) {
210 const { sessionId, videoLive, playlist, streamPath, resolutionsEnabled, originalResolution } = options 226 const { sessionId, videoLive, playlist, resolutionsEnabled, originalResolution, fps, rtmpUrl } = options
211 const startStreamDateTime = new Date().getTime() 227 const startStreamDateTime = new Date().getTime()
212 const allResolutions = resolutionsEnabled.concat([ originalResolution ]) 228 const allResolutions = resolutionsEnabled.concat([ originalResolution ])
213 229
@@ -238,17 +254,16 @@ class LiveManager {
238 const outPath = getHLSDirectory(videoLive.Video) 254 const outPath = getHLSDirectory(videoLive.Video)
239 await ensureDir(outPath) 255 await ensureDir(outPath)
240 256
257 const videoUUID = videoLive.Video.uuid
241 const deleteSegments = videoLive.saveReplay === false 258 const deleteSegments = videoLive.saveReplay === false
242 259
243 const rtmpUrl = 'rtmp://127.0.0.1:' + config.rtmp.port + streamPath
244 const ffmpegExec = CONFIG.LIVE.TRANSCODING.ENABLED 260 const ffmpegExec = CONFIG.LIVE.TRANSCODING.ENABLED
245 ? runLiveTranscoding(rtmpUrl, outPath, allResolutions, deleteSegments) 261 ? runLiveTranscoding(rtmpUrl, outPath, allResolutions, fps, deleteSegments)
246 : runLiveMuxing(rtmpUrl, outPath, deleteSegments) 262 : runLiveMuxing(rtmpUrl, outPath, deleteSegments)
247 263
248 logger.info('Running live muxing/transcoding.') 264 logger.info('Running live muxing/transcoding for %s.', videoUUID)
249 this.transSessions.set(sessionId, ffmpegExec) 265 this.transSessions.set(sessionId, ffmpegExec)
250 266
251 const videoUUID = videoLive.Video.uuid
252 const tsWatcher = chokidar.watch(outPath + '/*.ts') 267 const tsWatcher = chokidar.watch(outPath + '/*.ts')
253 268
254 const updateSegment = segmentPath => this.segmentsSha256Queue.push({ operation: 'update', segmentPath, videoUUID }) 269 const updateSegment = segmentPath => this.segmentsSha256Queue.push({ operation: 'update', segmentPath, videoUUID })
@@ -307,7 +322,7 @@ class LiveManager {
307 }) 322 })
308 323
309 const onFFmpegEnded = () => { 324 const onFFmpegEnded = () => {
310 logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', streamPath) 325 logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', rtmpUrl)
311 326
312 this.transSessions.delete(sessionId) 327 this.transSessions.delete(sessionId)
313 328
@@ -332,13 +347,6 @@ class LiveManager {
332 ffmpegExec.on('end', () => onFFmpegEnded()) 347 ffmpegExec.on('end', () => onFFmpegEnded())
333 } 348 }
334 349
335 getLiveQuotaUsedByUser (userId: number) {
336 const currentLives = this.livesPerUser.get(userId)
337 if (!currentLives) return 0
338
339 return currentLives.reduce((sum, obj) => sum + obj.size, 0)
340 }
341
342 private async onEndTransmuxing (videoId: number, cleanupNow = false) { 350 private async onEndTransmuxing (videoId: number, cleanupNow = false) {
343 try { 351 try {
344 const fullVideo = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId) 352 const fullVideo = await VideoModel.loadAndPopulateAccountAndServerAndTags(videoId)