diff options
author | Chocobozzz <me@florianbigard.com> | 2021-08-06 13:35:25 +0200 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2021-08-06 14:13:26 +0200 |
commit | 679c12e69c9f3a2d003ee3abe8b8da49f25b2bd3 (patch) | |
tree | 03abf589275db05e5b1fa1c89f57049cd807324a /shared/core-utils/videos/bitrate.ts | |
parent | c826f34a45757b324a20f71665b44ed10e6953b5 (diff) | |
download | PeerTube-679c12e69c9f3a2d003ee3abe8b8da49f25b2bd3.tar.gz PeerTube-679c12e69c9f3a2d003ee3abe8b8da49f25b2bd3.tar.zst PeerTube-679c12e69c9f3a2d003ee3abe8b8da49f25b2bd3.zip |
Improve target bitrate calculation
Diffstat (limited to 'shared/core-utils/videos/bitrate.ts')
-rw-r--r-- | shared/core-utils/videos/bitrate.ts | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/shared/core-utils/videos/bitrate.ts b/shared/core-utils/videos/bitrate.ts new file mode 100644 index 000000000..3d4e47906 --- /dev/null +++ b/shared/core-utils/videos/bitrate.ts | |||
@@ -0,0 +1,86 @@ | |||
1 | import { VideoResolution } from "@shared/models" | ||
2 | |||
3 | type BitPerPixel = { [ id in VideoResolution ]: number } | ||
4 | |||
5 | // https://bitmovin.com/video-bitrate-streaming-hls-dash/ | ||
6 | |||
7 | const averageBitPerPixel: BitPerPixel = { | ||
8 | [VideoResolution.H_NOVIDEO]: 0, | ||
9 | [VideoResolution.H_240P]: 0.17, | ||
10 | [VideoResolution.H_360P]: 0.15, | ||
11 | [VideoResolution.H_480P]: 0.12, | ||
12 | [VideoResolution.H_720P]: 0.11, | ||
13 | [VideoResolution.H_1080P]: 0.10, | ||
14 | [VideoResolution.H_1440P]: 0.09, | ||
15 | [VideoResolution.H_4K]: 0.08 | ||
16 | } | ||
17 | |||
18 | const maxBitPerPixel: BitPerPixel = { | ||
19 | [VideoResolution.H_NOVIDEO]: 0, | ||
20 | [VideoResolution.H_240P]: 0.29, | ||
21 | [VideoResolution.H_360P]: 0.26, | ||
22 | [VideoResolution.H_480P]: 0.22, | ||
23 | [VideoResolution.H_720P]: 0.19, | ||
24 | [VideoResolution.H_1080P]: 0.17, | ||
25 | [VideoResolution.H_1440P]: 0.16, | ||
26 | [VideoResolution.H_4K]: 0.14 | ||
27 | } | ||
28 | |||
29 | function getAverageBitrate (options: { | ||
30 | resolution: VideoResolution | ||
31 | ratio: number | ||
32 | fps: number | ||
33 | }) { | ||
34 | const targetBitrate = calculateBitrate({ ...options, bitPerPixel: averageBitPerPixel }) | ||
35 | if (!targetBitrate) return 192 * 1000 | ||
36 | |||
37 | return targetBitrate | ||
38 | } | ||
39 | |||
40 | function getMaxBitrate (options: { | ||
41 | resolution: VideoResolution | ||
42 | ratio: number | ||
43 | fps: number | ||
44 | }) { | ||
45 | const targetBitrate = calculateBitrate({ ...options, bitPerPixel: maxBitPerPixel }) | ||
46 | if (!targetBitrate) return 256 * 1000 | ||
47 | |||
48 | return targetBitrate | ||
49 | } | ||
50 | |||
51 | // --------------------------------------------------------------------------- | ||
52 | |||
53 | export { | ||
54 | getAverageBitrate, | ||
55 | getMaxBitrate | ||
56 | } | ||
57 | |||
58 | // --------------------------------------------------------------------------- | ||
59 | |||
60 | function calculateBitrate (options: { | ||
61 | bitPerPixel: BitPerPixel | ||
62 | resolution: VideoResolution | ||
63 | ratio: number | ||
64 | fps: number | ||
65 | }) { | ||
66 | const { bitPerPixel, resolution, ratio, fps } = options | ||
67 | |||
68 | const resolutionsOrder = [ | ||
69 | VideoResolution.H_4K, | ||
70 | VideoResolution.H_1440P, | ||
71 | VideoResolution.H_1080P, | ||
72 | VideoResolution.H_720P, | ||
73 | VideoResolution.H_480P, | ||
74 | VideoResolution.H_360P, | ||
75 | VideoResolution.H_240P, | ||
76 | VideoResolution.H_NOVIDEO | ||
77 | ] | ||
78 | |||
79 | for (const toTestResolution of resolutionsOrder) { | ||
80 | if (toTestResolution <= resolution) { | ||
81 | return resolution * resolution * ratio * fps * bitPerPixel[toTestResolution] | ||
82 | } | ||
83 | } | ||
84 | |||
85 | throw new Error('Unknown resolution ' + resolution) | ||
86 | } | ||