From 287057050526e1f474c4f4d5d9a7ef3b7c677f2f Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 16 May 2023 09:12:50 +0200 Subject: [PATCH] Provide public RTMP URL to runners --- server/initializers/constants.ts | 13 ++++-- server/lib/live/live-manager.ts | 42 ++++++++++++------- server/lib/live/shared/muxing-session.ts | 20 ++++++--- .../abstract-transcoding-wrapper.ts | 12 ++++-- .../ffmpeg-transcoding-wrapper.ts | 4 +- .../remote-transcoding-wrapper.ts | 2 +- server/models/video/video-live.ts | 4 +- 7 files changed, 67 insertions(+), 30 deletions(-) diff --git a/server/initializers/constants.ts b/server/initializers/constants.ts index 1dfc9fb27..46455dd5b 100644 --- a/server/initializers/constants.ts +++ b/server/initializers/constants.ts @@ -55,8 +55,12 @@ const WEBSERVER = { WS: '', HOSTNAME: '', PORT: 0, + RTMP_URL: '', - RTMPS_URL: '' + RTMPS_URL: '', + + RTMP_BASE_LIVE_URL: '', + RTMPS_BASE_LIVE_URL: '' } // Sortable columns per schema @@ -1242,8 +1246,11 @@ function updateWebserverUrls () { const rtmpHostname = CONFIG.LIVE.RTMP.PUBLIC_HOSTNAME || CONFIG.WEBSERVER.HOSTNAME const rtmpsHostname = CONFIG.LIVE.RTMPS.PUBLIC_HOSTNAME || CONFIG.WEBSERVER.HOSTNAME - WEBSERVER.RTMP_URL = 'rtmp://' + rtmpHostname + ':' + CONFIG.LIVE.RTMP.PORT + '/' + VIDEO_LIVE.RTMP.BASE_PATH - WEBSERVER.RTMPS_URL = 'rtmps://' + rtmpsHostname + ':' + CONFIG.LIVE.RTMPS.PORT + '/' + VIDEO_LIVE.RTMP.BASE_PATH + WEBSERVER.RTMP_URL = 'rtmp://' + rtmpHostname + ':' + CONFIG.LIVE.RTMP.PORT + WEBSERVER.RTMPS_URL = 'rtmps://' + rtmpsHostname + ':' + CONFIG.LIVE.RTMPS.PORT + + WEBSERVER.RTMP_BASE_LIVE_URL = WEBSERVER.RTMP_URL + '/' + VIDEO_LIVE.RTMP.BASE_PATH + WEBSERVER.RTMPS_BASE_LIVE_URL = WEBSERVER.RTMPS_URL + '/' + VIDEO_LIVE.RTMP.BASE_PATH } function updateWebserverConfig () { diff --git a/server/lib/live/live-manager.ts b/server/lib/live/live-manager.ts index 6d51f4de7..68aa18443 100644 --- a/server/lib/live/live-manager.ts +++ b/server/lib/live/live-manager.ts @@ -4,7 +4,7 @@ import { join } from 'path' import { createServer as createServerTLS, Server as ServerTLS } from 'tls' import { logger, loggerTagsFactory } from '@server/helpers/logger' import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config' -import { VIDEO_LIVE } from '@server/initializers/constants' +import { VIDEO_LIVE, WEBSERVER } from '@server/initializers/constants' import { sequelizeTypescript } from '@server/initializers/database' import { RunnerJobModel } from '@server/models/runner/runner-job' import { UserModel } from '@server/models/user/user' @@ -73,8 +73,10 @@ class LiveManager { } const session = this.getContext().sessions.get(sessionId) + const inputLocalUrl = session.inputOriginLocalUrl + streamPath + const inputPublicUrl = session.inputOriginPublicUrl + streamPath - this.handleSession(sessionId, session.inputOriginUrl + streamPath, splittedPath[2]) + this.handleSession({ sessionId, inputPublicUrl, inputLocalUrl, streamKey: splittedPath[2] }) .catch(err => logger.error('Cannot handle sessions.', { err, ...lTags(sessionId) })) }) @@ -110,7 +112,8 @@ class LiveManager { this.rtmpServer = createServer(socket => { const session = new NodeRtmpSession(config, socket) - session.inputOriginUrl = 'rtmp://127.0.0.1:' + CONFIG.LIVE.RTMP.PORT + session.inputOriginLocalUrl = 'rtmp://127.0.0.1:' + CONFIG.LIVE.RTMP.PORT + session.inputOriginPublicUrl = WEBSERVER.RTMP_URL session.run() }) @@ -133,7 +136,8 @@ class LiveManager { this.rtmpsServer = createServerTLS(serverOptions, socket => { const session = new NodeRtmpSession(config, socket) - session.inputOriginUrl = 'rtmps://127.0.0.1:' + CONFIG.LIVE.RTMPS.PORT + session.inputOriginLocalUrl = 'rtmps://127.0.0.1:' + CONFIG.LIVE.RTMPS.PORT + session.inputOriginPublicUrl = WEBSERVER.RTMPS_URL session.run() }) @@ -210,7 +214,14 @@ class LiveManager { } } - private async handleSession (sessionId: string, inputUrl: string, streamKey: string) { + private async handleSession (options: { + sessionId: string + inputLocalUrl: string + inputPublicUrl: string + streamKey: string + }) { + const { inputLocalUrl, inputPublicUrl, sessionId, streamKey } = options + const videoLive = await VideoLiveModel.loadByStreamKey(streamKey) if (!videoLive) { logger.warn('Unknown live video with stream key %s.', streamKey, lTags(sessionId)) @@ -239,18 +250,18 @@ class LiveManager { this.videoSessions.set(video.uuid, sessionId) const now = Date.now() - const probe = await ffprobePromise(inputUrl) + const probe = await ffprobePromise(inputLocalUrl) const [ { resolution, ratio }, fps, bitrate, hasAudio ] = await Promise.all([ - getVideoStreamDimensionsInfo(inputUrl, probe), - getVideoStreamFPS(inputUrl, probe), - getVideoStreamBitrate(inputUrl, probe), - hasAudioStream(inputUrl, probe) + getVideoStreamDimensionsInfo(inputLocalUrl, probe), + getVideoStreamFPS(inputLocalUrl, probe), + getVideoStreamBitrate(inputLocalUrl, probe), + hasAudioStream(inputLocalUrl, probe) ]) logger.info( '%s probing took %d ms (bitrate: %d, fps: %d, resolution: %d)', - inputUrl, Date.now() - now, bitrate, fps, resolution, lTags(sessionId, video.uuid) + inputLocalUrl, Date.now() - now, bitrate, fps, resolution, lTags(sessionId, video.uuid) ) const allResolutions = await Hooks.wrapObject( @@ -268,7 +279,8 @@ class LiveManager { sessionId, videoLive, - inputUrl, + inputLocalUrl, + inputPublicUrl, fps, bitrate, ratio, @@ -281,7 +293,9 @@ class LiveManager { sessionId: string videoLive: MVideoLiveVideoWithSetting - inputUrl: string + inputLocalUrl: string + inputPublicUrl: string + fps: number bitrate: number ratio: number @@ -303,7 +317,7 @@ class LiveManager { videoLive, user, - ...pick(options, [ 'inputUrl', 'bitrate', 'ratio', 'fps', 'allResolutions', 'hasAudio' ]) + ...pick(options, [ 'inputLocalUrl', 'inputPublicUrl', 'bitrate', 'ratio', 'fps', 'allResolutions', 'hasAudio' ]) }) muxingSession.on('live-ready', () => this.publishAndFederateLive(videoLive, localLTags)) diff --git a/server/lib/live/shared/muxing-session.ts b/server/lib/live/shared/muxing-session.ts index 57e28aabf..6632499ff 100644 --- a/server/lib/live/shared/muxing-session.ts +++ b/server/lib/live/shared/muxing-session.ts @@ -62,7 +62,10 @@ class MuxingSession extends EventEmitter { private readonly user: MUserId private readonly sessionId: string private readonly videoLive: MVideoLiveVideo - private readonly inputUrl: string + + private readonly inputLocalUrl: string + private readonly inputPublicUrl: string + private readonly fps: number private readonly allResolutions: number[] @@ -107,7 +110,10 @@ class MuxingSession extends EventEmitter { user: MUserId sessionId: string videoLive: MVideoLiveVideo - inputUrl: string + + inputLocalUrl: string + inputPublicUrl: string + fps: number bitrate: number ratio: number @@ -120,7 +126,10 @@ class MuxingSession extends EventEmitter { this.user = options.user this.sessionId = options.sessionId this.videoLive = options.videoLive - this.inputUrl = options.inputUrl + + this.inputLocalUrl = options.inputLocalUrl + this.inputPublicUrl = options.inputPublicUrl + this.fps = options.fps this.bitrate = options.bitrate @@ -375,7 +384,7 @@ class MuxingSession extends EventEmitter { private onTranscodedEnded () { this.emit('transcoding-end', ({ videoUUID: this.videoUUID })) - logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', this.inputUrl, this.lTags()) + logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', this.inputLocalUrl, this.lTags()) setTimeout(() => { // Wait latest segments generation, and close watchers @@ -468,7 +477,8 @@ class MuxingSession extends EventEmitter { lTags: this.lTags, - inputUrl: this.inputUrl, + inputLocalUrl: this.inputLocalUrl, + inputPublicUrl: this.inputPublicUrl, toTranscode: this.allResolutions.map(resolution => ({ resolution, diff --git a/server/lib/live/shared/transcoding-wrapper/abstract-transcoding-wrapper.ts b/server/lib/live/shared/transcoding-wrapper/abstract-transcoding-wrapper.ts index 226ba4573..ee61d7690 100644 --- a/server/lib/live/shared/transcoding-wrapper/abstract-transcoding-wrapper.ts +++ b/server/lib/live/shared/transcoding-wrapper/abstract-transcoding-wrapper.ts @@ -25,7 +25,9 @@ interface AbstractTranscodingWrapperOptions { lTags: LoggerTagsFn - inputUrl: string + inputLocalUrl: string + inputPublicUrl: string + fps: number toTranscode: { resolution: number @@ -50,7 +52,9 @@ abstract class AbstractTranscodingWrapper extends EventEmitter { fps: number }[] - protected readonly inputUrl: string + protected readonly inputLocalUrl: string + protected readonly inputPublicUrl: string + protected readonly fps: number protected readonly bitrate: number protected readonly ratio: number @@ -76,7 +80,9 @@ abstract class AbstractTranscodingWrapper extends EventEmitter { this.videoUUID = options.videoLive.Video.uuid this.streamingPlaylist = options.streamingPlaylist - this.inputUrl = options.inputUrl + this.inputLocalUrl = options.inputLocalUrl + this.inputPublicUrl = options.inputPublicUrl + this.fps = options.fps this.toTranscode = options.toTranscode diff --git a/server/lib/live/shared/transcoding-wrapper/ffmpeg-transcoding-wrapper.ts b/server/lib/live/shared/transcoding-wrapper/ffmpeg-transcoding-wrapper.ts index 1f4c12bd4..c82970b88 100644 --- a/server/lib/live/shared/transcoding-wrapper/ffmpeg-transcoding-wrapper.ts +++ b/server/lib/live/shared/transcoding-wrapper/ffmpeg-transcoding-wrapper.ts @@ -15,7 +15,7 @@ export class FFmpegTranscodingWrapper extends AbstractTranscodingWrapper { async run () { this.ffmpegCommand = CONFIG.LIVE.TRANSCODING.ENABLED ? await this.buildFFmpegLive().getLiveTranscodingCommand({ - inputUrl: this.inputUrl, + inputUrl: this.inputLocalUrl, outPath: this.outDirectory, masterPlaylistName: this.streamingPlaylist.playlistFilename, @@ -31,7 +31,7 @@ export class FFmpegTranscodingWrapper extends AbstractTranscodingWrapper { hasAudio: this.hasAudio }) : this.buildFFmpegLive().getLiveMuxingCommand({ - inputUrl: this.inputUrl, + inputUrl: this.inputLocalUrl, outPath: this.outDirectory, masterPlaylistName: this.streamingPlaylist.playlistFilename, diff --git a/server/lib/live/shared/transcoding-wrapper/remote-transcoding-wrapper.ts b/server/lib/live/shared/transcoding-wrapper/remote-transcoding-wrapper.ts index 345eaf442..6770a5e6f 100644 --- a/server/lib/live/shared/transcoding-wrapper/remote-transcoding-wrapper.ts +++ b/server/lib/live/shared/transcoding-wrapper/remote-transcoding-wrapper.ts @@ -4,7 +4,7 @@ import { AbstractTranscodingWrapper } from './abstract-transcoding-wrapper' export class RemoteTranscodingWrapper extends AbstractTranscodingWrapper { async run () { await new LiveRTMPHLSTranscodingJobHandler().create({ - rtmpUrl: this.inputUrl, + rtmpUrl: this.inputPublicUrl, toTranscode: this.toTranscode, video: this.videoLive.Video, outputDirectory: this.outDirectory, diff --git a/server/models/video/video-live.ts b/server/models/video/video-live.ts index 1acf9cbf3..ca1118641 100644 --- a/server/models/video/video-live.ts +++ b/server/models/video/video-live.ts @@ -159,11 +159,11 @@ export class VideoLiveModel extends Model streamKey: this.streamKey, rtmpUrl: CONFIG.LIVE.RTMP.ENABLED - ? WEBSERVER.RTMP_URL + ? WEBSERVER.RTMP_BASE_LIVE_URL : null, rtmpsUrl: CONFIG.LIVE.RTMPS.ENABLED - ? WEBSERVER.RTMPS_URL + ? WEBSERVER.RTMPS_BASE_LIVE_URL : null } }