aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--server/initializers/constants.ts13
-rw-r--r--server/lib/live/live-manager.ts42
-rw-r--r--server/lib/live/shared/muxing-session.ts20
-rw-r--r--server/lib/live/shared/transcoding-wrapper/abstract-transcoding-wrapper.ts12
-rw-r--r--server/lib/live/shared/transcoding-wrapper/ffmpeg-transcoding-wrapper.ts4
-rw-r--r--server/lib/live/shared/transcoding-wrapper/remote-transcoding-wrapper.ts2
-rw-r--r--server/models/video/video-live.ts4
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 = {
55 WS: '', 55 WS: '',
56 HOSTNAME: '', 56 HOSTNAME: '',
57 PORT: 0, 57 PORT: 0,
58
58 RTMP_URL: '', 59 RTMP_URL: '',
59 RTMPS_URL: '' 60 RTMPS_URL: '',
61
62 RTMP_BASE_LIVE_URL: '',
63 RTMPS_BASE_LIVE_URL: ''
60} 64}
61 65
62// Sortable columns per schema 66// Sortable columns per schema
@@ -1242,8 +1246,11 @@ function updateWebserverUrls () {
1242 const rtmpHostname = CONFIG.LIVE.RTMP.PUBLIC_HOSTNAME || CONFIG.WEBSERVER.HOSTNAME 1246 const rtmpHostname = CONFIG.LIVE.RTMP.PUBLIC_HOSTNAME || CONFIG.WEBSERVER.HOSTNAME
1243 const rtmpsHostname = CONFIG.LIVE.RTMPS.PUBLIC_HOSTNAME || CONFIG.WEBSERVER.HOSTNAME 1247 const rtmpsHostname = CONFIG.LIVE.RTMPS.PUBLIC_HOSTNAME || CONFIG.WEBSERVER.HOSTNAME
1244 1248
1245 WEBSERVER.RTMP_URL = 'rtmp://' + rtmpHostname + ':' + CONFIG.LIVE.RTMP.PORT + '/' + VIDEO_LIVE.RTMP.BASE_PATH 1249 WEBSERVER.RTMP_URL = 'rtmp://' + rtmpHostname + ':' + CONFIG.LIVE.RTMP.PORT
1246 WEBSERVER.RTMPS_URL = 'rtmps://' + rtmpsHostname + ':' + CONFIG.LIVE.RTMPS.PORT + '/' + VIDEO_LIVE.RTMP.BASE_PATH 1250 WEBSERVER.RTMPS_URL = 'rtmps://' + rtmpsHostname + ':' + CONFIG.LIVE.RTMPS.PORT
1251
1252 WEBSERVER.RTMP_BASE_LIVE_URL = WEBSERVER.RTMP_URL + '/' + VIDEO_LIVE.RTMP.BASE_PATH
1253 WEBSERVER.RTMPS_BASE_LIVE_URL = WEBSERVER.RTMPS_URL + '/' + VIDEO_LIVE.RTMP.BASE_PATH
1247} 1254}
1248 1255
1249function updateWebserverConfig () { 1256function 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'
4import { createServer as createServerTLS, Server as ServerTLS } from 'tls' 4import { createServer as createServerTLS, Server as ServerTLS } from 'tls'
5import { logger, loggerTagsFactory } from '@server/helpers/logger' 5import { logger, loggerTagsFactory } from '@server/helpers/logger'
6import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config' 6import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config'
7import { VIDEO_LIVE } from '@server/initializers/constants' 7import { VIDEO_LIVE, WEBSERVER } from '@server/initializers/constants'
8import { sequelizeTypescript } from '@server/initializers/database' 8import { sequelizeTypescript } from '@server/initializers/database'
9import { RunnerJobModel } from '@server/models/runner/runner-job' 9import { RunnerJobModel } from '@server/models/runner/runner-job'
10import { UserModel } from '@server/models/user/user' 10import { UserModel } from '@server/models/user/user'
@@ -73,8 +73,10 @@ class LiveManager {
73 } 73 }
74 74
75 const session = this.getContext().sessions.get(sessionId) 75 const session = this.getContext().sessions.get(sessionId)
76 const inputLocalUrl = session.inputOriginLocalUrl + streamPath
77 const inputPublicUrl = session.inputOriginPublicUrl + streamPath
76 78
77 this.handleSession(sessionId, session.inputOriginUrl + streamPath, splittedPath[2]) 79 this.handleSession({ sessionId, inputPublicUrl, inputLocalUrl, streamKey: splittedPath[2] })
78 .catch(err => logger.error('Cannot handle sessions.', { err, ...lTags(sessionId) })) 80 .catch(err => logger.error('Cannot handle sessions.', { err, ...lTags(sessionId) }))
79 }) 81 })
80 82
@@ -110,7 +112,8 @@ class LiveManager {
110 this.rtmpServer = createServer(socket => { 112 this.rtmpServer = createServer(socket => {
111 const session = new NodeRtmpSession(config, socket) 113 const session = new NodeRtmpSession(config, socket)
112 114
113 session.inputOriginUrl = 'rtmp://127.0.0.1:' + CONFIG.LIVE.RTMP.PORT 115 session.inputOriginLocalUrl = 'rtmp://127.0.0.1:' + CONFIG.LIVE.RTMP.PORT
116 session.inputOriginPublicUrl = WEBSERVER.RTMP_URL
114 session.run() 117 session.run()
115 }) 118 })
116 119
@@ -133,7 +136,8 @@ class LiveManager {
133 this.rtmpsServer = createServerTLS(serverOptions, socket => { 136 this.rtmpsServer = createServerTLS(serverOptions, socket => {
134 const session = new NodeRtmpSession(config, socket) 137 const session = new NodeRtmpSession(config, socket)
135 138
136 session.inputOriginUrl = 'rtmps://127.0.0.1:' + CONFIG.LIVE.RTMPS.PORT 139 session.inputOriginLocalUrl = 'rtmps://127.0.0.1:' + CONFIG.LIVE.RTMPS.PORT
140 session.inputOriginPublicUrl = WEBSERVER.RTMPS_URL
137 session.run() 141 session.run()
138 }) 142 })
139 143
@@ -210,7 +214,14 @@ class LiveManager {
210 } 214 }
211 } 215 }
212 216
213 private async handleSession (sessionId: string, inputUrl: string, streamKey: string) { 217 private async handleSession (options: {
218 sessionId: string
219 inputLocalUrl: string
220 inputPublicUrl: string
221 streamKey: string
222 }) {
223 const { inputLocalUrl, inputPublicUrl, sessionId, streamKey } = options
224
214 const videoLive = await VideoLiveModel.loadByStreamKey(streamKey) 225 const videoLive = await VideoLiveModel.loadByStreamKey(streamKey)
215 if (!videoLive) { 226 if (!videoLive) {
216 logger.warn('Unknown live video with stream key %s.', streamKey, lTags(sessionId)) 227 logger.warn('Unknown live video with stream key %s.', streamKey, lTags(sessionId))
@@ -239,18 +250,18 @@ class LiveManager {
239 this.videoSessions.set(video.uuid, sessionId) 250 this.videoSessions.set(video.uuid, sessionId)
240 251
241 const now = Date.now() 252 const now = Date.now()
242 const probe = await ffprobePromise(inputUrl) 253 const probe = await ffprobePromise(inputLocalUrl)
243 254
244 const [ { resolution, ratio }, fps, bitrate, hasAudio ] = await Promise.all([ 255 const [ { resolution, ratio }, fps, bitrate, hasAudio ] = await Promise.all([
245 getVideoStreamDimensionsInfo(inputUrl, probe), 256 getVideoStreamDimensionsInfo(inputLocalUrl, probe),
246 getVideoStreamFPS(inputUrl, probe), 257 getVideoStreamFPS(inputLocalUrl, probe),
247 getVideoStreamBitrate(inputUrl, probe), 258 getVideoStreamBitrate(inputLocalUrl, probe),
248 hasAudioStream(inputUrl, probe) 259 hasAudioStream(inputLocalUrl, probe)
249 ]) 260 ])
250 261
251 logger.info( 262 logger.info(
252 '%s probing took %d ms (bitrate: %d, fps: %d, resolution: %d)', 263 '%s probing took %d ms (bitrate: %d, fps: %d, resolution: %d)',
253 inputUrl, Date.now() - now, bitrate, fps, resolution, lTags(sessionId, video.uuid) 264 inputLocalUrl, Date.now() - now, bitrate, fps, resolution, lTags(sessionId, video.uuid)
254 ) 265 )
255 266
256 const allResolutions = await Hooks.wrapObject( 267 const allResolutions = await Hooks.wrapObject(
@@ -268,7 +279,8 @@ class LiveManager {
268 sessionId, 279 sessionId,
269 videoLive, 280 videoLive,
270 281
271 inputUrl, 282 inputLocalUrl,
283 inputPublicUrl,
272 fps, 284 fps,
273 bitrate, 285 bitrate,
274 ratio, 286 ratio,
@@ -281,7 +293,9 @@ class LiveManager {
281 sessionId: string 293 sessionId: string
282 videoLive: MVideoLiveVideoWithSetting 294 videoLive: MVideoLiveVideoWithSetting
283 295
284 inputUrl: string 296 inputLocalUrl: string
297 inputPublicUrl: string
298
285 fps: number 299 fps: number
286 bitrate: number 300 bitrate: number
287 ratio: number 301 ratio: number
@@ -303,7 +317,7 @@ class LiveManager {
303 videoLive, 317 videoLive,
304 user, 318 user,
305 319
306 ...pick(options, [ 'inputUrl', 'bitrate', 'ratio', 'fps', 'allResolutions', 'hasAudio' ]) 320 ...pick(options, [ 'inputLocalUrl', 'inputPublicUrl', 'bitrate', 'ratio', 'fps', 'allResolutions', 'hasAudio' ])
307 }) 321 })
308 322
309 muxingSession.on('live-ready', () => this.publishAndFederateLive(videoLive, localLTags)) 323 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 {
62 private readonly user: MUserId 62 private readonly user: MUserId
63 private readonly sessionId: string 63 private readonly sessionId: string
64 private readonly videoLive: MVideoLiveVideo 64 private readonly videoLive: MVideoLiveVideo
65 private readonly inputUrl: string 65
66 private readonly inputLocalUrl: string
67 private readonly inputPublicUrl: string
68
66 private readonly fps: number 69 private readonly fps: number
67 private readonly allResolutions: number[] 70 private readonly allResolutions: number[]
68 71
@@ -107,7 +110,10 @@ class MuxingSession extends EventEmitter {
107 user: MUserId 110 user: MUserId
108 sessionId: string 111 sessionId: string
109 videoLive: MVideoLiveVideo 112 videoLive: MVideoLiveVideo
110 inputUrl: string 113
114 inputLocalUrl: string
115 inputPublicUrl: string
116
111 fps: number 117 fps: number
112 bitrate: number 118 bitrate: number
113 ratio: number 119 ratio: number
@@ -120,7 +126,10 @@ class MuxingSession extends EventEmitter {
120 this.user = options.user 126 this.user = options.user
121 this.sessionId = options.sessionId 127 this.sessionId = options.sessionId
122 this.videoLive = options.videoLive 128 this.videoLive = options.videoLive
123 this.inputUrl = options.inputUrl 129
130 this.inputLocalUrl = options.inputLocalUrl
131 this.inputPublicUrl = options.inputPublicUrl
132
124 this.fps = options.fps 133 this.fps = options.fps
125 134
126 this.bitrate = options.bitrate 135 this.bitrate = options.bitrate
@@ -375,7 +384,7 @@ class MuxingSession extends EventEmitter {
375 private onTranscodedEnded () { 384 private onTranscodedEnded () {
376 this.emit('transcoding-end', ({ videoUUID: this.videoUUID })) 385 this.emit('transcoding-end', ({ videoUUID: this.videoUUID }))
377 386
378 logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', this.inputUrl, this.lTags()) 387 logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', this.inputLocalUrl, this.lTags())
379 388
380 setTimeout(() => { 389 setTimeout(() => {
381 // Wait latest segments generation, and close watchers 390 // Wait latest segments generation, and close watchers
@@ -468,7 +477,8 @@ class MuxingSession extends EventEmitter {
468 477
469 lTags: this.lTags, 478 lTags: this.lTags,
470 479
471 inputUrl: this.inputUrl, 480 inputLocalUrl: this.inputLocalUrl,
481 inputPublicUrl: this.inputPublicUrl,
472 482
473 toTranscode: this.allResolutions.map(resolution => ({ 483 toTranscode: this.allResolutions.map(resolution => ({
474 resolution, 484 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 {
25 25
26 lTags: LoggerTagsFn 26 lTags: LoggerTagsFn
27 27
28 inputUrl: string 28 inputLocalUrl: string
29 inputPublicUrl: string
30
29 fps: number 31 fps: number
30 toTranscode: { 32 toTranscode: {
31 resolution: number 33 resolution: number
@@ -50,7 +52,9 @@ abstract class AbstractTranscodingWrapper extends EventEmitter {
50 fps: number 52 fps: number
51 }[] 53 }[]
52 54
53 protected readonly inputUrl: string 55 protected readonly inputLocalUrl: string
56 protected readonly inputPublicUrl: string
57
54 protected readonly fps: number 58 protected readonly fps: number
55 protected readonly bitrate: number 59 protected readonly bitrate: number
56 protected readonly ratio: number 60 protected readonly ratio: number
@@ -76,7 +80,9 @@ abstract class AbstractTranscodingWrapper extends EventEmitter {
76 this.videoUUID = options.videoLive.Video.uuid 80 this.videoUUID = options.videoLive.Video.uuid
77 this.streamingPlaylist = options.streamingPlaylist 81 this.streamingPlaylist = options.streamingPlaylist
78 82
79 this.inputUrl = options.inputUrl 83 this.inputLocalUrl = options.inputLocalUrl
84 this.inputPublicUrl = options.inputPublicUrl
85
80 this.fps = options.fps 86 this.fps = options.fps
81 this.toTranscode = options.toTranscode 87 this.toTranscode = options.toTranscode
82 88
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 {
15 async run () { 15 async run () {
16 this.ffmpegCommand = CONFIG.LIVE.TRANSCODING.ENABLED 16 this.ffmpegCommand = CONFIG.LIVE.TRANSCODING.ENABLED
17 ? await this.buildFFmpegLive().getLiveTranscodingCommand({ 17 ? await this.buildFFmpegLive().getLiveTranscodingCommand({
18 inputUrl: this.inputUrl, 18 inputUrl: this.inputLocalUrl,
19 19
20 outPath: this.outDirectory, 20 outPath: this.outDirectory,
21 masterPlaylistName: this.streamingPlaylist.playlistFilename, 21 masterPlaylistName: this.streamingPlaylist.playlistFilename,
@@ -31,7 +31,7 @@ export class FFmpegTranscodingWrapper extends AbstractTranscodingWrapper {
31 hasAudio: this.hasAudio 31 hasAudio: this.hasAudio
32 }) 32 })
33 : this.buildFFmpegLive().getLiveMuxingCommand({ 33 : this.buildFFmpegLive().getLiveMuxingCommand({
34 inputUrl: this.inputUrl, 34 inputUrl: this.inputLocalUrl,
35 outPath: this.outDirectory, 35 outPath: this.outDirectory,
36 36
37 masterPlaylistName: this.streamingPlaylist.playlistFilename, 37 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'
4export class RemoteTranscodingWrapper extends AbstractTranscodingWrapper { 4export class RemoteTranscodingWrapper extends AbstractTranscodingWrapper {
5 async run () { 5 async run () {
6 await new LiveRTMPHLSTranscodingJobHandler().create({ 6 await new LiveRTMPHLSTranscodingJobHandler().create({
7 rtmpUrl: this.inputUrl, 7 rtmpUrl: this.inputPublicUrl,
8 toTranscode: this.toTranscode, 8 toTranscode: this.toTranscode,
9 video: this.videoLive.Video, 9 video: this.videoLive.Video,
10 outputDirectory: this.outDirectory, 10 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<Partial<AttributesOnly<VideoLiveModel>
159 streamKey: this.streamKey, 159 streamKey: this.streamKey,
160 160
161 rtmpUrl: CONFIG.LIVE.RTMP.ENABLED 161 rtmpUrl: CONFIG.LIVE.RTMP.ENABLED
162 ? WEBSERVER.RTMP_URL 162 ? WEBSERVER.RTMP_BASE_LIVE_URL
163 : null, 163 : null,
164 164
165 rtmpsUrl: CONFIG.LIVE.RTMPS.ENABLED 165 rtmpsUrl: CONFIG.LIVE.RTMPS.ENABLED
166 ? WEBSERVER.RTMPS_URL 166 ? WEBSERVER.RTMPS_BASE_LIVE_URL
167 : null 167 : null
168 } 168 }
169 } 169 }