aboutsummaryrefslogtreecommitdiffhomepage
path: root/shared/ffmpeg
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2023-05-05 10:53:04 +0200
committerChocobozzz <chocobozzz@cpy.re>2023-05-09 08:57:34 +0200
commite7d8e2b245491c0a8e008fb570037506d729ff04 (patch)
treed850a7f82cc02946f2e87b306d0b281cef5eb73d /shared/ffmpeg
parentdd3f99434cc3cb7226d33ffcd888c91d0ce150a9 (diff)
downloadPeerTube-e7d8e2b245491c0a8e008fb570037506d729ff04.tar.gz
PeerTube-e7d8e2b245491c0a8e008fb570037506d729ff04.tar.zst
PeerTube-e7d8e2b245491c0a8e008fb570037506d729ff04.zip
Fix audio transcoding copy
Diffstat (limited to 'shared/ffmpeg')
-rw-r--r--shared/ffmpeg/ffmpeg-default-transcoding-profile.ts61
1 files changed, 57 insertions, 4 deletions
diff --git a/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts b/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts
index f7fc49465..8a3f32011 100644
--- a/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts
+++ b/shared/ffmpeg/ffmpeg-default-transcoding-profile.ts
@@ -1,5 +1,15 @@
1import { getAverageBitrate, getMinLimitBitrate } from '@shared/core-utils' 1import { FfprobeData } from 'fluent-ffmpeg'
2import { buildStreamSuffix, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '@shared/ffmpeg' 2import { getAverageTheoreticalBitrate, getMaxTheoreticalBitrate, getMinTheoreticalBitrate } from '@shared/core-utils'
3import {
4 buildStreamSuffix,
5 ffprobePromise,
6 getAudioStream,
7 getMaxAudioBitrate,
8 getVideoStream,
9 getVideoStreamBitrate,
10 getVideoStreamDimensionsInfo,
11 getVideoStreamFPS
12} from '@shared/ffmpeg'
3import { EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '@shared/models' 13import { EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '@shared/models'
4 14
5const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => { 15const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
@@ -34,6 +44,10 @@ const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOp
34const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum, canCopyAudio }) => { 44const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum, canCopyAudio }) => {
35 const probe = await ffprobePromise(input) 45 const probe = await ffprobePromise(input)
36 46
47 if (canCopyAudio && await canDoQuickAudioTranscode(input, probe)) {
48 return { copy: true, outputOptions: [ ] }
49 }
50
37 const parsedAudio = await getAudioStream(input, probe) 51 const parsedAudio = await getAudioStream(input, probe)
38 52
39 // We try to reduce the ceiling bitrate by making rough matches of bitrates 53 // We try to reduce the ceiling bitrate by making rough matches of bitrates
@@ -95,6 +109,45 @@ export function getDefaultEncodersToTry () {
95 } 109 }
96} 110}
97 111
112export async function canDoQuickAudioTranscode (path: string, probe?: FfprobeData): Promise<boolean> {
113 const parsedAudio = await getAudioStream(path, probe)
114
115 if (!parsedAudio.audioStream) return true
116
117 if (parsedAudio.audioStream['codec_name'] !== 'aac') return false
118
119 const audioBitrate = parsedAudio.bitrate
120 if (!audioBitrate) return false
121
122 const maxAudioBitrate = getMaxAudioBitrate('aac', audioBitrate)
123 if (maxAudioBitrate !== -1 && audioBitrate > maxAudioBitrate) return false
124
125 const channelLayout = parsedAudio.audioStream['channel_layout']
126 // Causes playback issues with Chrome
127 if (!channelLayout || channelLayout === 'unknown' || channelLayout === 'quad') return false
128
129 return true
130}
131
132export async function canDoQuickVideoTranscode (path: string, probe?: FfprobeData): Promise<boolean> {
133 const videoStream = await getVideoStream(path, probe)
134 const fps = await getVideoStreamFPS(path, probe)
135 const bitRate = await getVideoStreamBitrate(path, probe)
136 const resolutionData = await getVideoStreamDimensionsInfo(path, probe)
137
138 // If ffprobe did not manage to guess the bitrate
139 if (!bitRate) return false
140
141 // check video params
142 if (!videoStream) return false
143 if (videoStream['codec_name'] !== 'h264') return false
144 if (videoStream['pix_fmt'] !== 'yuv420p') return false
145 if (fps < 2 || fps > 65) return false
146 if (bitRate > getMaxTheoreticalBitrate({ ...resolutionData, fps })) return false
147
148 return true
149}
150
98// --------------------------------------------------------------------------- 151// ---------------------------------------------------------------------------
99 152
100function getTargetBitrate (options: { 153function getTargetBitrate (options: {
@@ -105,8 +158,8 @@ function getTargetBitrate (options: {
105}) { 158}) {
106 const { inputBitrate, resolution, ratio, fps } = options 159 const { inputBitrate, resolution, ratio, fps } = options
107 160
108 const capped = capBitrate(inputBitrate, getAverageBitrate({ resolution, fps, ratio })) 161 const capped = capBitrate(inputBitrate, getAverageTheoreticalBitrate({ resolution, fps, ratio }))
109 const limit = getMinLimitBitrate({ resolution, fps, ratio }) 162 const limit = getMinTheoreticalBitrate({ resolution, fps, ratio })
110 163
111 return Math.max(limit, capped) 164 return Math.max(limit, capped)
112} 165}