aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-11-10 11:04:00 +0100
committerChocobozzz <me@florianbigard.com>2021-11-10 11:04:00 +0100
commit67eeec8b955339120ff5d3c8286fdf0715e6270c (patch)
treeec28e8c218ed4e80f5f1f86f59fe2acb360950a9
parent93904032506dd222404d9be60fd2e41763554665 (diff)
downloadPeerTube-67eeec8b955339120ff5d3c8286fdf0715e6270c.tar.gz
PeerTube-67eeec8b955339120ff5d3c8286fdf0715e6270c.tar.zst
PeerTube-67eeec8b955339120ff5d3c8286fdf0715e6270c.zip
Add minimum bitrate limit
-rw-r--r--server/helpers/ffmpeg-utils.ts12
-rw-r--r--server/lib/transcoding/video-transcoding-profiles.ts27
-rw-r--r--shared/core-utils/videos/bitrate.ts26
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: {
286 286
287 addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i }) 287 addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i })
288 288
289 logger.debug('Apply ffmpeg live video params from %s using %s profile.', builderResult.encoder, profile, builderResult, lTags()) 289 logger.debug(
290 'Apply ffmpeg live video params from %s using %s profile.', builderResult.encoder, profile, builderResult,
291 { fps: resolutionFPS, resolution, ...lTags() }
292 )
290 293
291 command.outputOption(`${buildStreamSuffix('-c:v', i)} ${builderResult.encoder}`) 294 command.outputOption(`${buildStreamSuffix('-c:v', i)} ${builderResult.encoder}`)
292 applyEncoderOptions(command, builderResult.result) 295 applyEncoderOptions(command, builderResult.result)
@@ -310,7 +313,10 @@ async function getLiveTranscodingCommand (options: {
310 313
311 addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i }) 314 addDefaultEncoderParams({ command, encoder: builderResult.encoder, fps: resolutionFPS, streamNum: i })
312 315
313 logger.debug('Apply ffmpeg live audio params from %s using %s profile.', builderResult.encoder, profile, builderResult, lTags()) 316 logger.debug(
317 'Apply ffmpeg live audio params from %s using %s profile.', builderResult.encoder, profile, builderResult,
318 { fps: resolutionFPS, resolution, ...lTags() }
319 )
314 320
315 command.outputOption(`${buildStreamSuffix('-c:a', i)} ${builderResult.encoder}`) 321 command.outputOption(`${buildStreamSuffix('-c:a', i)} ${builderResult.encoder}`)
316 applyEncoderOptions(command, builderResult.result) 322 applyEncoderOptions(command, builderResult.result)
@@ -622,7 +628,7 @@ async function presetVideo (options: {
622 logger.debug( 628 logger.debug(
623 'Apply ffmpeg params from %s for %s stream of input %s using %s profile.', 629 'Apply ffmpeg params from %s for %s stream of input %s using %s profile.',
624 builderResult.encoder, streamType, input, profile, builderResult, 630 builderResult.encoder, streamType, input, profile, builderResult,
625 lTags() 631 { resolution, fps, ...lTags() }
626 ) 632 )
627 633
628 if (streamType === 'video') { 634 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 @@
1
1import { logger } from '@server/helpers/logger' 2import { logger } from '@server/helpers/logger'
2import { getAverageBitrate } from '@shared/core-utils' 3import { getAverageBitrate, getMinLimitBitrate } from '@shared/core-utils'
3import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams } from '../../../shared/models/videos' 4import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '../../../shared/models/videos'
4import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-utils' 5import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-utils'
5import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '../../helpers/ffprobe-utils' 6import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '../../helpers/ffprobe-utils'
6 7
@@ -15,10 +16,10 @@ import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBi
15 */ 16 */
16 17
17const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => { 18const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
18 const { fps, inputRatio, inputBitrate } = options 19 const { fps, inputRatio, inputBitrate, resolution } = options
19 if (!fps) return { outputOptions: [ ] } 20 if (!fps) return { outputOptions: [ ] }
20 21
21 const targetBitrate = capBitrate(inputBitrate, getAverageBitrate({ ...options, fps, ratio: inputRatio })) 22 const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
22 23
23 return { 24 return {
24 outputOptions: [ 25 outputOptions: [
@@ -31,9 +32,9 @@ const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOpt
31} 32}
32 33
33const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => { 34const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
34 const { streamNum, fps, inputBitrate, inputRatio } = options 35 const { streamNum, fps, inputBitrate, inputRatio, resolution } = options
35 36
36 const targetBitrate = capBitrate(inputBitrate, getAverageBitrate({ ...options, fps, ratio: inputRatio })) 37 const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
37 38
38 return { 39 return {
39 outputOptions: [ 40 outputOptions: [
@@ -234,6 +235,20 @@ export {
234 235
235// --------------------------------------------------------------------------- 236// ---------------------------------------------------------------------------
236 237
238function getTargetBitrate (options: {
239 inputBitrate: number
240 resolution: VideoResolution
241 ratio: number
242 fps: number
243}) {
244 const { inputBitrate, resolution, ratio, fps } = options
245
246 const capped = capBitrate(inputBitrate, getAverageBitrate({ resolution, fps, ratio }))
247 const limit = getMinLimitBitrate({ resolution, fps, ratio })
248
249 return Math.max(limit, capped)
250}
251
237function capBitrate (inputBitrate: number, targetBitrate: number) { 252function capBitrate (inputBitrate: number, targetBitrate: number) {
238 if (!inputBitrate) return targetBitrate 253 if (!inputBitrate) return targetBitrate
239 254
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 }
4 4
5// https://bitmovin.com/video-bitrate-streaming-hls-dash/ 5// https://bitmovin.com/video-bitrate-streaming-hls-dash/
6 6
7const minLimitBitPerPixel: BitPerPixel = {
8 [VideoResolution.H_NOVIDEO]: 0,
9 [VideoResolution.H_144P]: 0.02,
10 [VideoResolution.H_240P]: 0.02,
11 [VideoResolution.H_360P]: 0.02,
12 [VideoResolution.H_480P]: 0.02,
13 [VideoResolution.H_720P]: 0.02,
14 [VideoResolution.H_1080P]: 0.02,
15 [VideoResolution.H_1440P]: 0.02,
16 [VideoResolution.H_4K]: 0.02
17}
18
7const averageBitPerPixel: BitPerPixel = { 19const averageBitPerPixel: BitPerPixel = {
8 [VideoResolution.H_NOVIDEO]: 0, 20 [VideoResolution.H_NOVIDEO]: 0,
9 [VideoResolution.H_144P]: 0.19, 21 [VideoResolution.H_144P]: 0.19,
@@ -50,11 +62,23 @@ function getMaxBitrate (options: {
50 return targetBitrate 62 return targetBitrate
51} 63}
52 64
65function getMinLimitBitrate (options: {
66 resolution: VideoResolution
67 ratio: number
68 fps: number
69}) {
70 const minLimitBitrate = calculateBitrate({ ...options, bitPerPixel: minLimitBitPerPixel })
71 if (!minLimitBitrate) return 10 * 1000
72
73 return minLimitBitrate
74}
75
53// --------------------------------------------------------------------------- 76// ---------------------------------------------------------------------------
54 77
55export { 78export {
56 getAverageBitrate, 79 getAverageBitrate,
57 getMaxBitrate 80 getMaxBitrate,
81 getMinLimitBitrate
58} 82}
59 83
60// --------------------------------------------------------------------------- 84// ---------------------------------------------------------------------------