diff options
-rw-r--r-- | server/lib/live/shared/muxing-session.ts | 43 | ||||
-rw-r--r-- | server/tests/api/server/services.ts | 6 |
2 files changed, 32 insertions, 17 deletions
diff --git a/server/lib/live/shared/muxing-session.ts b/server/lib/live/shared/muxing-session.ts index c71f4e25f..eccaefcfa 100644 --- a/server/lib/live/shared/muxing-session.ts +++ b/server/lib/live/shared/muxing-session.ts | |||
@@ -135,13 +135,20 @@ class MuxingSession extends EventEmitter { | |||
135 | }) | 135 | }) |
136 | : getLiveMuxingCommand(this.inputUrl, outPath, this.streamingPlaylist.playlistFilename) | 136 | : getLiveMuxingCommand(this.inputUrl, outPath, this.streamingPlaylist.playlistFilename) |
137 | 137 | ||
138 | logger.info('Running live muxing/transcoding for %s.', this.videoUUID, this.lTags) | 138 | logger.info('Running live muxing/transcoding for %s.', this.videoUUID, this.lTags()) |
139 | 139 | ||
140 | this.watchTSFiles(outPath) | 140 | this.watchTSFiles(outPath) |
141 | this.watchMasterFile(outPath) | 141 | this.watchMasterFile(outPath) |
142 | 142 | ||
143 | let ffmpegShellCommand: string | ||
144 | this.ffmpegCommand.on('start', cmdline => { | ||
145 | ffmpegShellCommand = cmdline | ||
146 | |||
147 | logger.debug('Running ffmpeg command for live', { ffmpegShellCommand, ...this.lTags() }) | ||
148 | }) | ||
149 | |||
143 | this.ffmpegCommand.on('error', (err, stdout, stderr) => { | 150 | this.ffmpegCommand.on('error', (err, stdout, stderr) => { |
144 | this.onFFmpegError(err, stdout, stderr, outPath) | 151 | this.onFFmpegError({ err, stdout, stderr, outPath, ffmpegShellCommand }) |
145 | }) | 152 | }) |
146 | 153 | ||
147 | this.ffmpegCommand.on('end', () => this.onFFmpegEnded(outPath)) | 154 | this.ffmpegCommand.on('end', () => this.onFFmpegEnded(outPath)) |
@@ -161,19 +168,27 @@ class MuxingSession extends EventEmitter { | |||
161 | this.hasClientSocketInBadHealthWithCache.clear() | 168 | this.hasClientSocketInBadHealthWithCache.clear() |
162 | } | 169 | } |
163 | 170 | ||
164 | private onFFmpegError (err: any, stdout: string, stderr: string, outPath: string) { | 171 | private onFFmpegError (options: { |
172 | err: any | ||
173 | stdout: string | ||
174 | stderr: string | ||
175 | outPath: string | ||
176 | ffmpegShellCommand: string | ||
177 | }) { | ||
178 | const { err, stdout, stderr, outPath, ffmpegShellCommand } = options | ||
179 | |||
165 | this.onFFmpegEnded(outPath) | 180 | this.onFFmpegEnded(outPath) |
166 | 181 | ||
167 | // Don't care that we killed the ffmpeg process | 182 | // Don't care that we killed the ffmpeg process |
168 | if (err?.message?.includes('Exiting normally')) return | 183 | if (err?.message?.includes('Exiting normally')) return |
169 | 184 | ||
170 | logger.error('Live transcoding error.', { err, stdout, stderr, ...this.lTags }) | 185 | logger.error('Live transcoding error.', { err, stdout, stderr, ffmpegShellCommand, ...this.lTags() }) |
171 | 186 | ||
172 | this.emit('ffmpeg-error', ({ sessionId: this.sessionId })) | 187 | this.emit('ffmpeg-error', ({ sessionId: this.sessionId })) |
173 | } | 188 | } |
174 | 189 | ||
175 | private onFFmpegEnded (outPath: string) { | 190 | private onFFmpegEnded (outPath: string) { |
176 | logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', this.inputUrl, this.lTags) | 191 | logger.info('RTMP transmuxing for video %s ended. Scheduling cleanup', this.inputUrl, this.lTags()) |
177 | 192 | ||
178 | setTimeout(() => { | 193 | setTimeout(() => { |
179 | // Wait latest segments generation, and close watchers | 194 | // Wait latest segments generation, and close watchers |
@@ -188,7 +203,7 @@ class MuxingSession extends EventEmitter { | |||
188 | .catch(err => { | 203 | .catch(err => { |
189 | logger.error( | 204 | logger.error( |
190 | 'Cannot close watchers of %s or process remaining hash segments.', outPath, | 205 | 'Cannot close watchers of %s or process remaining hash segments.', outPath, |
191 | { err, ...this.lTags } | 206 | { err, ...this.lTags() } |
192 | ) | 207 | ) |
193 | }) | 208 | }) |
194 | 209 | ||
@@ -203,7 +218,7 @@ class MuxingSession extends EventEmitter { | |||
203 | this.emit('master-playlist-created', { videoId: this.videoId }) | 218 | this.emit('master-playlist-created', { videoId: this.videoId }) |
204 | 219 | ||
205 | this.masterWatcher.close() | 220 | this.masterWatcher.close() |
206 | .catch(err => logger.error('Cannot close master watcher of %s.', outPath, { err, ...this.lTags })) | 221 | .catch(err => logger.error('Cannot close master watcher of %s.', outPath, { err, ...this.lTags() })) |
207 | }) | 222 | }) |
208 | } | 223 | } |
209 | 224 | ||
@@ -215,7 +230,7 @@ class MuxingSession extends EventEmitter { | |||
215 | const playlistIdMatcher = /^([\d+])-/ | 230 | const playlistIdMatcher = /^([\d+])-/ |
216 | 231 | ||
217 | const addHandler = async segmentPath => { | 232 | const addHandler = async segmentPath => { |
218 | logger.debug('Live add handler of %s.', segmentPath, this.lTags) | 233 | logger.debug('Live add handler of %s.', segmentPath, this.lTags()) |
219 | 234 | ||
220 | const playlistId = basename(segmentPath).match(playlistIdMatcher)[0] | 235 | const playlistId = basename(segmentPath).match(playlistIdMatcher)[0] |
221 | 236 | ||
@@ -259,7 +274,7 @@ class MuxingSession extends EventEmitter { | |||
259 | 274 | ||
260 | return canUpload !== true | 275 | return canUpload !== true |
261 | } catch (err) { | 276 | } catch (err) { |
262 | logger.error('Cannot stat %s or check quota of %d.', segmentPath, this.user.id, { err, ...this.lTags }) | 277 | logger.error('Cannot stat %s or check quota of %d.', segmentPath, this.user.id, { err, ...this.lTags() }) |
263 | } | 278 | } |
264 | } | 279 | } |
265 | 280 | ||
@@ -277,7 +292,7 @@ class MuxingSession extends EventEmitter { | |||
277 | }) | 292 | }) |
278 | 293 | ||
279 | VideoFileModel.customUpsert(file, 'streaming-playlist', null) | 294 | VideoFileModel.customUpsert(file, 'streaming-playlist', null) |
280 | .catch(err => logger.error('Cannot create file for live streaming.', { err, ...this.lTags })) | 295 | .catch(err => logger.error('Cannot create file for live streaming.', { err, ...this.lTags() })) |
281 | } | 296 | } |
282 | } | 297 | } |
283 | 298 | ||
@@ -313,14 +328,14 @@ class MuxingSession extends EventEmitter { | |||
313 | if (this.saveReplay) { | 328 | if (this.saveReplay) { |
314 | await this.addSegmentToReplay(hlsVideoPath, previousSegment) | 329 | await this.addSegmentToReplay(hlsVideoPath, previousSegment) |
315 | } | 330 | } |
316 | }).catch(err => logger.error('Cannot process segments in %s', hlsVideoPath, { err, ...this.lTags })) | 331 | }).catch(err => logger.error('Cannot process segments in %s', hlsVideoPath, { err, ...this.lTags() })) |
317 | } | 332 | } |
318 | 333 | ||
319 | private hasClientSocketInBadHealth (sessionId: string) { | 334 | private hasClientSocketInBadHealth (sessionId: string) { |
320 | const rtmpSession = this.context.sessions.get(sessionId) | 335 | const rtmpSession = this.context.sessions.get(sessionId) |
321 | 336 | ||
322 | if (!rtmpSession) { | 337 | if (!rtmpSession) { |
323 | logger.warn('Cannot get session %s to check players socket health.', sessionId, this.lTags) | 338 | logger.warn('Cannot get session %s to check players socket health.', sessionId, this.lTags()) |
324 | return | 339 | return |
325 | } | 340 | } |
326 | 341 | ||
@@ -328,7 +343,7 @@ class MuxingSession extends EventEmitter { | |||
328 | const playerSession = this.context.sessions.get(playerSessionId) | 343 | const playerSession = this.context.sessions.get(playerSessionId) |
329 | 344 | ||
330 | if (!playerSession) { | 345 | if (!playerSession) { |
331 | logger.error('Cannot get player session %s to check socket health.', playerSession, this.lTags) | 346 | logger.error('Cannot get player session %s to check socket health.', playerSession, this.lTags()) |
332 | continue | 347 | continue |
333 | } | 348 | } |
334 | 349 | ||
@@ -349,7 +364,7 @@ class MuxingSession extends EventEmitter { | |||
349 | 364 | ||
350 | await appendFile(dest, data) | 365 | await appendFile(dest, data) |
351 | } catch (err) { | 366 | } catch (err) { |
352 | logger.error('Cannot copy segment %s to replay directory.', segmentPath, { err, ...this.lTags }) | 367 | logger.error('Cannot copy segment %s to replay directory.', segmentPath, { err, ...this.lTags() }) |
353 | } | 368 | } |
354 | } | 369 | } |
355 | } | 370 | } |
diff --git a/server/tests/api/server/services.ts b/server/tests/api/server/services.ts index 3a87df981..823630ae4 100644 --- a/server/tests/api/server/services.ts +++ b/server/tests/api/server/services.ts | |||
@@ -56,7 +56,7 @@ describe('Test services', function () { | |||
56 | const oembedUrl = server.url + basePath + video.uuid + suffix | 56 | const oembedUrl = server.url + basePath + video.uuid + suffix |
57 | 57 | ||
58 | const res = await server.services.getOEmbed({ oembedUrl }) | 58 | const res = await server.services.getOEmbed({ oembedUrl }) |
59 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + | 59 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts allow-popups" ' + |
60 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + | 60 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + |
61 | 'frameborder="0" allowfullscreen></iframe>' | 61 | 'frameborder="0" allowfullscreen></iframe>' |
62 | const expectedThumbnailUrl = 'http://localhost:' + server.port + video.previewPath | 62 | const expectedThumbnailUrl = 'http://localhost:' + server.port + video.previewPath |
@@ -79,7 +79,7 @@ describe('Test services', function () { | |||
79 | const oembedUrl = server.url + basePath + playlistUUID + suffix | 79 | const oembedUrl = server.url + basePath + playlistUUID + suffix |
80 | 80 | ||
81 | const res = await server.services.getOEmbed({ oembedUrl }) | 81 | const res = await server.services.getOEmbed({ oembedUrl }) |
82 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts" ' + | 82 | const expectedHtml = '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts allow-popups" ' + |
83 | `title="${playlistDisplayName}" src="http://localhost:${server.port}/video-playlists/embed/${playlistUUID}" ` + | 83 | `title="${playlistDisplayName}" src="http://localhost:${server.port}/video-playlists/embed/${playlistUUID}" ` + |
84 | 'frameborder="0" allowfullscreen></iframe>' | 84 | 'frameborder="0" allowfullscreen></iframe>' |
85 | 85 | ||
@@ -103,7 +103,7 @@ describe('Test services', function () { | |||
103 | const maxWidth = 50 | 103 | const maxWidth = 50 |
104 | 104 | ||
105 | const res = await server.services.getOEmbed({ oembedUrl, format, maxHeight, maxWidth }) | 105 | const res = await server.services.getOEmbed({ oembedUrl, format, maxHeight, maxWidth }) |
106 | const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts" ' + | 106 | const expectedHtml = '<iframe width="50" height="50" sandbox="allow-same-origin allow-scripts allow-popups" ' + |
107 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + | 107 | `title="${video.name}" src="http://localhost:${server.port}/videos/embed/${video.uuid}" ` + |
108 | 'frameborder="0" allowfullscreen></iframe>' | 108 | 'frameborder="0" allowfullscreen></iframe>' |
109 | 109 | ||