PeerTube/shared/core-utils/videos/bitrate.ts

114 lines
2.9 KiB
TypeScript
Raw Normal View History

import { VideoResolution } from '@shared/models'
2021-08-06 13:35:25 +02:00
type BitPerPixel = { [ id in VideoResolution ]: number }
// https://bitmovin.com/video-bitrate-streaming-hls-dash/
2021-11-10 11:04:00 +01:00
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
}
2021-08-06 13:35:25 +02:00
const averageBitPerPixel: BitPerPixel = {
[VideoResolution.H_NOVIDEO]: 0,
[VideoResolution.H_144P]: 0.19,
2021-08-06 13:35:25 +02:00
[VideoResolution.H_240P]: 0.17,
[VideoResolution.H_360P]: 0.15,
[VideoResolution.H_480P]: 0.12,
[VideoResolution.H_720P]: 0.11,
[VideoResolution.H_1080P]: 0.10,
[VideoResolution.H_1440P]: 0.09,
[VideoResolution.H_4K]: 0.08
}
const maxBitPerPixel: BitPerPixel = {
[VideoResolution.H_NOVIDEO]: 0,
[VideoResolution.H_144P]: 0.32,
2021-08-06 13:35:25 +02:00
[VideoResolution.H_240P]: 0.29,
[VideoResolution.H_360P]: 0.26,
[VideoResolution.H_480P]: 0.22,
[VideoResolution.H_720P]: 0.19,
[VideoResolution.H_1080P]: 0.17,
[VideoResolution.H_1440P]: 0.16,
[VideoResolution.H_4K]: 0.14
}
2023-05-05 10:53:04 +02:00
function getAverageTheoreticalBitrate (options: {
2021-08-06 13:35:25 +02:00
resolution: VideoResolution
ratio: number
fps: number
}) {
const targetBitrate = calculateBitrate({ ...options, bitPerPixel: averageBitPerPixel })
if (!targetBitrate) return 192 * 1000
return targetBitrate
}
2023-05-05 10:53:04 +02:00
function getMaxTheoreticalBitrate (options: {
2021-08-06 13:35:25 +02:00
resolution: VideoResolution
ratio: number
fps: number
}) {
const targetBitrate = calculateBitrate({ ...options, bitPerPixel: maxBitPerPixel })
if (!targetBitrate) return 256 * 1000
return targetBitrate
}
2023-05-05 10:53:04 +02:00
function getMinTheoreticalBitrate (options: {
2021-11-10 11:04:00 +01:00
resolution: VideoResolution
ratio: number
fps: number
}) {
const minLimitBitrate = calculateBitrate({ ...options, bitPerPixel: minLimitBitPerPixel })
if (!minLimitBitrate) return 10 * 1000
return minLimitBitrate
}
2021-08-06 13:35:25 +02:00
// ---------------------------------------------------------------------------
export {
2023-05-05 10:53:04 +02:00
getAverageTheoreticalBitrate,
getMaxTheoreticalBitrate,
getMinTheoreticalBitrate
2021-08-06 13:35:25 +02:00
}
// ---------------------------------------------------------------------------
function calculateBitrate (options: {
bitPerPixel: BitPerPixel
resolution: VideoResolution
ratio: number
fps: number
}) {
const { bitPerPixel, resolution, ratio, fps } = options
const resolutionsOrder = [
VideoResolution.H_4K,
VideoResolution.H_1440P,
VideoResolution.H_1080P,
VideoResolution.H_720P,
VideoResolution.H_480P,
VideoResolution.H_360P,
VideoResolution.H_240P,
VideoResolution.H_144P,
2021-08-06 13:35:25 +02:00
VideoResolution.H_NOVIDEO
]
for (const toTestResolution of resolutionsOrder) {
if (toTestResolution <= resolution) {
2021-10-12 09:18:54 +02:00
return Math.floor(resolution * resolution * ratio * fps * bitPerPixel[toTestResolution])
2021-08-06 13:35:25 +02:00
}
}
throw new Error('Unknown resolution ' + resolution)
}