paperclip-ffmpeg 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in paperclip-ffmpeg.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,50 @@
1
+ Paperclip FFMPEG
2
+ ================
3
+
4
+ Adding video handling to Paperclip via ffmpeg.
5
+ This gem has been tested under Linux and Mac OS X, YMMV under Windows.
6
+
7
+ Requirements
8
+ ------------
9
+
10
+ FFMPEG must be installed and Paperclip must have access to it. To ensure
11
+ that it does, on your command line, run `which ffmpeg`.
12
+ This will give you the path where ffmpeg is installed. For
13
+ example, it might return `/usr/local/bin/ffmpeg`.
14
+
15
+ Then, in your environment config file, let Paperclip know to look there by adding that
16
+ directory to its path.
17
+
18
+ In development mode, you might add this line to `config/environments/development.rb)`:
19
+
20
+ Paperclip.options[:command_path] = "/usr/local/bin/"
21
+
22
+ Installation
23
+ ------------
24
+
25
+ Include the gem in your Gemfile:
26
+
27
+ gem "paperclip-ffmpeg"
28
+
29
+ Quick Start
30
+ -----------
31
+
32
+ In your model:
33
+
34
+ class User < ActiveRecord::Base
35
+ has_attached_file :avatar, :styles => {
36
+ :medium => { :geometry => "640x480", :format => 'flv' }
37
+ :thumb => { :geometry => "100x100#", :format => 'jpg', :time => 10 }
38
+ }, :processors => [:ffmpeg]
39
+ end
40
+
41
+ This will produce:
42
+
43
+ 1. A transcoded +:medium+ FLV file with the requested dimensions if they will match the aspect ratio of the original file, otherwise, width will be maintained and height will be recalculated to keep the original aspect ration.
44
+ 2. A screenshot +:thumb+ with the requested dimensions regardless of the aspect ratio.
45
+
46
+
47
+ License
48
+ -------
49
+
50
+ Licensed under BSD license.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,113 @@
1
+ require "paperclip"
2
+ module Paperclip
3
+ class Ffmpeg < Processor
4
+ attr_accessor :geometry, :format, :whiny, :convert_options
5
+
6
+ # Creates a Video object set to work on the +file+ given. It
7
+ # will attempt to transcode the video into one defined by +target_geometry+
8
+ # which is a "WxH"-style string. +format+ should be specified.
9
+ # Video transcoding will raise no errors unless
10
+ # +whiny+ is true (which it is, by default. If +convert_options+ is
11
+ # set, the options will be appended to the convert command upon video transcoding
12
+ def initialize file, options = {}, attachment = nil
13
+ @convert_options = {
14
+ :ab => '46k',
15
+ :ac => 2,
16
+ :ar => 44100,
17
+ :b => '1200k',
18
+ :deinterlace => nil,
19
+ :r => 25,
20
+ :y => nil,
21
+ }
22
+ @convert_options.reverse_merge! options[:convert_options] unless options[:convert_options].nil? || options[:convert_options].class != Hash
23
+
24
+ @geometry = options[:geometry]
25
+ @file = file
26
+ @keep_aspect = @geometry.nil? || @geometry[-1,1] != '#'
27
+ @whiny = options[:whiny].nil? ? true : options[:whiny]
28
+ @format = options[:format]
29
+ @time = options[:time].nil? ? 3 : options[:time]
30
+ @current_format = File.extname(@file.path)
31
+ @basename = File.basename(@file.path, @current_format)
32
+ @meta = identify
33
+ end
34
+ # Performs the transcoding of the +file+ into a thumbnail/video. Returns the Tempfile
35
+ # that contains the new image/video.
36
+ def make
37
+ src = @file
38
+ dst = Tempfile.new([@basename, @format ? ".#{@format}" : ''])
39
+ dst.binmode
40
+
41
+ begin
42
+ parameters = []
43
+ parameters << '-y'
44
+ # Add geometry
45
+ if @geometry
46
+ if @geometry =~ /(\d*)x(\d*)/
47
+ target_width = $1
48
+ target_height = $2
49
+ end
50
+ current_geometry = @meta[:size].split('x')
51
+ current_width = current_geometry[0]
52
+ current_height = current_geometry[1]
53
+ if @keep_aspect
54
+ # Correct size to keep aspect
55
+ if current_width.to_i > target_width.to_i
56
+ # Scaling down
57
+ width = target_width.to_i
58
+ height = (width.to_f / (@meta[:aspect].to_f)).to_i
59
+ else
60
+ # TODO: Padding
61
+ end
62
+ @convert_options[:s] = "#{width.to_i}x#{height.to_i}" unless width.nil? || height.nil?
63
+ else
64
+ @convert_options[:s] = @geometry
65
+ end
66
+ end
67
+ # Add format
68
+ case @format
69
+ when 'jpg', 'jpeg', 'png', 'gif' # Images
70
+ @convert_options[:f] = 'image2'
71
+ @convert_options[:ss] = @time
72
+ @convert_options[:vframes] = 1
73
+ end
74
+
75
+ parameters << '-i :source'
76
+ parameters << @convert_options.map { |k,v| "-#{k.to_s} #{v} "}
77
+ parameters << ":dest"
78
+
79
+ parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
80
+ success = Paperclip.run("ffmpeg", parameters, :source => "#{File.expand_path(src.path)}", :dest => File.expand_path(dst.path))
81
+
82
+ rescue PaperclipCommandLineError => e
83
+ raise PaperclipError, "error while processing video for #{@basename}." if @whiny
84
+ end
85
+
86
+ dst
87
+ end
88
+
89
+ def identify
90
+ meta = {}
91
+ command = "ffmpeg -i #{File.expand_path(@file.path)} 2>&1"
92
+ Paperclip.log(command)
93
+ ffmpeg = IO.popen(command)
94
+ ffmpeg.each("\r") do |line|
95
+ if line =~ /((\d*)\s.?)fps,/
96
+ meta[:fps] = $1.to_i
97
+ end
98
+ # Matching lines like:
99
+ # Video: mjpeg, yuvj420p, 640x480 [PAR 72:72 DAR 4:3], 10301 kb/s, 30 fps, 30 tbr, 600 tbn, 600 tbc
100
+ if line =~ /Video:(\s.?(\w*),\s.?(\w*),\s(\d*x\d*)\s.?PAR\s.?(\d*):(\d*)\s.?DAR\s(\d*):(\d*))/
101
+ meta[:size] = $4
102
+ meta[:aspect] = $7.to_f / $8.to_f
103
+ end
104
+ # Matching Duration: 00:01:31.66, start: 0.000000, bitrate: 10404 kb/s
105
+ if line =~ /Duration:(\s.?(\d*):(\d*):(\d*\.\d*))/
106
+ meta[:length] = $2.to_s + ":" + $3.to_s + ":" + $4.to_s
107
+ meta[:frames] = ($4.to_i + ($3.to_i * 60) + ($2.to_i * 60 * 60)) * meta[:fps]
108
+ end
109
+ end
110
+ meta
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,5 @@
1
+ module Paperclip
2
+ module Ffmpeg
3
+ VERSION = "0.2.1"
4
+ end
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "paperclip-ffmpeg/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "paperclip-ffmpeg"
7
+ s.version = Paperclip::Ffmpeg::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Omar Abdel-Wahab"]
10
+ s.email = ["owahab@gmail.com"]
11
+ s.homepage = "http://github.com/owahab/paperclip-ffmpeg"
12
+ s.summary = %q{Process your attachments with FFMPEG}
13
+ s.description = %q{Process your attachments with FFMPEG}
14
+
15
+ s.rubyforge_project = "paperclip-ffmpeg"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency('paperclip', '>=2.3.8')
23
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paperclip-ffmpeg
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.2.1
6
+ platform: ruby
7
+ authors:
8
+ - Omar Abdel-Wahab
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-01 00:00:00 +02:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: paperclip
18
+ prerelease: false
19
+ requirement: &id001 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 2.3.8
25
+ type: :runtime
26
+ version_requirements: *id001
27
+ description: Process your attachments with FFMPEG
28
+ email:
29
+ - owahab@gmail.com
30
+ executables: []
31
+
32
+ extensions: []
33
+
34
+ extra_rdoc_files: []
35
+
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - README.md
40
+ - Rakefile
41
+ - lib/paperclip-ffmpeg.rb
42
+ - lib/paperclip-ffmpeg/version.rb
43
+ - paperclip-ffmpeg.gemspec
44
+ has_rdoc: true
45
+ homepage: http://github.com/owahab/paperclip-ffmpeg
46
+ licenses: []
47
+
48
+ post_install_message:
49
+ rdoc_options: []
50
+
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ requirements: []
66
+
67
+ rubyforge_project: paperclip-ffmpeg
68
+ rubygems_version: 1.5.2
69
+ signing_key:
70
+ specification_version: 3
71
+ summary: Process your attachments with FFMPEG
72
+ test_files: []
73
+