diff options
author | Chocobozzz <me@florianbigard.com> | 2021-08-06 10:39:40 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-08-06 10:39:40 +0200 |
commit | c826f34a45757b324a20f71665b44ed10e6953b5 (patch) | |
tree | ff29bdff8b4519bbdbbcd3aa0d68521ce2b06ff5 /server/helpers | |
parent | 421ff4618da64f0849353383f690a014024c40da (diff) | |
download | PeerTube-c826f34a45757b324a20f71665b44ed10e6953b5.tar.gz PeerTube-c826f34a45757b324a20f71665b44ed10e6953b5.tar.zst PeerTube-c826f34a45757b324a20f71665b44ed10e6953b5.zip |
Limit live bitrate
Diffstat (limited to 'server/helpers')
-rw-r--r-- | server/helpers/ffmpeg-utils.ts | 21 | ||||
-rw-r--r-- | server/helpers/ffprobe-utils.ts | 13 |
2 files changed, 25 insertions, 9 deletions
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index 61c8a6db2..7f84a049f 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts | |||
@@ -6,7 +6,7 @@ import { FFMPEG_NICE, VIDEO_LIVE } from '@server/initializers/constants' | |||
6 | import { AvailableEncoders, EncoderOptions, EncoderOptionsBuilder, EncoderProfile, VideoResolution } from '../../shared/models/videos' | 6 | import { AvailableEncoders, EncoderOptions, EncoderOptionsBuilder, EncoderProfile, VideoResolution } from '../../shared/models/videos' |
7 | import { CONFIG } from '../initializers/config' | 7 | import { CONFIG } from '../initializers/config' |
8 | import { execPromise, promisify0 } from './core-utils' | 8 | import { execPromise, promisify0 } from './core-utils' |
9 | import { computeFPS, getAudioStream, getVideoFileFPS } from './ffprobe-utils' | 9 | import { computeFPS, ffprobePromise, getAudioStream, getVideoFileBitrate, getVideoFileFPS } from './ffprobe-utils' |
10 | import { processImage } from './image-utils' | 10 | import { processImage } from './image-utils' |
11 | import { logger } from './logger' | 11 | import { logger } from './logger' |
12 | 12 | ||
@@ -218,11 +218,12 @@ async function getLiveTranscodingCommand (options: { | |||
218 | 218 | ||
219 | resolutions: number[] | 219 | resolutions: number[] |
220 | fps: number | 220 | fps: number |
221 | bitrate: number | ||
221 | 222 | ||
222 | availableEncoders: AvailableEncoders | 223 | availableEncoders: AvailableEncoders |
223 | profile: string | 224 | profile: string |
224 | }) { | 225 | }) { |
225 | const { rtmpUrl, outPath, resolutions, fps, availableEncoders, profile, masterPlaylistName } = options | 226 | const { rtmpUrl, outPath, resolutions, fps, bitrate, availableEncoders, profile, masterPlaylistName } = options |
226 | const input = rtmpUrl | 227 | const input = rtmpUrl |
227 | 228 | ||
228 | const command = getFFmpeg(input, 'live') | 229 | const command = getFFmpeg(input, 'live') |
@@ -253,6 +254,7 @@ async function getLiveTranscodingCommand (options: { | |||
253 | profile, | 254 | profile, |
254 | 255 | ||
255 | fps: resolutionFPS, | 256 | fps: resolutionFPS, |
257 | inputBitrate: bitrate, | ||
256 | resolution, | 258 | resolution, |
257 | streamNum: i, | 259 | streamNum: i, |
258 | videoType: 'live' as 'live' | 260 | videoType: 'live' as 'live' |
@@ -260,7 +262,7 @@ async function getLiveTranscodingCommand (options: { | |||
260 | 262 | ||
261 | { | 263 | { |
262 | const streamType: StreamType = 'video' | 264 | const streamType: StreamType = 'video' |
263 | const builderResult = await getEncoderBuilderResult(Object.assign({}, baseEncoderBuilderParams, { streamType })) | 265 | const builderResult = await getEncoderBuilderResult({ ...baseEncoderBuilderParams, streamType }) |
264 | if (!builderResult) { | 266 | if (!builderResult) { |
265 | throw new Error('No available live video encoder found') | 267 | throw new Error('No available live video encoder found') |
266 | } | 268 | } |
@@ -284,7 +286,7 @@ async function getLiveTranscodingCommand (options: { | |||
284 | 286 | ||
285 | { | 287 | { |
286 | const streamType: StreamType = 'audio' | 288 | const streamType: StreamType = 'audio' |
287 | const builderResult = await getEncoderBuilderResult(Object.assign({}, baseEncoderBuilderParams, { streamType })) | 289 | const builderResult = await getEncoderBuilderResult({ ...baseEncoderBuilderParams, streamType }) |
288 | if (!builderResult) { | 290 | if (!builderResult) { |
289 | throw new Error('No available live audio encoder found') | 291 | throw new Error('No available live audio encoder found') |
290 | } | 292 | } |
@@ -510,10 +512,11 @@ async function getEncoderBuilderResult (options: { | |||
510 | videoType: 'vod' | 'live' | 512 | videoType: 'vod' | 'live' |
511 | 513 | ||
512 | resolution: number | 514 | resolution: number |
515 | inputBitrate: number | ||
513 | fps?: number | 516 | fps?: number |
514 | streamNum?: number | 517 | streamNum?: number |
515 | }) { | 518 | }) { |
516 | const { availableEncoders, input, profile, resolution, streamType, fps, streamNum, videoType } = options | 519 | const { availableEncoders, input, profile, resolution, streamType, fps, inputBitrate, streamNum, videoType } = options |
517 | 520 | ||
518 | const encodersToTry = availableEncoders.encodersToTry[videoType][streamType] | 521 | const encodersToTry = availableEncoders.encodersToTry[videoType][streamType] |
519 | const encoders = availableEncoders.available[videoType] | 522 | const encoders = availableEncoders.available[videoType] |
@@ -543,7 +546,7 @@ async function getEncoderBuilderResult (options: { | |||
543 | } | 546 | } |
544 | } | 547 | } |
545 | 548 | ||
546 | const result = await builder({ input, resolution, fps, streamNum }) | 549 | const result = await builder({ input, resolution, inputBitrate, fps, streamNum }) |
547 | 550 | ||
548 | return { | 551 | return { |
549 | result, | 552 | result, |
@@ -573,8 +576,11 @@ async function presetVideo (options: { | |||
573 | 576 | ||
574 | addDefaultEncoderGlobalParams({ command }) | 577 | addDefaultEncoderGlobalParams({ command }) |
575 | 578 | ||
579 | const probe = await ffprobePromise(input) | ||
580 | |||
576 | // Audio encoder | 581 | // Audio encoder |
577 | const parsedAudio = await getAudioStream(input) | 582 | const parsedAudio = await getAudioStream(input, probe) |
583 | const bitrate = await getVideoFileBitrate(input, probe) | ||
578 | 584 | ||
579 | let streamsToProcess: StreamType[] = [ 'audio', 'video' ] | 585 | let streamsToProcess: StreamType[] = [ 'audio', 'video' ] |
580 | 586 | ||
@@ -593,6 +599,7 @@ async function presetVideo (options: { | |||
593 | availableEncoders, | 599 | availableEncoders, |
594 | profile, | 600 | profile, |
595 | fps, | 601 | fps, |
602 | inputBitrate: bitrate, | ||
596 | videoType: 'vod' as 'vod' | 603 | videoType: 'vod' as 'vod' |
597 | }) | 604 | }) |
598 | 605 | ||
diff --git a/server/helpers/ffprobe-utils.ts b/server/helpers/ffprobe-utils.ts index ef2aa3f89..bc87e49b1 100644 --- a/server/helpers/ffprobe-utils.ts +++ b/server/helpers/ffprobe-utils.ts | |||
@@ -175,10 +175,19 @@ async function getMetadataFromFile (path: string, existingProbe?: ffmpeg.Ffprobe | |||
175 | return new VideoFileMetadata(metadata) | 175 | return new VideoFileMetadata(metadata) |
176 | } | 176 | } |
177 | 177 | ||
178 | async function getVideoFileBitrate (path: string, existingProbe?: ffmpeg.FfprobeData) { | 178 | async function getVideoFileBitrate (path: string, existingProbe?: ffmpeg.FfprobeData): Promise<number> { |
179 | const metadata = await getMetadataFromFile(path, existingProbe) | 179 | const metadata = await getMetadataFromFile(path, existingProbe) |
180 | 180 | ||
181 | return metadata.format.bit_rate as number | 181 | let bitrate = metadata.format.bit_rate as number |
182 | if (bitrate && !isNaN(bitrate)) return bitrate | ||
183 | |||
184 | const videoStream = await getVideoStreamFromFile(path, existingProbe) | ||
185 | if (!videoStream) return undefined | ||
186 | |||
187 | bitrate = videoStream?.bit_rate | ||
188 | if (bitrate && !isNaN(bitrate)) return bitrate | ||
189 | |||
190 | return undefined | ||
182 | } | 191 | } |
183 | 192 | ||
184 | async function getDurationFromVideoFile (path: string, existingProbe?: ffmpeg.FfprobeData) { | 193 | async function getDurationFromVideoFile (path: string, existingProbe?: ffmpeg.FfprobeData) { |