WebM support

This commit is contained in:
Toks 2014-06-30 13:21:07 -04:00
parent 1a2517634a
commit a84850c094
8 changed files with 87 additions and 18 deletions

View File

@ -43,6 +43,7 @@ gem 'statistics2'
gem 'capistrano'
gem 'capistrano-ext'
gem 'radix62', '~> 1.0.1'
gem 'streamio-ffmpeg'
# needed for looser jpeg header compat
gem 'ruby-imagespec', :require => "image_spec", :git => "https://github.com/r888888888/ruby-imagespec.git", :branch => "exif-fixes"

View File

@ -27,7 +27,7 @@ class AmazonBackup < ActiveRecord::Base
AWS::S3::S3Object.store(File.basename(post.file_path), open(post.file_path, "rb"), Danbooru.config.amazon_s3_bucket_name, "Content-MD5" => base64_md5)
end
if post.is_image? && File.exists?(post.preview_file_path)
if post.has_preview? && File.exists?(post.preview_file_path)
AWS::S3::S3Object.store("preview/#{post.md5}.jpg", open(post.preview_file_path, "rb"), Danbooru.config.amazon_s3_bucket_name)
end

View File

@ -44,13 +44,13 @@ class Post < ActiveRecord::Base
module FileMethods
def distribute_files
RemoteFileManager.new(file_path).distribute
RemoteFileManager.new(preview_file_path).distribute if is_image?
RemoteFileManager.new(preview_file_path).distribute if has_preview?
RemoteFileManager.new(large_file_path).distribute if has_large?
end
def delete_remote_files
RemoteFileManager.new(file_path).delete
RemoteFileManager.new(preview_file_path).delete if is_image?
RemoteFileManager.new(preview_file_path).delete if has_preview?
RemoteFileManager.new(large_file_path).delete if has_large?
end
@ -93,7 +93,7 @@ class Post < ActiveRecord::Base
end
def preview_file_url
if !is_image?
if !has_preview?
return "/images/download-preview.png"
end
@ -127,6 +127,18 @@ class Post < ActiveRecord::Base
def is_flash?
file_ext =~ /swf/i
end
def is_video?
file_ext =~ /webm/i
end
def has_preview?
is_image? || is_video?
end
def has_dimensions?
is_image? || is_flash? || is_video?
end
end
module ImageMethods

View File

