]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Correctly handle RTMP streams without audio
authorChocobozzz <me@florianbigard.com>
Wed, 28 Sep 2022 08:23:03 +0000 (10:23 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 28 Sep 2022 08:26:28 +0000 (10:26 +0200)
server/helpers/ffmpeg/ffmpeg-live.ts
server/lib/live/live-manager.ts
server/lib/live/shared/muxing-session.ts

index 8377dc7e25435f72d72204e813d8afcf8d4092de..379d7b1ad5b532b72162bd6eb4801aa2b4351cfb 100644 (file)
@@ -23,11 +23,24 @@ async function getLiveTranscodingCommand (options: {
   fps: number
   bitrate: number
   ratio: number
+  hasAudio: boolean
 
   availableEncoders: AvailableEncoders
   profile: string
 }) {
-  const { inputUrl, outPath, resolutions, fps, bitrate, availableEncoders, profile, masterPlaylistName, ratio, latencyMode } = options
+  const {
+    inputUrl,
+    outPath,
+    resolutions,
+    fps,
+    bitrate,
+    availableEncoders,
+    profile,
+    masterPlaylistName,
+    ratio,
+    latencyMode,
+    hasAudio
+  } = options
 
   const command = getFFmpeg(inputUrl, 'live')
 
@@ -47,6 +60,7 @@ async function getLiveTranscodingCommand (options: {
   addDefaultEncoderGlobalParams(command)
 
   for (let i = 0; i < resolutions.length; i++) {
+    const streamMap: string[] = []
     const resolution = resolutions[i]
     const resolutionFPS = computeFPS(fps, resolution)
 
@@ -94,9 +108,11 @@ async function getLiveTranscodingCommand (options: {
         options: `w=-2:h=${resolution}`,
         outputs: `vout${resolution}`
       })
+
+      streamMap.push(`v:${i}`)
     }
 
-    {
+    if (hasAudio) {
       const streamType: StreamType = 'audio'
       const builderResult = await getEncoderBuilderResult({ ...baseEncoderBuilderParams, streamType })
       if (!builderResult) {
@@ -114,9 +130,11 @@ async function getLiveTranscodingCommand (options: {
 
       command.outputOption(`${buildStreamSuffix('-c:a', i)} ${builderResult.encoder}`)
       applyEncoderOptions(command, builderResult.result)
+
+      streamMap.push(`a:${i}`)
     }
 
-    varStreamMap.push(`v:${i},a:${i}`)
+    varStreamMap.push(streamMap.join(','))
   }
 
   command.complexFilter(complexFilter)
index aadd8e30829e61b63aede0a8a00891e77f0013f3..16715862bc78188c80575a82c21c22148fd4c1d2 100644 (file)
@@ -1,4 +1,3 @@
-
 import { readdir, readFile } from 'fs-extra'
 import { createServer, Server } from 'net'
 import { join } from 'path'
@@ -9,7 +8,8 @@ import {
   getLiveSegmentTime,
   getVideoStreamBitrate,
   getVideoStreamDimensionsInfo,
-  getVideoStreamFPS
+  getVideoStreamFPS,
+  hasAudioStream
 } from '@server/helpers/ffmpeg'
 import { logger, loggerTagsFactory } from '@server/helpers/logger'
 import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config'
@@ -20,7 +20,7 @@ import { VideoLiveModel } from '@server/models/video/video-live'
 import { VideoLiveSessionModel } from '@server/models/video/video-live-session'
 import { VideoStreamingPlaylistModel } from '@server/models/video/video-streaming-playlist'
 import { MStreamingPlaylistVideo, MVideo, MVideoLiveSession, MVideoLiveVideo } from '@server/types/models'
-import { wait } from '@shared/core-utils'
+import { pick, wait } from '@shared/core-utils'
 import { LiveVideoError, VideoState, VideoStreamingPlaylistType } from '@shared/models'
 import { federateVideoIfNeeded } from '../activitypub/videos'
 import { JobQueue } from '../job-queue'
@@ -232,10 +232,11 @@ class LiveManager {
     const now = Date.now()
     const probe = await ffprobePromise(inputUrl)
 
-    const [ { resolution, ratio }, fps, bitrate ] = await Promise.all([
+    const [ { resolution, ratio }, fps, bitrate, hasAudio ] = await Promise.all([
       getVideoStreamDimensionsInfo(inputUrl, probe),
       getVideoStreamFPS(inputUrl, probe),
-      getVideoStreamBitrate(inputUrl, probe)
+      getVideoStreamBitrate(inputUrl, probe),
+      hasAudioStream(inputUrl, probe)
     ])
 
     logger.info(
@@ -259,26 +260,30 @@ class LiveManager {
     return this.runMuxingSession({
       sessionId,
       videoLive,
+
       streamingPlaylist,
       inputUrl,
       fps,
       bitrate,
       ratio,
-      allResolutions
+      allResolutions,
+      hasAudio
     })
   }
 
   private async runMuxingSession (options: {
     sessionId: string
     videoLive: MVideoLiveVideo
+
     streamingPlaylist: MStreamingPlaylistVideo
     inputUrl: string
     fps: number
     bitrate: number
     ratio: number
     allResolutions: number[]
+    hasAudio: boolean
   }) {
-    const { sessionId, videoLive, streamingPlaylist, allResolutions, fps, bitrate, ratio, inputUrl } = options
+    const { sessionId, videoLive } = options
     const videoUUID = videoLive.Video.uuid
     const localLTags = lTags(sessionId, videoUUID)
 
@@ -289,15 +294,11 @@ class LiveManager {
 
     const muxingSession = new MuxingSession({
       context: this.getContext(),
-      user,
       sessionId,
       videoLive,
-      streamingPlaylist,
-      inputUrl,
-      bitrate,
-      ratio,
-      fps,
-      allResolutions
+      user,
+
+      ...pick(options, [ 'streamingPlaylist', 'inputUrl', 'bitrate', 'ratio', 'fps', 'allResolutions', 'hasAudio' ])
     })
 
     muxingSession.on('master-playlist-created', () => this.publishAndFederateLive(videoLive, localLTags))
index 310a7026dcd215671546cf71c163f6794f58aafe..505717dce0bf03fb9664e277d0932156005d178b 100644 (file)
@@ -59,6 +59,8 @@ class MuxingSession extends EventEmitter {
   private readonly bitrate: number
   private readonly ratio: number
 
+  private readonly hasAudio: boolean
+
   private readonly videoId: number
   private readonly videoUUID: string
   private readonly saveReplay: boolean
@@ -94,6 +96,7 @@ class MuxingSession extends EventEmitter {
     bitrate: number
     ratio: number
     allResolutions: number[]
+    hasAudio: boolean
   }) {
     super()
 
@@ -108,6 +111,8 @@ class MuxingSession extends EventEmitter {
     this.bitrate = options.bitrate
     this.ratio = options.ratio
 
+    this.hasAudio = options.hasAudio
+
     this.allResolutions = options.allResolutions
 
     this.videoId = this.videoLive.Video.id
@@ -140,6 +145,8 @@ class MuxingSession extends EventEmitter {
         bitrate: this.bitrate,
         ratio: this.ratio,
 
+        hasAudio: this.hasAudio,
+
         availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
         profile: CONFIG.LIVE.TRANSCODING.PROFILE
       })