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')
addDefaultEncoderGlobalParams(command)
for (let i = 0; i < resolutions.length; i++) {
+ const streamMap: string[] = []
const resolution = resolutions[i]
const resolutionFPS = computeFPS(fps, resolution)
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) {
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)
-
import { readdir, readFile } from 'fs-extra'
import { createServer, Server } from 'net'
import { join } from 'path'
getLiveSegmentTime,
getVideoStreamBitrate,
getVideoStreamDimensionsInfo,
- getVideoStreamFPS
+ getVideoStreamFPS,
+ hasAudioStream
} from '@server/helpers/ffmpeg'
import { logger, loggerTagsFactory } from '@server/helpers/logger'
import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config'
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'
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(
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)
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))
private readonly bitrate: number
private readonly ratio: number
+ private readonly hasAudio: boolean
+
private readonly videoId: number
private readonly videoUUID: string
private readonly saveReplay: boolean
bitrate: number
ratio: number
allResolutions: number[]
+ hasAudio: boolean
}) {
super()
this.bitrate = options.bitrate
this.ratio = options.ratio
+ this.hasAudio = options.hasAudio
+
this.allResolutions = options.allResolutions
this.videoId = this.videoLive.Video.id
bitrate: this.bitrate,
ratio: this.ratio,
+ hasAudio: this.hasAudio,
+
availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
profile: CONFIG.LIVE.TRANSCODING.PROFILE
})