在S3上设置MP4文件的内容类型

8
我正在使用paperclip gem和s3存储将用户上传的视频添加到我的RoRs网站。但是,无论我如何尝试,每当用户上传mp4文件时,s3都会将该文件的content-type设置为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"

我在我的paperclip和/或s3设置中缺少什么?

####更新#####

由于某种原因,超出了我对Rails的了解范围,我的mp4文件的默认mime类型如下:

    MIME::Types.type_for("my_video.mp4").to_s
 => "[application/mp4, audio/mp4, video/mp4, video/vnd.objectvideo]" 

所以,当Paperclip将mp4文件发送到S3时,它似乎将文件的MIME类型识别为第一个默认值,“application/mp4”。这就是为什么S3将该文件标识为具有“application/mp4”的内容类型。因为我想启用这些mp4文件的流式传输,所以我需要让Paperclip将该文件识别为具有“video/mp4”的MIME类型。是否有一种方法可以修改Paperclip(可能在before_post_process过滤器中)来实现这一点,或者是否有一种方法通过init文件修改Rails以将mp4文件识别为“video/mp4”?如果我能做到任何一种方式,哪种方式最好。谢谢您的帮助。

遇到了与上传 .svg 文件类似的问题。以下代码解决了我的问题::s3_headers => { "Content-Type" => "image/svg+xml" } - DavidMann10k
2个回答

9
原来我需要在模型中设置一个默认的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" }

2

我做了以下事情:

...
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
...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接