2012-07-23 61 views
6

我正在用paperclip gem和s3存储的帮助将用户上传的视频添加到我的RoRs站点。出于某种原因,我无法弄清楚,无论何时用户上传mp4文件,s3都会将该文件的内容类型设置为application/mp4而不是video/mp4设置s3上的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文件修改的轨道,以确定MP4文件为“视频/ MP4”的方式。如果我能做到,哪种方式最好。

感谢您的帮助

+0

曾与.SVG上传了类似的问题。这解决了我的问题::s3_headers => {“Content-Type”=>“image/svg + xml”} – DavidMann10k 2013-03-02 01:17:04

回答

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

我做了以下内容:

... 
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 
... 
相关问题