From 67eeec8b955339120ff5d3c8286fdf0715e6270c Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 10 Nov 2021 11:04:00 +0100 Subject: [PATCH] Add minimum bitrate limit --- server/helpers/ffmpeg-utils.ts | 12 ++++++--- .../transcoding/video-transcoding-profiles.ts | 27 ++++++++++++++----- shared/core-utils/videos/bitrate.ts | 26 +++++++++++++++++- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index cc79828f6..ab29d4691 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts @@ -286,7 +286,10 @@ async function getLiveTranscodingCommand (options: { 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}`) applyEncoderOptions(command, builderResult.result) @@ -310,7 +313,10 @@ async function getLiveTranscodingCommand (options: { 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}`) applyEncoderOptions(command, builderResult.result) @@ -622,7 +628,7 @@ async function presetVideo (options: { logger.debug( 'Apply ffmpeg params from %s for %s stream of input %s using %s profile.', builderResult.encoder, streamType, input, profile, builderResult, - lTags() + { resolution, fps, ...lTags() } ) if (streamType === 'video') { diff --git a/server/lib/transcoding/video-transcoding-profiles.ts b/server/lib/transcoding/video-transcoding-profiles.ts index 92971210c..34a364415 100644 --- a/server/lib/transcoding/video-transcoding-profiles.ts +++ b/server/lib/transcoding/video-transcoding-profiles.ts @@ -1,6 +1,7 @@ + import { logger } from '@server/helpers/logger' -import { getAverageBitrate } from '@shared/core-utils' -import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams } from '../../../shared/models/videos' +import { getAverageBitrate, getMinLimitBitrate } from '@shared/core-utils' +import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '../../../shared/models/videos' import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-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 { fps, inputRatio, inputBitrate } = options + const { fps, inputRatio, inputBitrate, resolution } = options if (!fps) return { outputOptions: [ ] } - const targetBitrate = capBitrate(inputBitrate, getAverageBitrate({ ...options, fps, ratio: inputRatio })) + const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution }) return { outputOptions: [ @@ -31,9 +32,9 @@ const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOpt } 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 { 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) { if (!inputBitrate) return targetBitrate diff --git a/shared/core-utils/videos/bitrate.ts b/shared/core-utils/videos/bitrate.ts index 18c6e2f6c..c1891188f 100644 --- a/shared/core-utils/videos/bitrate.ts +++ b/shared/core-utils/videos/bitrate.ts @@ -4,6 +4,18 @@ type BitPerPixel = { [ id in VideoResolution ]: number } // 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 = { [VideoResolution.H_NOVIDEO]: 0, [VideoResolution.H_144P]: 0.19, @@ -50,11 +62,23 @@ function getMaxBitrate (options: { 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 { getAverageBitrate, - getMaxBitrate + getMaxBitrate, + getMinLimitBitrate } // --------------------------------------------------------------------------- -- 2.41.0