Rails和Paperclip:处理多种文件类型(视频和图片)的上传

3
我正在学习Rails,过去的两天里一直在尝试通过使用Paperclip上传视频和图片到同一个模型中。我感觉已经用尽了所有资源来寻找答案,但是没有找到任何有助于我将正确的样式应用于正确的文件类型的东西。
以下是我的Image模型(注意:我从一个Image模型和一个avatar属性开始。我正在扩展它的用途,所以请不要被它的名称所迷惑)。
class Image < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true

  has_attached_file :avatar, 
    if: :is_image_type?, styles: {:large => "750x750>", :medium => "300x300#", :thumb => "100x100#" }, :default_url => "no_image.png",
    if: :is_video_type?, :styles =>  {
        :medium => { :geometry => "640x480", :format => 'flv' },
        :thumb => { :geometry => "100x100#", :format => 'jpg', :time => 10 }
      }, :processors => [:transcoder]

  validates_attachment_content_type :avatar,
    :content_type => ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', "video/mp4", "video/m4v", "video/mpeg"]

  def is_image_type? 
    content_type = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif']
    # /\Aimage\/.*\Z/
  end 

  def is_video_type? 
    content_type = ["video/mp4", "video/m4v", "video/mpeg"]
  end

end

本质上,我正在尝试弄清楚如何使样式适用于相应的文件类型。如果是视频,我希望它被视为视频,如果是图像,则视为图像。

内容验证运行良好,一旦运行良好,我将更改它以包括所有图像格式和所有视频格式。

目标 总之,我的目标是能够有一个文件上传字段,用户可以上传多个文件和多种文件类型,包括图像、视频、音频、PDF和其他文件类型。

然后,我将使用“content_type”字段来提取我想要在站点不同区域显示的文件类型。

如果这种使用单一模型的方法不足,请指出更好的方法。

我正在使用'paperclip-av-transcoder' gem处理视频。

再次说明,我正在学习Rails,如果有什么不清楚的地方,我很乐意澄清和修改。

非常感谢。

1个回答

4
所以我最终找出了问题。我的代码(基本上)是正确的,尽管我将在此处粘贴最终代码。
问题是因为我没有在我的计算机上安装编码器,所以它无法正确处理。
因此,对于任何想要上传视频并像我一样是新手的人,您需要安装类似FFmpeg这样的工具来处理上传的视频。
我使用了Homebrew和这个教程,它非常容易:https://trac.ffmpeg.org/wiki/CompilationGuide/MacOSX 这是我的最终代码版本:
 class Image < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true



  # Apply styling appropriate for this file
  has_attached_file :avatar, styles: lambda { |a| a.instance.check_file_type}, :default_url => "no_image.png"
  validates_attachment_content_type :avatar, :content_type => /.*/


  # The path of the image that will be shown while the file is loading
  def processing_image_path(image_name)
    "/assets/" + Rails.application.assets.find_asset(image_name).digest_path
  end  


  process_in_background :avatar, processing_image_url: lambda { |a| a.instance.processing_image_path("dad.jpg")}


  # IMPORTANT! The ffmpeg library has to added to the server machine. 
  # It can be uploaded from the official website https://www.ffmpeg.org/
  def check_file_type
    if is_image_type?
      {:large => "750x750>", :medium => "300x300#", :thumb => "100x100#" }
    elsif is_video_type?
      {
          :medium => { :geometry => "300x300#", :format => 'jpg'},
          :video => {:geometry => "640x360#", :format => 'mp4', :processors => [:transcoder]}
      }
    elsif is_audio_type?
      {
        :audio => {
          :format => "mp3", :processors => [:transcoder]
        }
      }
     # avatar_file_name = self.basename(:avatar_file_name, self.extname(:avatar_file_name))
    else
      {}
    end
  end



  # Method returns true if file's content type contains word 'image', overwise false
  def is_image_type?
    avatar_content_type =~ %r(image)
  end

  # Method returns true if file's content type contains word 'video', overwise false
  def is_video_type?
    avatar_content_type =~ %r(video)
  end

  # Method returns true if file's content type contains word 'audio', overwise false
  def is_audio_type?
    avatar_content_type =~ /\Aaudio\/.*\Z/
  end

end

我仍在添加不同的数据类型,并将在完成时特别允许这些数据类型进行验证,但这应该可以向您展示我所做的事情,您可以在此基础上构建。

希望这对其他人有所帮助,而不仅仅是对我有用!


Jake,我正在尝试这个,但是假设我不事先验证数据,因为整个系统都是内部的。我想使用Active Admin直接上传文件,而不验证内容类型-图像/音频/视频,并将S3 URL保存在数据库中。您建议使用什么工具?有哪些相关链接可以提供帮助? - akshaymani

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