about summary refs log tree commit diff
path: root/app/models/media_attachment.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/media_attachment.rb')
-rw-r--r--app/models/media_attachment.rb73
1 files changed, 49 insertions, 24 deletions
diff --git a/app/models/media_attachment.rb b/app/models/media_attachment.rb
index 6925f9b0d..818190214 100644
--- a/app/models/media_attachment.rb
+++ b/app/models/media_attachment.rb
@@ -1,15 +1,32 @@
 # frozen_string_literal: true
 
 class MediaAttachment < ApplicationRecord
+  self.inheritance_column = nil
+
+  enum type: [:image, :gifv, :video]
+
   IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
   VIDEO_MIME_TYPES = ['video/webm', 'video/mp4'].freeze
 
+  IMAGE_STYLES = { original: '1280x1280>', small: '400x400>' }.freeze
+  VIDEO_STYLES = {
+    small: {
+      convert_options: {
+        output: {
+          vf: 'scale=\'min(400\, iw):min(400\, ih)\':force_original_aspect_ratio=decrease',
+        },
+      },
+      format: 'png',
+      time: 0,
+    },
+  }.freeze
+
   belongs_to :account, inverse_of: :media_attachments
   belongs_to :status,  inverse_of: :media_attachments
 
   has_attached_file :file,
-                    styles: -> (f) { file_styles f },
-                    processors: -> (f) { f.video? ? [:transcoder] : [:thumbnail] },
+                    styles: ->(f) { file_styles f },
+                    processors: ->(f) { file_processors f },
                     convert_options: { all: '-quality 90 -strip' }
   validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES
   validates_attachment_size :file, less_than: 8.megabytes
@@ -27,45 +44,49 @@ class MediaAttachment < ApplicationRecord
     self.file = URI.parse(url)
   end
 
-  def image?
-    IMAGE_MIME_TYPES.include? file_content_type
-  end
-
-  def video?
-    VIDEO_MIME_TYPES.include? file_content_type
-  end
-
-  def type
-    image? ? 'image' : 'video'
-  end
-
   def to_param
     shortcode
   end
 
   before_create :set_shortcode
+  before_post_process :set_type
 
   class << self
     private
 
     def file_styles(f)
-      if f.instance.image?
+      if f.instance.file_content_type == 'image/gif'
         {
-          original: '1280x1280>',
-          small: '400x400>',
-        }
-      else
-        {
-          small: {
+          small: IMAGE_STYLES[:small],
+          original: {
+            format: 'mp4',
             convert_options: {
               output: {
-                vf: 'scale=\'min(400\, iw):min(400\, ih)\':force_original_aspect_ratio=decrease',
+                'movflags' => 'faststart',
+                'pix_fmt'  => 'yuv420p',
+                'vf'       => 'scale=\'trunc(iw/2)*2:trunc(ih/2)*2\'',
+                'vsync'    => 'cfr',
+                'b:v'      => '1300K',
+                'maxrate'  => '500K',
+                'crf'      => 6,
               },
             },
-            format: 'png',
-            time: 1,
           },
         }
+      elsif IMAGE_MIME_TYPES.include? f.instance.file_content_type
+        IMAGE_STYLES
+      else
+        VIDEO_STYLES
+      end
+    end
+
+    def file_processors(f)
+      if f.file_content_type == 'image/gif'
+        [:gif_transcoder]
+      elsif VIDEO_MIME_TYPES.include? f.file_content_type
+        [:video_transcoder]
+      else
+        [:thumbnail]
       end
     end
   end
@@ -80,4 +101,8 @@ class MediaAttachment < ApplicationRecord
       break if MediaAttachment.find_by(shortcode: shortcode).nil?
     end
   end
+
+  def set_type
+    self.type = VIDEO_MIME_TYPES.include?(file_content_type) ? :video : :image
+  end
 end