@ -51,7 +51,7 @@ class Upload < ActiveRecord::Base
def validate_file_content_type
unless is_valid_content_type?
raise "invalid content type (only JPEG, PNG, GIF, and SWF files are allowed)"
raise "invalid content type (only JPEG, PNG, GIF, SWF, and WebM files are allowed)"
end
end
@ -72,6 +72,18 @@ class Upload < ActiveRecord::Base
return false
end
end
def validate_no_audio
if is_video? && video.audio_channels.present?
raise "video must not have audio channels"
end
end
def validate_video_duration
if is_video? && video.duration > 120
raise "video must not be longer than 2 minutes"
end
end
end
module ConversionMethods
@ -90,6 +102,8 @@ class Upload < ActiveRecord::Base
calculate_hash(file_path)
validate_md5_uniqueness
validate_md5_confirmation
validate_no_audio
validate_video_duration
calculate_file_size(file_path)
if has_dimensions?
calculate_dimensions(file_path)
@ -151,15 +165,23 @@ class Upload < ActiveRecord::Base
end
def is_image?
["jpg", "gif", "png"].include?(file_ext)
%w(jpg gif png).include?(file_ext)
end
def is_flash?
%w(swf).include?(file_ext)
end
def is_video?
%w(webm).include?(file_ext)
end
end
module ResizerMethods
def generate_resizes(source_path)
if is_image?
generate_resize_for(Danbooru.config.small_image_width, Danbooru.config.small_image_width, source_path, 85)
generate_resize_for(Danbooru.config.large_image_width, nil, source_path) if image_width > Danbooru.config.large_image_width
generate_resize_for(Danbooru.config.small_image_width, Danbooru.config.small_image_width, source_path, 85)
if is_image? && image_width > Danbooru.config.large_image_width
generate_resize_for(Danbooru.config.large_image_width, nil, source_path)
end
end
@ -168,29 +190,45 @@ class Upload < ActiveRecord::Base
raise Error.new("file not found")
end
Danbooru.resize(source_path, resized_file_path_for(width), width, height, quality)
if is_image?
Danbooru.resize(source_path, resized_file_path_for(width), width, height, quality)
elsif is_video?
dimension_ratio = image_width.to_f / image_height
if dimension_ratio > 1
height = (width / dimension_ratio).to_i
else
width = (height * dimension_ratio).to_i
end
video.screenshot(resized_file_path_for(width), {:seek_time => 0, :resolution => "#{width}x#{height}"})
FileUtils.chmod(0664, resized_file_path_for(width))
end
end
end
module DimensionMethods
# Figures out the dimensions of the image.
def calculate_dimensions(file_path)
File.open(file_path, "rb") do |file|
image_size = ImageSpec.new(file)
self.image_width = image_size.width
self.image_height = image_size.height
if is_video?
self.image_width = video.width
self.image_height = video.height
else
File.open(file_path, "rb") do |file|
image_size = ImageSpec.new(file)
self.image_width = image_size.width
self.image_height = image_size.height
end
end
end
# Does this file have image dimensions?
def has_dimensions?
%w(jpg gif png swf).include?(file_ext)
%w(jpg gif png swf webm).include?(file_ext)
end
end
module ContentTypeMethods
def is_valid_content_type?
file_ext =~ /jpg|gif|png|swf/
file_ext =~ /jpg|gif|png|swf|webm/
end
def content_type_to_file_ext(content_type)
@ -207,6 +245,9 @@ class Upload < ActiveRecord::Base
when "application/x-shockwave-flash"
"swf"
when "video/webm"
"webm"
else
"bin"
end
@ -226,6 +267,9 @@ class Upload < ActiveRecord::Base
when /^CWS/, /^FWS/, /^ZWS/
"application/x-shockwave-flash"
when /^\x1a\x45\xdf\xa3/
"video/webm"
else
"application/octet-stream"
end
@ -320,6 +364,12 @@ class Upload < ActiveRecord::Base
end
end
module VideoMethods
def video
@video ||= FFMPEG::Movie.new(file_path)
end
end
module SearchMethods
def uploaded_by(user_id)
where("uploader_id = ?", user_id)
@ -381,6 +431,7 @@ class Upload < ActiveRecord::Base
include CgiFileMethods
include StatusMethods
include UploaderMethods
include VideoMethods
extend SearchMethods
include ApiMethods

View File

@ -155,6 +155,8 @@ class PostPresenter < Presenter
if @post.is_flash?
template.render("posts/partials/show/flash", :post => @post)
elsif @post.is_video?
template.render("posts/partials/show/video", :post => @post)
elsif !@post.is_image?
template.render("posts/partials/show/download", :post => @post)
elsif @post.is_image?

View File

@ -38,7 +38,7 @@
<li>
<strong>Size:</strong>
<%= number_to_human_size(post.file_size) %>
<% if post.is_image? %>
<% if post.has_dimensions? %>
(<%= post.image_width %>x<%= post.image_height %>)
<% end %>
</li>

View File

@ -7,7 +7,7 @@
<% end %>
<li>
Size: <%= link_to_if post.visible?, number_to_human_size(post.file_size), post.file_url %>
<% if post.is_image? %>
<% if post.has_dimensions? %>
(<%= post.image_width %>x<%= post.image_height %>)
<% end %>
</li>

View File

@ -0,0 +1,3 @@
<%= content_tag(:video, nil, :width => post.image_width, :height => post.image_height, :autoplay => true, :loop => true, :src => post.file_url) %>
<p><%= link_to "Save this video (right click and save)", post.file_url %></p>