]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/helpers/ffmpeg-utils.ts
Add tests for video downscale framerate matching
[github/Chocobozzz/PeerTube.git] / server / helpers / ffmpeg-utils.ts
index 1eea05d1edaaaeeaecc8cce6b8dfaf052c38bd20..63dc5b6a3af39ac92ed9e8893fea1ccc31a1492c 100644 (file)
@@ -70,7 +70,7 @@ async function getAudioStreamCodec (path: string) {
   if (!audioStream) return ''
 
   const audioCodec = audioStream.codec_name
-  if (audioCodec.codec_name === 'aac') return 'mp4a.40.2'
+  if (audioCodec === 'aac') return 'mp4a.40.2'
 
   logger.warn('Cannot get audio codec of %s.', path, { audioStream })
 
@@ -263,6 +263,10 @@ async function canDoQuickTranscode (path: string): Promise<boolean> {
   return true
 }
 
+function getClosestFramerateStandard (fps: number, hd = false): number {
+  return VIDEO_TRANSCODING_FPS[hd ? 'HD_STANDARD' : 'STANDARD'].slice(0).sort((a, b) => fps % a - fps % b)[0]
+}
+
 // ---------------------------------------------------------------------------
 
 export {
@@ -286,13 +290,16 @@ export {
 
 async function buildx264Command (command: ffmpeg.FfmpegCommand, options: TranscodeOptions) {
   let fps = await getVideoFileFPS(options.inputPath)
-  // On small/medium resolutions, limit FPS
   if (
+    // On small/medium resolutions, limit FPS
     options.resolution !== undefined &&
     options.resolution < VIDEO_TRANSCODING_FPS.KEEP_ORIGIN_FPS_RESOLUTION_MIN &&
-    fps > VIDEO_TRANSCODING_FPS.AVERAGE
+    fps > VIDEO_TRANSCODING_FPS.AVERAGE ||
+    // If the video is doesn't match hd standard
+    !VIDEO_TRANSCODING_FPS.HD_STANDARD.some(value => fps % value === 0)
   ) {
-    fps = VIDEO_TRANSCODING_FPS.AVERAGE
+    // Get closest standard framerate by modulo: downsampling has to be done to a divisor of the nominal fps value
+    fps = getClosestFramerateStandard(fps)
   }
 
   command = await presetH264(command, options.inputPath, options.resolution, fps)
@@ -305,7 +312,7 @@ async function buildx264Command (command: ffmpeg.FfmpegCommand, options: Transco
 
   if (fps) {
     // Hard FPS limits
-    if (fps > VIDEO_TRANSCODING_FPS.MAX) fps = VIDEO_TRANSCODING_FPS.MAX
+    if (fps > VIDEO_TRANSCODING_FPS.MAX) fps = getClosestFramerateStandard(fps, true)
     else if (fps < VIDEO_TRANSCODING_FPS.MIN) fps = VIDEO_TRANSCODING_FPS.MIN
 
     command = command.withFPS(fps)