Add minimum bitrate limit
This commit is contained in:
		
							parent
							
								
									9390403250
								
							
						
					
					
						commit
						67eeec8b95
					
				
					 3 changed files with 55 additions and 10 deletions
				
			
		| 
						 | 
				
			
			@ -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') {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ---------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue