Correctly handle RTMP streams without audio
This commit is contained in:
parent
690bad52e1
commit
1ce4256a65
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue