aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2021-08-06 10:39:40 +0200
committerChocobozzz <me@florianbigard.com>2021-08-06 10:39:40 +0200
commitc826f34a45757b324a20f71665b44ed10e6953b5 (patch)
treeff29bdff8b4519bbdbbcd3aa0d68521ce2b06ff5 /server/lib
parent421ff4618da64f0849353383f690a014024c40da (diff)
downloadPeerTube-c826f34a45757b324a20f71665b44ed10e6953b5.tar.gz
PeerTube-c826f34a45757b324a20f71665b44ed10e6953b5.tar.zst
PeerTube-c826f34a45757b324a20f71665b44ed10e6953b5.zip
Limit live bitrate
Diffstat (limited to 'server/lib')
-rw-r--r--server/lib/live/live-manager.ts28
-rw-r--r--server/lib/live/shared/muxing-session.ts5
-rw-r--r--server/lib/transcoding/video-transcoding-profiles.ts33
3 files changed, 39 insertions, 27 deletions
diff --git a/server/lib/live/live-manager.ts b/server/lib/live/live-manager.ts
index f106d69fb..b19ecef6f 100644
--- a/server/lib/live/live-manager.ts
+++ b/server/lib/live/live-manager.ts
@@ -1,7 +1,13 @@
1 1
2import { createServer, Server } from 'net' 2import { createServer, Server } from 'net'
3import { isTestInstance } from '@server/helpers/core-utils' 3import { isTestInstance } from '@server/helpers/core-utils'
4import { computeResolutionsToTranscode, getVideoFileFPS, getVideoFileResolution } from '@server/helpers/ffprobe-utils' 4import {
5 computeResolutionsToTranscode,
6 ffprobePromise,
7 getVideoFileBitrate,
8 getVideoFileFPS,
9 getVideoFileResolution
10} from '@server/helpers/ffprobe-utils'
5import { logger, loggerTagsFactory } from '@server/helpers/logger' 11import { logger, loggerTagsFactory } from '@server/helpers/logger'
6import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config' 12import { CONFIG, registerConfigChangedHandler } from '@server/initializers/config'
7import { P2P_MEDIA_LOADER_PEER_VERSION, VIDEO_LIVE, VIEW_LIFETIME } from '@server/initializers/constants' 13import { P2P_MEDIA_LOADER_PEER_VERSION, VIDEO_LIVE, VIEW_LIFETIME } from '@server/initializers/constants'
@@ -193,11 +199,20 @@ class LiveManager {
193 199
194 const rtmpUrl = 'rtmp://127.0.0.1:' + config.rtmp.port + streamPath 200 const rtmpUrl = 'rtmp://127.0.0.1:' + config.rtmp.port + streamPath
195 201
196 const [ { videoFileResolution }, fps ] = await Promise.all([ 202 const now = Date.now()
197 getVideoFileResolution(rtmpUrl), 203 const probe = await ffprobePromise(rtmpUrl)
198 getVideoFileFPS(rtmpUrl) 204
205 const [ { videoFileResolution }, fps, bitrate ] = await Promise.all([
206 getVideoFileResolution(rtmpUrl, probe),
207 getVideoFileFPS(rtmpUrl, probe),
208 getVideoFileBitrate(rtmpUrl, probe)
199 ]) 209 ])
200 210
211 logger.info(
212 '%s probing took %d ms (bitrate: %d, fps: %d, resolution: %d)',
213 rtmpUrl, Date.now() - now, bitrate, fps, videoFileResolution, lTags(sessionId, video.uuid)
214 )
215
201 const allResolutions = this.buildAllResolutionsToTranscode(videoFileResolution) 216 const allResolutions = this.buildAllResolutionsToTranscode(videoFileResolution)
202 217
203 logger.info( 218 logger.info(
@@ -213,6 +228,7 @@ class LiveManager {
213 streamingPlaylist, 228 streamingPlaylist,
214 rtmpUrl, 229 rtmpUrl,
215 fps, 230 fps,
231 bitrate,
216 allResolutions 232 allResolutions
217 }) 233 })
218 } 234 }
@@ -223,9 +239,10 @@ class LiveManager {
223 streamingPlaylist: MStreamingPlaylistVideo 239 streamingPlaylist: MStreamingPlaylistVideo
224 rtmpUrl: string 240 rtmpUrl: string
225 fps: number 241 fps: number
242 bitrate: number
226 allResolutions: number[] 243 allResolutions: number[]
227 }) { 244 }) {
228 const { sessionId, videoLive, streamingPlaylist, allResolutions, fps, rtmpUrl } = options 245 const { sessionId, videoLive, streamingPlaylist, allResolutions, fps, bitrate, rtmpUrl } = options
229 const videoUUID = videoLive.Video.uuid 246 const videoUUID = videoLive.Video.uuid
230 const localLTags = lTags(sessionId, videoUUID) 247 const localLTags = lTags(sessionId, videoUUID)
231 248
@@ -239,6 +256,7 @@ class LiveManager {
239 videoLive, 256 videoLive,
240 streamingPlaylist, 257 streamingPlaylist,
241 rtmpUrl, 258 rtmpUrl,
259 bitrate,
242 fps, 260 fps,
243 allResolutions 261 allResolutions
244 }) 262 })
diff --git a/server/lib/live/shared/muxing-session.ts b/server/lib/live/shared/muxing-session.ts
index 709d6c615..62708b14b 100644
--- a/server/lib/live/shared/muxing-session.ts
+++ b/server/lib/live/shared/muxing-session.ts
@@ -54,6 +54,7 @@ class MuxingSession extends EventEmitter {
54 private readonly streamingPlaylist: MStreamingPlaylistVideo 54 private readonly streamingPlaylist: MStreamingPlaylistVideo
55 private readonly rtmpUrl: string 55 private readonly rtmpUrl: string
56 private readonly fps: number 56 private readonly fps: number
57 private readonly bitrate: number
57 private readonly allResolutions: number[] 58 private readonly allResolutions: number[]
58 59
59 private readonly videoId: number 60 private readonly videoId: number
@@ -83,6 +84,7 @@ class MuxingSession extends EventEmitter {
83 streamingPlaylist: MStreamingPlaylistVideo 84 streamingPlaylist: MStreamingPlaylistVideo
84 rtmpUrl: string 85 rtmpUrl: string
85 fps: number 86 fps: number
87 bitrate: number
86 allResolutions: number[] 88 allResolutions: number[]
87 }) { 89 }) {
88 super() 90 super()
@@ -94,6 +96,7 @@ class MuxingSession extends EventEmitter {
94 this.streamingPlaylist = options.streamingPlaylist 96 this.streamingPlaylist = options.streamingPlaylist
95 this.rtmpUrl = options.rtmpUrl 97 this.rtmpUrl = options.rtmpUrl
96 this.fps = options.fps 98 this.fps = options.fps
99 this.bitrate = options.bitrate
97 this.allResolutions = options.allResolutions 100 this.allResolutions = options.allResolutions
98 101
99 this.videoId = this.videoLive.Video.id 102 this.videoId = this.videoLive.Video.id
@@ -118,6 +121,8 @@ class MuxingSession extends EventEmitter {
118 121
119 resolutions: this.allResolutions, 122 resolutions: this.allResolutions,
120 fps: this.fps, 123 fps: this.fps,
124 bitrate: this.bitrate,
125
121 availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(), 126 availableEncoders: VideoTranscodingProfilesManager.Instance.getAvailableEncoders(),
122 profile: CONFIG.LIVE.TRANSCODING.PROFILE 127 profile: CONFIG.LIVE.TRANSCODING.PROFILE
123 }) 128 })
diff --git a/server/lib/transcoding/video-transcoding-profiles.ts b/server/lib/transcoding/video-transcoding-profiles.ts
index c5ea72a5f..2309f38d4 100644
--- a/server/lib/transcoding/video-transcoding-profiles.ts
+++ b/server/lib/transcoding/video-transcoding-profiles.ts
@@ -1,14 +1,7 @@
1import { logger } from '@server/helpers/logger' 1import { logger } from '@server/helpers/logger'
2import { AvailableEncoders, EncoderOptionsBuilder, getTargetBitrate, VideoResolution } from '../../../shared/models/videos' 2import { AvailableEncoders, EncoderOptionsBuilder, getTargetBitrate, VideoResolution } from '../../../shared/models/videos'
3import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-utils' 3import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-utils'
4import { 4import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '../../helpers/ffprobe-utils'
5 canDoQuickAudioTranscode,
6 ffprobePromise,
7 getAudioStream,
8 getMaxAudioBitrate,
9 getVideoFileBitrate,
10 getVideoStreamFromFile
11} from '../../helpers/ffprobe-utils'
12import { VIDEO_TRANSCODING_FPS } from '../../initializers/constants' 5import { VIDEO_TRANSCODING_FPS } from '../../initializers/constants'
13 6
14/** 7/**
@@ -22,8 +15,8 @@ import { VIDEO_TRANSCODING_FPS } from '../../initializers/constants'
22// * https://slhck.info/video/2017/03/01/rate-control.html 15// * https://slhck.info/video/2017/03/01/rate-control.html
23// * https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate 16// * https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
24 17
25const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = async ({ input, resolution, fps }) => { 18const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = async ({ inputBitrate, resolution, fps }) => {
26 const targetBitrate = await buildTargetBitrate({ input, resolution, fps }) 19 const targetBitrate = buildTargetBitrate({ inputBitrate, resolution, fps })
27 if (!targetBitrate) return { outputOptions: [ ] } 20 if (!targetBitrate) return { outputOptions: [ ] }
28 21
29 return { 22 return {
@@ -36,8 +29,8 @@ const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = async ({ input, reso
36 } 29 }
37} 30}
38 31
39const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = async ({ resolution, fps, streamNum }) => { 32const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = async ({ resolution, fps, inputBitrate, streamNum }) => {
40 const targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS) 33 const targetBitrate = buildTargetBitrate({ inputBitrate, resolution, fps })
41 34
42 return { 35 return {
43 outputOptions: [ 36 outputOptions: [
@@ -237,20 +230,16 @@ export {
237} 230}
238 231
239// --------------------------------------------------------------------------- 232// ---------------------------------------------------------------------------
240async function buildTargetBitrate (options: { 233
241 input: string 234function buildTargetBitrate (options: {
235 inputBitrate: number
242 resolution: VideoResolution 236 resolution: VideoResolution
243 fps: number 237 fps: number
244}) { 238}) {
245 const { input, resolution, fps } = options 239 const { inputBitrate, resolution, fps } = options
246 const probe = await ffprobePromise(input)
247
248 const videoStream = await getVideoStreamFromFile(input, probe)
249 if (!videoStream) return undefined
250 240
251 const targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS) 241 const targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS)
242 if (!inputBitrate) return targetBitrate
252 243
253 // Don't transcode to an higher bitrate than the original file 244 return Math.min(targetBitrate, inputBitrate)
254 const fileBitrate = await getVideoFileBitrate(input, probe)
255 return Math.min(targetBitrate, fileBitrate)
256} 245}