2424class MediaAttachment < ApplicationRecord
2525 self . inheritance_column = nil
2626
27- enum type : [ :image , :gifv , :video , :unknown ]
27+ enum type : [ :image , :gifv , :video , :unknown , :audio ]
2828
2929 IMAGE_FILE_EXTENSIONS = [ '.jpg' , '.jpeg' , '.png' , '.gif' , '.webp' ] . freeze
3030 VIDEO_FILE_EXTENSIONS = [ '.webm' , '.mp4' , '.m4v' , '.mov' ] . freeze
31+ AUDIO_FILE_EXTENSIONS = [ '.ogg' , '.oga' , '.mp3' , '.wav' , '.flac' , '.opus' ] . freeze
3132
3233 IMAGE_MIME_TYPES = [ 'image/jpeg' , 'image/png' , 'image/gif' , 'image/webp' ] . freeze
3334 VIDEO_MIME_TYPES = [ 'video/webm' , 'video/mp4' , 'video/quicktime' ] . freeze
3435 VIDEO_CONVERTIBLE_MIME_TYPES = [ 'video/webm' , 'video/quicktime' ] . freeze
36+ AUDIO_MIME_TYPES = [ 'audio/wave' , 'audio/wav' , 'audio/x-wav' , 'audio/x-pn-wave' , 'audio/ogg' , 'audio/mpeg' , 'audio/webm' , 'audio/flac' ] . freeze
3537
3638 BLURHASH_OPTIONS = {
3739 x_comp : 4 ,
@@ -65,6 +67,13 @@ class MediaAttachment < ApplicationRecord
6567 } ,
6668 } . freeze
6769
70+ AUDIO_STYLES = {
71+ original : {
72+ format : 'ogg' ,
73+ convert_options : { } ,
74+ } ,
75+ } . freeze
76+
6877 VIDEO_FORMAT = {
6978 format : 'mp4' ,
7079 convert_options : {
@@ -83,6 +92,11 @@ class MediaAttachment < ApplicationRecord
8392 } ,
8493 } . freeze
8594
95+ VIDEO_CONVERTED_STYLES = {
96+ small : VIDEO_STYLES [ :small ] ,
97+ original : VIDEO_FORMAT ,
98+ } . freeze
99+
86100 IMAGE_LIMIT = 15 . megabytes
87101 VIDEO_LIMIT = 40 . megabytes
88102
@@ -95,9 +109,9 @@ class MediaAttachment < ApplicationRecord
95109 processors : -> ( f ) { file_processors f } ,
96110 convert_options : { all : '-quality 90 -strip' }
97111
98- validates_attachment_content_type :file , content_type : IMAGE_MIME_TYPES + VIDEO_MIME_TYPES
99- validates_attachment_size :file , less_than : IMAGE_LIMIT , unless : :video_or_gifv ?
100- validates_attachment_size :file , less_than : VIDEO_LIMIT , if : :video_or_gifv ?
112+ validates_attachment_content_type :file , content_type : IMAGE_MIME_TYPES + VIDEO_MIME_TYPES + AUDIO_MIME_TYPES
113+ validates_attachment_size :file , less_than : IMAGE_LIMIT , unless : :larger_media_format ?
114+ validates_attachment_size :file , less_than : VIDEO_LIMIT , if : :larger_media_format ?
101115 remotable_attachment :file , VIDEO_LIMIT
102116
103117 include Attachmentable
@@ -120,8 +134,12 @@ def needs_redownload?
120134 file . blank? && remote_url . present?
121135 end
122136
123- def video_or_gifv?
124- video? || gifv?
137+ def larger_media_format?
138+ video? || gifv? || audio?
139+ end
140+
141+ def audio_or_video?
142+ audio? || video?
125143 end
126144
127145 def to_param
@@ -156,28 +174,24 @@ class << self
156174 private
157175
158176 def file_styles ( f )
159- if f . instance . file_content_type == 'image/gif'
160- {
161- small : IMAGE_STYLES [ :small ] ,
162- original : VIDEO_FORMAT ,
163- }
164- elsif IMAGE_MIME_TYPES . include? f . instance . file_content_type
177+ if f . instance . file_content_type == 'image/gif' || VIDEO_CONVERTIBLE_MIME_TYPES . include? ( f . instance . file_content_type )
178+ VIDEO_CONVERTED_STYLES
179+ elsif IMAGE_MIME_TYPES . include? ( f . instance . file_content_type )
165180 IMAGE_STYLES
166- elsif VIDEO_CONVERTIBLE_MIME_TYPES . include? ( f . instance . file_content_type )
167- {
168- small : VIDEO_STYLES [ :small ] ,
169- original : VIDEO_FORMAT ,
170- }
171- else
181+ elsif VIDEO_MIME_TYPES . include? ( f . instance . file_content_type )
172182 VIDEO_STYLES
183+ else
184+ AUDIO_STYLES
173185 end
174186 end
175187
176188 def file_processors ( f )
177189 if f . file_content_type == 'image/gif'
178190 [ :gif_transcoder , :blurhash_transcoder ]
179- elsif VIDEO_MIME_TYPES . include? f . file_content_type
191+ elsif VIDEO_MIME_TYPES . include? ( f . file_content_type )
180192 [ :video_transcoder , :blurhash_transcoder ]
193+ elsif AUDIO_MIME_TYPES . include? ( f . file_content_type )
194+ [ :transcoder ]
181195 else
182196 [ :lazy_thumbnail , :blurhash_transcoder ]
183197 end
@@ -202,7 +216,15 @@ def prepare_description
202216 end
203217
204218 def set_type_and_extension
205- self . type = VIDEO_MIME_TYPES . include? ( file_content_type ) ? :video : :image
219+ self . type = begin
220+ if VIDEO_MIME_TYPES . include? ( file_content_type )
221+ :video
222+ elsif AUDIO_MIME_TYPES . include? ( file_content_type )
223+ :audio
224+ else
225+ :image
226+ end
227+ end
206228 end
207229
208230 def set_meta
@@ -245,7 +267,7 @@ def video_metadata(file)
245267 frame_rate : movie . frame_rate ,
246268 duration : movie . duration ,
247269 bitrate : movie . bitrate ,
248- }
270+ } . compact
249271 end
250272
251273 def reset_parent_cache
0 commit comments