Skip to content

Commit

Permalink
feature: allow videos and gifs larger than the limits, just transcode…
Browse files Browse the repository at this point in the history
… them. also increase the limits
  • Loading branch information
sneakers-the-rat committed Dec 18, 2023
1 parent 5bcd2d1 commit 2ae3f61
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 4 deletions.
4 changes: 3 additions & 1 deletion app/models/concerns/attachmentable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ module Attachmentable
extend ActiveSupport::Concern

MAX_MATRIX_LIMIT = 33_177_600 # 7680x4320px or approx. 847MB in RAM
GIF_MATRIX_LIMIT = 921_600 # 1280x720px
MAX_GIF_WIDTH = 3840
MAX_GIF_HEIGHT = 2160
GIF_MATRIX_LIMIT = MAX_GIF_WIDTH * MAX_GIF_HEIGHT

# For some file extensions, there exist different content
# type variants, and browsers often send the wrong one,
Expand Down
11 changes: 8 additions & 3 deletions app/models/media_attachment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ class MediaAttachment < ApplicationRecord
IMAGE_LIMIT = (ENV['MAX_IMAGE_SIZE'] || 16.megabytes).to_i
VIDEO_LIMIT = (ENV['MAX_VIDEO_SIZE'] || 99.megabytes).to_i

MAX_VIDEO_MATRIX_LIMIT = 8_294_400 # 3840x2160px
MAX_VIDEO_WIDTH = 3840
MAX_VIDEO_HEIGHT = 2160
MAX_VIDEO_MATRIX_LIMIT = MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT # 3840x2160px
MAX_VIDEO_FRAME_RATE = 120
MAX_VIDEO_FRAMES = 36_000 # Approx. 5 minutes at 120 fps

Expand Down Expand Up @@ -102,7 +104,9 @@ class MediaAttachment < ApplicationRecord
'preset' => 'veryfast',
'movflags' => 'faststart', # Move metadata to start of file so playback can begin before download finishes
'pix_fmt' => 'yuv420p', # Ensure color space for cross-browser compatibility
'vf' => 'crop=floor(iw/2)*2:floor(ih/2)*2', # h264 requires width and height to be even. Crop instead of scale to avoid blurring
# scale videos if larger than maximum width or height, keeping same size otherwise. then,
# h264 requires width and height to be even. Crop instead of scale to avoid blurring
'vf' => "scale=iw*min(1\\,min(#{MAX_VIDEO_WIDTH}/iw\\,#{MAX_VIDEO_HEIGHT}/ih)):-1,crop=floor(iw/2)*2:floor(ih/2)*2",
'c:v' => 'h264',
'c:a' => 'aac',
'b:a' => '192k',
Expand Down Expand Up @@ -348,7 +352,8 @@ def check_video_dimensions
return unless movie.valid?

raise Mastodon::StreamValidationError, 'Video has no video stream' if movie.width.nil? || movie.frame_rate.nil?
raise Mastodon::DimensionsValidationError, "#{movie.width}x#{movie.height} videos are not supported" if movie.width * movie.height > MAX_VIDEO_MATRIX_LIMIT
# Only reject if more than 1.5x max allowed size to reject resource overuse attacks, otherwise rescale
raise Mastodon::DimensionsValidationError, "#{movie.width}x#{movie.height} videos are not supported" if movie.width * movie.height > MAX_VIDEO_MATRIX_LIMIT * 1.5
raise Mastodon::DimensionsValidationError, "#{movie.frame_rate.floor}fps videos are not supported" if movie.frame_rate.floor > MAX_VIDEO_FRAME_RATE
end

Expand Down

0 comments on commit 2ae3f61

Please sign in to comment.