aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared
diff options
context:
space:
mode:
Diffstat (limited to 'shared')
-rw-r--r--shared/ffmpeg/ffmpeg-default-transcoding-profile.ts134
-rw-r--r--shared/ffmpeg/index.ts1
-rw-r--r--shared/models/runners/runner-job-payload.model.ts4
-rw-r--r--shared/models/runners/runner-job-private-payload.model.ts4
-rw-r--r--shared/models/runners/runner-job-success-body.model.ts4
-rw-r--r--shared/models/runners/runner-job-type.type.ts2
6 files changed, 142 insertions, 7 deletions
diff --git a/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts b/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts
new file mode 100644
index 000000000..f7fc49465
--- /dev/null
+++ b/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts
@@ -0,0 +1,134 @@
1import { getAverageBitrate, getMinLimitBitrate } from '@shared/core-utils'
2import { buildStreamSuffix, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '@shared/ffmpeg'
3import { EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '@shared/models'
4
5const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
6 const { fps, inputRatio, inputBitrate, resolution } = options
7
8 const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
9
10 return {
11 outputOptions: [
12 ...getCommonOutputOptions(targetBitrate),
13
14 `-r ${fps}`
15 ]
16 }
17}
18
19const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
20 const { streamNum, fps, inputBitrate, inputRatio, resolution } = options
21
22 const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
23
24 return {
25 outputOptions: [
26 ...getCommonOutputOptions(targetBitrate, streamNum),
27
28 `${buildStreamSuffix('-r:v', streamNum)} ${fps}`,
29 `${buildStreamSuffix('-b:v', streamNum)} ${targetBitrate}`
30 ]
31 }
32}
33
34const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum, canCopyAudio }) => {
35 const probe = await ffprobePromise(input)
36
37 const parsedAudio = await getAudioStream(input, probe)
38
39 // We try to reduce the ceiling bitrate by making rough matches of bitrates
40 // Of course this is far from perfect, but it might save some space in the end
41
42 const audioCodecName = parsedAudio.audioStream['codec_name']
43
44 const bitrate = getMaxAudioBitrate(audioCodecName, parsedAudio.bitrate)
45
46 // Force stereo as it causes some issues with HLS playback in Chrome
47 const base = [ '-channel_layout', 'stereo' ]
48
49 if (bitrate !== -1) {
50 return { outputOptions: base.concat([ buildStreamSuffix('-b:a', streamNum), bitrate + 'k' ]) }
51 }
52
53 return { outputOptions: base }
54}
55
56const defaultLibFDKAACVODOptionsBuilder: EncoderOptionsBuilder = ({ streamNum }) => {
57 return { outputOptions: [ buildStreamSuffix('-q:a', streamNum), '5' ] }
58}
59
60export function getDefaultAvailableEncoders () {
61 return {
62 vod: {
63 libx264: {
64 default: defaultX264VODOptionsBuilder
65 },
66 aac: {
67 default: defaultAACOptionsBuilder
68 },
69 libfdk_aac: {
70 default: defaultLibFDKAACVODOptionsBuilder
71 }
72 },
73 live: {
74 libx264: {
75 default: defaultX264LiveOptionsBuilder
76 },
77 aac: {
78 default: defaultAACOptionsBuilder
79 }
80 }
81 }
82}
83
84export function getDefaultEncodersToTry () {
85 return {
86 vod: {
87 video: [ 'libx264' ],
88 audio: [ 'libfdk_aac', 'aac' ]
89 },
90
91 live: {
92 video: [ 'libx264' ],
93 audio: [ 'libfdk_aac', 'aac' ]
94 }
95 }
96}
97
98// ---------------------------------------------------------------------------
99
100function getTargetBitrate (options: {
101 inputBitrate: number
102 resolution: VideoResolution
103 ratio: number
104 fps: number
105}) {
106 const { inputBitrate, resolution, ratio, fps } = options
107
108 const capped = capBitrate(inputBitrate, getAverageBitrate({ resolution, fps, ratio }))
109 const limit = getMinLimitBitrate({ resolution, fps, ratio })
110
111 return Math.max(limit, capped)
112}
113
114function capBitrate (inputBitrate: number, targetBitrate: number) {
115 if (!inputBitrate) return targetBitrate
116
117 // Add 30% margin to input bitrate
118 const inputBitrateWithMargin = inputBitrate + (inputBitrate * 0.3)
119
120 return Math.min(targetBitrate, inputBitrateWithMargin)
121}
122
123function getCommonOutputOptions (targetBitrate: number, streamNum?: number) {
124 return [
125 `-preset veryfast`,
126 `${buildStreamSuffix('-maxrate:v', streamNum)} ${targetBitrate}`,
127 `${buildStreamSuffix('-bufsize:v', streamNum)} ${targetBitrate * 2}`,
128
129 // NOTE: b-strategy 1 - heuristic algorithm, 16 is optimal B-frames for it
130 `-b_strategy 1`,
131 // NOTE: Why 16: https://github.com/Chocobozzz/PeerTube/pull/774. b-strategy 2 -> B-frames<16
132 `-bf 16`
133 ]
134}
diff --git a/shared/ffmpeg/index.ts b/shared/ffmpeg/index.ts
index 07a7d5402..1dab292da 100644
--- a/shared/ffmpeg/index.ts
+++ b/shared/ffmpeg/index.ts
@@ -1,4 +1,5 @@
1export * from './ffmpeg-command-wrapper' 1export * from './ffmpeg-command-wrapper'
2export * from './ffmpeg-default-transcoding-profile'
2export * from './ffmpeg-edition' 3export * from './ffmpeg-edition'
3export * from './ffmpeg-images' 4export * from './ffmpeg-images'
4export * from './ffmpeg-live' 5export * from './ffmpeg-live'
diff --git a/shared/models/runners/runner-job-payload.model.ts b/shared/models/runners/runner-job-payload.model.ts
index 9f0db0dc4..3dda6c51f 100644
--- a/shared/models/runners/runner-job-payload.model.ts
+++ b/shared/models/runners/runner-job-payload.model.ts
@@ -8,7 +8,7 @@ export type RunnerJobVODPayload =
8export type RunnerJobPayload = 8export type RunnerJobPayload =
9 RunnerJobVODPayload | 9 RunnerJobVODPayload |
10 RunnerJobLiveRTMPHLSTranscodingPayload | 10 RunnerJobLiveRTMPHLSTranscodingPayload |
11 RunnerJobVideoEditionTranscodingPayload 11 RunnerJobStudioTranscodingPayload
12 12
13// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
14 14
@@ -46,7 +46,7 @@ export interface RunnerJobVODAudioMergeTranscodingPayload {
46 } 46 }
47} 47}
48 48
49export interface RunnerJobVideoEditionTranscodingPayload { 49export interface RunnerJobStudioTranscodingPayload {
50 input: { 50 input: {
51 videoFileUrl: string 51 videoFileUrl: string
52 } 52 }
diff --git a/shared/models/runners/runner-job-private-payload.model.ts b/shared/models/runners/runner-job-private-payload.model.ts
index c8fe0a7d8..32b837de4 100644
--- a/shared/models/runners/runner-job-private-payload.model.ts
+++ b/shared/models/runners/runner-job-private-payload.model.ts
@@ -8,7 +8,7 @@ export type RunnerJobVODPrivatePayload =
8export type RunnerJobPrivatePayload = 8export type RunnerJobPrivatePayload =
9 RunnerJobVODPrivatePayload | 9 RunnerJobVODPrivatePayload |
10 RunnerJobLiveRTMPHLSTranscodingPrivatePayload | 10 RunnerJobLiveRTMPHLSTranscodingPrivatePayload |
11 RunnerJobVideoEditionTranscodingPrivatePayload 11 RunnerJobVideoStudioTranscodingPrivatePayload
12 12
13// --------------------------------------------------------------------------- 13// ---------------------------------------------------------------------------
14 14
@@ -38,7 +38,7 @@ export interface RunnerJobLiveRTMPHLSTranscodingPrivatePayload {
38 38
39// --------------------------------------------------------------------------- 39// ---------------------------------------------------------------------------
40 40
41export interface RunnerJobVideoEditionTranscodingPrivatePayload { 41export interface RunnerJobVideoStudioTranscodingPrivatePayload {
42 videoUUID: string 42 videoUUID: string
43 originalTasks: VideoStudioTaskPayload[] 43 originalTasks: VideoStudioTaskPayload[]
44} 44}
diff --git a/shared/models/runners/runner-job-success-body.model.ts b/shared/models/runners/runner-job-success-body.model.ts
index 17e921f69..f45336b05 100644
--- a/shared/models/runners/runner-job-success-body.model.ts
+++ b/shared/models/runners/runner-job-success-body.model.ts
@@ -12,7 +12,7 @@ export type RunnerJobSuccessPayload =
12 VODHLSTranscodingSuccess | 12 VODHLSTranscodingSuccess |
13 VODAudioMergeTranscodingSuccess | 13 VODAudioMergeTranscodingSuccess |
14 LiveRTMPHLSTranscodingSuccess | 14 LiveRTMPHLSTranscodingSuccess |
15 VideoEditionTranscodingSuccess 15 VideoStudioTranscodingSuccess
16 16
17export interface VODWebVideoTranscodingSuccess { 17export interface VODWebVideoTranscodingSuccess {
18 videoFile: Blob | string 18 videoFile: Blob | string
@@ -31,7 +31,7 @@ export interface LiveRTMPHLSTranscodingSuccess {
31 31
32} 32}
33 33
34export interface VideoEditionTranscodingSuccess { 34export interface VideoStudioTranscodingSuccess {
35 videoFile: Blob | string 35 videoFile: Blob | string
36} 36}
37 37
diff --git a/shared/models/runners/runner-job-type.type.ts b/shared/models/runners/runner-job-type.type.ts
index 3b997cb6e..91b92a729 100644
--- a/shared/models/runners/runner-job-type.type.ts
+++ b/shared/models/runners/runner-job-type.type.ts
@@ -3,4 +3,4 @@ export type RunnerJobType =
3 'vod-hls-transcoding' | 3 'vod-hls-transcoding' |
4 'vod-audio-merge-transcoding' | 4 'vod-audio-merge-transcoding' |
5 'live-rtmp-hls-transcoding' | 5 'live-rtmp-hls-transcoding' |
6 'video-edition-transcoding' 6 'video-studio-transcoding'