]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/lib/video-transcoding-profiles.ts
Refactor last PR
[github/Chocobozzz/PeerTube.git] / server / lib / video-transcoding-profiles.ts
index 91a5c65f2f137b93deafacc06828ffc21303de56..3bf83d6a8247bf2bc478aa7fe6ec21831f9ff93d 100644 (file)
@@ -1,33 +1,36 @@
-import { getTargetBitrate } from '../../shared/models/videos'
+import { logger } from '@server/helpers/logger'
+import { getTargetBitrate, VideoResolution } from '../../shared/models/videos'
 import { AvailableEncoders, buildStreamSuffix, EncoderOptionsBuilder } from '../helpers/ffmpeg-utils'
-import { ffprobePromise, getAudioStream, getMaxAudioBitrate, getVideoFileBitrate, getVideoStreamFromFile } from '../helpers/ffprobe-utils'
+import {
+  canDoQuickAudioTranscode,
+  ffprobePromise,
+  getAudioStream,
+  getMaxAudioBitrate,
+  getVideoFileBitrate,
+  getVideoStreamFromFile
+} from '../helpers/ffprobe-utils'
 import { VIDEO_TRANSCODING_FPS } from '../initializers/constants'
 
-// ---------------------------------------------------------------------------
-// Available encoders profiles
-// ---------------------------------------------------------------------------
+/**
+ *
+ * Available encoders and profiles for the transcoding jobs
+ * These functions are used by ffmpeg-utils that will get the encoders and options depending on the chosen profile
+ *
+ */
 
 // Resources:
 //  * https://slhck.info/video/2017/03/01/rate-control.html
 //  * https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
 
 const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = async ({ input, resolution, fps }) => {
-  let targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS)
-
-  const probe = await ffprobePromise(input)
-
-  const videoStream = await getVideoStreamFromFile(input, probe)
-  if (!videoStream) {
-    return { outputOptions: [ ] }
-  }
-
-  // Don't transcode to an higher bitrate than the original file
-  const fileBitrate = await getVideoFileBitrate(input, probe)
-  targetBitrate = Math.min(targetBitrate, fileBitrate)
+  const targetBitrate = await buildTargetBitrate({ input, resolution, fps })
+  if (!targetBitrate) return { outputOptions: [ ] }
 
   return {
     outputOptions: [
-      `-maxrate ${targetBitrate}`, `-bufsize ${targetBitrate * 2}`
+      `-r ${fps}`,
+      `-maxrate ${targetBitrate}`,
+      `-bufsize ${targetBitrate * 2}`
     ]
   }
 }
@@ -37,6 +40,7 @@ const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = async ({ resolution
 
   return {
     outputOptions: [
+      `${buildStreamSuffix('-r:v', streamNum)} ${fps}`,
       `${buildStreamSuffix('-b:v', streamNum)} ${targetBitrate}`,
       `-maxrate ${targetBitrate}`,
       `-bufsize ${targetBitrate * 2}`
@@ -45,7 +49,14 @@ const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = async ({ resolution
 }
 
 const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum }) => {
-  const parsedAudio = await getAudioStream(input)
+  const probe = await ffprobePromise(input)
+
+  if (await canDoQuickAudioTranscode(input, probe)) {
+    logger.debug('Copy audio stream %s by AAC encoder.', input)
+    return { copy: true, outputOptions: [] }
+  }
+
+  const parsedAudio = await getAudioStream(input, probe)
 
   // We try to reduce the ceiling bitrate by making rough matches of bitrates
   // Of course this is far from perfect, but it might save some space in the end
@@ -54,11 +65,13 @@ const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNu
 
   const bitrate = getMaxAudioBitrate(audioCodecName, parsedAudio.bitrate)
 
+  logger.debug('Calculating audio bitrate of %s by AAC encoder.', input, { bitrate: parsedAudio.bitrate, audioCodecName })
+
   if (bitrate !== undefined && bitrate !== -1) {
     return { outputOptions: [ buildStreamSuffix('-b:a', streamNum), bitrate + 'k' ] }
   }
 
-  return { copy: true, outputOptions: [] }
+  return { outputOptions: [ ] }
 }
 
 const defaultLibFDKAACVODOptionsBuilder: EncoderOptionsBuilder = ({ streamNum }) => {
@@ -94,3 +107,21 @@ export {
 }
 
 // ---------------------------------------------------------------------------
+async function buildTargetBitrate (options: {
+  input: string
+  resolution: VideoResolution
+  fps: number
+
+}) {
+  const { input, resolution, fps } = options
+  const probe = await ffprobePromise(input)
+
+  const videoStream = await getVideoStreamFromFile(input, probe)
+  if (!videoStream) return undefined
+
+  const targetBitrate = getTargetBitrate(resolution, fps, VIDEO_TRANSCODING_FPS)
+
+  // Don't transcode to an higher bitrate than the original file
+  const fileBitrate = await getVideoFileBitrate(input, probe)
+  return Math.min(targetBitrate, fileBitrate)
+}