Add minimum bitrate limit

pull/4548/head
Chocobozzz 2021-11-10 11:04:00 +01:00
parent 9390403250
commit 67eeec8b95
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
3 changed files with 55 additions and 10 deletions

View File

@ -286,7 +286,10 @@ async function getLiveTranscodingCommand (options: {
addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i }) addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i })
logger.debug('Apply ffmpeg live video params from %s using %s profile.', builderResult.encoder, profile, builderResult, lTags()) logger.debug(
'Apply ffmpeg live video params from %s using %s profile.', builderResult.encoder, profile, builderResult,
{ fps: resolutionFPS, resolution, ...lTags() }
)
command.outputOption(`${buildStreamSuffix('-c:v', i)} ${builderResult.encoder}`) command.outputOption(`${buildStreamSuffix('-c:v', i)} ${builderResult.encoder}`)
applyEncoderOptions(command, builderResult.result) applyEncoderOptions(command, builderResult.result)
@ -310,7 +313,10 @@ async function getLiveTranscodingCommand (options: {
addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i }) addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i })
logger.debug('Apply ffmpeg live audio params from %s using %s profile.', builderResult.encoder, profile, builderResult, lTags()) logger.debug(
'Apply ffmpeg live audio params from %s using %s profile.', builderResult.encoder, profile, builderResult,
{ fps: resolutionFPS, resolution, ...lTags() }
)
command.outputOption(`${buildStreamSuffix('-c:a', i)} ${builderResult.encoder}`) command.outputOption(`${buildStreamSuffix('-c:a', i)} ${builderResult.encoder}`)
applyEncoderOptions(command, builderResult.result) applyEncoderOptions(command, builderResult.result)
@ -622,7 +628,7 @@ async function presetVideo (options: {
logger.debug( logger.debug(
'Apply ffmpeg params from %s for %s stream of input %s using %s profile.', 'Apply ffmpeg params from %s for %s stream of input %s using %s profile.',
builderResult.encoder, streamType, input, profile, builderResult, builderResult.encoder, streamType, input, profile, builderResult,
lTags() { resolution, fps, ...lTags() }
) )
if (streamType === 'video') { if (streamType === 'video') {

View File

@ -1,6 +1,7 @@
import { logger } from '@server/helpers/logger' import { logger } from '@server/helpers/logger'
import { getAverageBitrate } from '@shared/core-utils' import { getAverageBitrate, getMinLimitBitrate } from '@shared/core-utils'
import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams } from '../../../shared/models/videos' import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '../../../shared/models/videos'
import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-utils' import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-utils'
import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '../../helpers/ffprobe-utils' import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '../../helpers/ffprobe-utils'
@ -15,10 +16,10 @@ import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBi
*/ */
const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => { const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
const { fps, inputRatio, inputBitrate } = options const { fps, inputRatio, inputBitrate, resolution } = options
if (!fps) return { outputOptions: [ ] } if (!fps) return { outputOptions: [ ] }
const targetBitrate = capBitrate(inputBitrate, getAverageBitrate({ ...options, fps, ratio: inputRatio })) const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
return { return {
outputOptions: [ outputOptions: [
@ -31,9 +32,9 @@ const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOpt
} }
const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => { const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
const { streamNum, fps, inputBitrate, inputRatio } = options const { streamNum, fps, inputBitrate, inputRatio, resolution } = options
const targetBitrate = capBitrate(inputBitrate, getAverageBitrate({ ...options, fps, ratio: inputRatio })) const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
return { return {
outputOptions: [ outputOptions: [
@ -234,6 +235,20 @@ export {
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function getTargetBitrate (options: {
inputBitrate: number
resolution: VideoResolution
ratio: number
fps: number
}) {
const { inputBitrate, resolution, ratio, fps } = options
const capped = capBitrate(inputBitrate, getAverageBitrate({ resolution, fps, ratio }))
const limit = getMinLimitBitrate({ resolution, fps, ratio })
return Math.max(limit, capped)
}
function capBitrate (inputBitrate: number, targetBitrate: number) { function capBitrate (inputBitrate: number, targetBitrate: number) {
if (!inputBitrate) return targetBitrate if (!inputBitrate) return targetBitrate

View File

@ -4,6 +4,18 @@ type BitPerPixel = { [ id in VideoResolution ]: number }
// https://bitmovin.com/video-bitrate-streaming-hls-dash/ // https://bitmovin.com/video-bitrate-streaming-hls-dash/
const minLimitBitPerPixel: BitPerPixel = {
[VideoResolution.H_NOVIDEO]: 0,
[VideoResolution.H_144P]: 0.02,
[VideoResolution.H_240P]: 0.02,
[VideoResolution.H_360P]: 0.02,
[VideoResolution.H_480P]: 0.02,
[VideoResolution.H_720P]: 0.02,
[VideoResolution.H_1080P]: 0.02,
[VideoResolution.H_1440P]: 0.02,
[VideoResolution.H_4K]: 0.02
}
const averageBitPerPixel: BitPerPixel = { const averageBitPerPixel: BitPerPixel = {
[VideoResolution.H_NOVIDEO]: 0, [VideoResolution.H_NOVIDEO]: 0,
[VideoResolution.H_144P]: 0.19, [VideoResolution.H_144P]: 0.19,
@ -50,11 +62,23 @@ function getMaxBitrate (options: {
return targetBitrate return targetBitrate
} }
function getMinLimitBitrate (options: {
resolution: VideoResolution
ratio: number
fps: number
}) {
const minLimitBitrate = calculateBitrate({ ...options, bitPerPixel: minLimitBitPerPixel })
if (!minLimitBitrate) return 10 * 1000
return minLimitBitrate
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
export { export {
getAverageBitrate, getAverageBitrate,
getMaxBitrate getMaxBitrate,
getMinLimitBitrate
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------