From 0f3f9b611f509fc5405bb1bcbeb71dfcdff7095b Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Tue, 19 Sep 2023 12:25:58 +0200
Subject: [PATCH] Change video bitrate to always fit within size limit (#26970)

---
 lib/paperclip/transcoder.rb | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/lib/paperclip/transcoder.rb b/lib/paperclip/transcoder.rb
index b88cf662c..ed5425a3b 100644
--- a/lib/paperclip/transcoder.rb
+++ b/lib/paperclip/transcoder.rb
@@ -41,11 +41,14 @@ module Paperclip
         @output_options['vframes'] = 1
       when 'mp4'
         unless eligible_to_passthrough?(metadata)
-          bitrate = (metadata.width * metadata.height * 30 * BITS_PER_PIXEL) / 1_000
+          size_limit_in_bits = MediaAttachment::VIDEO_LIMIT * 8
+          desired_bitrate = (metadata.width * metadata.height * 30 * BITS_PER_PIXEL).floor
+          maximum_bitrate = (size_limit_in_bits / metadata.duration).floor - 192_000 # Leave some space for the audio stream
+          bitrate = [desired_bitrate, maximum_bitrate].min
 
-          @output_options['b:v']     = "#{bitrate}k"
-          @output_options['maxrate'] = "#{bitrate + 192}k"
-          @output_options['bufsize'] = "#{bitrate * 5}k"
+          @output_options['b:v']     = bitrate
+          @output_options['maxrate'] = bitrate + 192_000
+          @output_options['bufsize'] = bitrate * 5
 
           if high_vfr?(metadata)
             @output_options['vsync'] = 'vfr'