2012-07-23 127 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 
...