我正在借助paperclip gem和s3存储将用户上传的视频添加到我的RoRs网站。由于某些原因,我无法弄清楚,每当用户上传mp4文件时,s3将该文件的内容类型设置为application/mp4
而不是video/mp4
。
请注意,我在初始化文件中注册了mp4 mime类型:
Mime::Type.lookup_by_extension('mp4').to_s
=> "video/mp4"
以下是我的Post模型的相关部分:
has_attached_file :video,
:storage => :s3,
:s3_credentials => "#{Rails.root.to_s}/config/s3.yml",
:path => "/video/:id/:filename"
validates_attachment_content_type :video,
:content_type => ['video/mp4'],
:message => "Sorry, this site currently only supports MP4 video"
我的回形针和/或s3设置中缺少什么。
####更新#####
由于某些我不熟悉Rails的原因,我的mp4包含文件的默认mime类型如下:
MIME::Types.type_for("my_video.mp4").to_s
=> "[application/mp4, audio/mp4, video/mp4, video/vnd.objectvideo]"
因此,当回形针将mp4文件发送到s3时,它似乎将文件的mime类型识别为第一个默认值“application / mp4”。这就是为什么s3将文件标识为具有“application / mp4”的内容类型的原因。因为我想启用这些mp4文件的流式传输,我需要使用回形针将文件识别为具有mime类型的“video / mp4”。
有没有办法修改回形针(可能在before_post_process过滤器中)以允许这个,或者有没有办法通过init文件修改rails以将mp4文件识别为“video / mp4”。如果我能做到,哪种方式最好。
感谢您的帮助
答案 0 :(得分:7)
事实证明我需要在模型中设置默认的s3标头content_type。这对我来说不是最好的解决方案,因为在某些时候我可能会开始允许除mp4以外的视频容器。但它让我继续讨论下一个问题。
has_attached_file :video,
:storage => :s3,
:s3_credentials => "#{Rails.root.to_s}/config/s3.yml",
:path => "/video/:id/:filename",
:s3_headers => { "Content-Type" => "video/mp4" }
答案 1 :(得分:1)
我做了以下事情:
...
MIN_VIDEO_SIZE = 0.megabytes
MAX_VIDEO_SIZE = 2048.megabytes
VALID_VIDEO_CONTENT_TYPES = ["video/mp4", /\Avideo/] # Note: The regular expression /\Avideo/ will match anything that starts with "video"
has_attached_file :video, {
url: BASE_URL,
path: "video/:id_partition/:filename"
}
validates_attachment :video,
size: { in: MIN_VIDEO_SIZE..MAX_VIDEO_SIZE },
content_type: { content_type: VALID_VIDEO_CONTENT_TYPES }
before_validation :validate_video_content_type, on: :create
before_post_process :validate_video_content_type
def validate_video_content_type
if video_content_type == "application/octet-stream"
# Finds the first match and returns it.
# Alternatively you could use the ".select" method instead which would find all mime types that match any of the VALID_VIDEO_CONTENT_TYPES
mime_type = MIME::Types.type_for(video_file_name).find do |type|
type.to_s.match Regexp.union(VALID_VIDEO_CONTENT_TYPES)
end
self.video_content_type = mime_type.to_s unless mime_type.blank?
end
end
...