carrierwave-video 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/README.rdoc +32 -2
- data/lib/carrierwave-video/version.rb +1 -1
- data/lib/carrierwave/video.rb +28 -0
- data/lib/carrierwave/video/ffmpeg_options.rb +1 -1
- data/lib/carrierwave/video/ffmpeg_theora.rb +41 -0
- data/spec/lib/carrierwave_video_spec.rb +52 -0
- data/spec/lib/ffmpeg_theora_spec.rb +35 -0
- metadata +84 -58
data/.gitignore
CHANGED
data/README.rdoc
CHANGED
|
@@ -59,7 +59,37 @@ They will be called with the parameters sent to process.
|
|
|
59
59
|
Logging:
|
|
60
60
|
logger: :method #returns object that behaves like Logger
|
|
61
61
|
|
|
62
|
-
=
|
|
62
|
+
= OGG/OGV & Theora
|
|
63
|
+
|
|
64
|
+
If you want to transcode to OGV format, I recommend using ffmpeg2theora. It works better.
|
|
65
|
+
Support for this is built into this gem, but it is not as mature as the transcoding
|
|
66
|
+
support built into the streamio-ffmpeg gem. You will need to install the ffmpeg2theora binary.
|
|
67
|
+
http://v2v.cc/~j/ffmpeg2theora/
|
|
68
|
+
|
|
69
|
+
ffmpeg2theora does not have watermark support, so if you want a watermark, I recommend
|
|
70
|
+
building the theora file off previous version. I have not built in resolution or any other options
|
|
71
|
+
as I am just creating mine from a previous version (in the correct size/with watermark).
|
|
72
|
+
If you need support for this it shouldn't be too hard to add. (Use streamio-ffmpeg for inspiration)
|
|
73
|
+
|
|
74
|
+
Example:
|
|
75
|
+
|
|
76
|
+
class VideoUploader < CarrierWave::Uploader::Base
|
|
77
|
+
include CarrierWave::VideoConverter
|
|
78
|
+
|
|
79
|
+
version :mp4 do
|
|
80
|
+
process :encode_video => [:mp4, {...}]
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
version :ogv, :from_version => :mp4 do
|
|
84
|
+
process :encode_ogv => [{ logger: logger_method, callbacks: {...} }]
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
You do not need to pass in the format to the encode_ogv method (as it is always ogv).
|
|
89
|
+
The only options that do work are logger and callbacks. Others will be ignored.
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
= Upcoming and notes
|
|
63
93
|
|
|
64
|
-
* screengrabs
|
|
65
94
|
* ffmpeg gives a confusing error if watermark file does not exist, raise in ruby
|
|
95
|
+
* error handling/checking (extract from streamio-ffmpeg gem's transcoder) for encode_ogv
|
data/lib/carrierwave/video.rb
CHANGED
|
@@ -1,14 +1,42 @@
|
|
|
1
1
|
require 'streamio-ffmpeg'
|
|
2
2
|
require 'carrierwave'
|
|
3
3
|
require 'carrierwave/video/ffmpeg_options'
|
|
4
|
+
require 'carrierwave/video/ffmpeg_theora'
|
|
4
5
|
|
|
5
6
|
module CarrierWave
|
|
6
7
|
module Video
|
|
7
8
|
extend ActiveSupport::Concern
|
|
9
|
+
def self.ffmpeg2theora_binary=(bin)
|
|
10
|
+
@ffmpeg2theora = bin
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.ffmpeg2theora_binary
|
|
14
|
+
@ffmpeg2theora.nil? ? 'ffmpeg2theora' : @ffmpeg2theora
|
|
15
|
+
end
|
|
16
|
+
|
|
8
17
|
module ClassMethods
|
|
9
18
|
def encode_video(target_format, options={})
|
|
10
19
|
process encode_video: [target_format, options]
|
|
11
20
|
end
|
|
21
|
+
|
|
22
|
+
def encode_ogv(opts={})
|
|
23
|
+
process encode_ogv: [opts]
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def encode_ogv(opts)
|
|
29
|
+
# move upload to local cache
|
|
30
|
+
cache_stored_file! if !cached?
|
|
31
|
+
|
|
32
|
+
tmp_path = File.join( File.dirname(current_path), "tmpfile.ogv" )
|
|
33
|
+
@options = CarrierWave::Video::FfmpegOptions.new('ogv', opts)
|
|
34
|
+
|
|
35
|
+
with_trancoding_callbacks do
|
|
36
|
+
transcoder = CarrierWave::Video::FfmpegTheora.new(current_path, tmp_path)
|
|
37
|
+
transcoder.run(@options.logger(model))
|
|
38
|
+
File.rename tmp_path, current_path
|
|
39
|
+
end
|
|
12
40
|
end
|
|
13
41
|
|
|
14
42
|
def encode_video(format, opts={})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module CarrierWave
|
|
2
|
+
module Video
|
|
3
|
+
class FfmpegTheora
|
|
4
|
+
attr_reader :input_path, :output_path
|
|
5
|
+
def initialize(input_file_path, output_file_path)
|
|
6
|
+
@input_path = input_file_path
|
|
7
|
+
@output_path = output_file_path
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def run(logger=nil)
|
|
11
|
+
cmd = "#{CarrierWave::Video.ffmpeg2theora_binary} #{input_path} -o #{output_path}"
|
|
12
|
+
logger.info("Running....#{cmd}") if logger
|
|
13
|
+
outputs = []
|
|
14
|
+
exit_code = nil
|
|
15
|
+
|
|
16
|
+
Open3.popen3(cmd) do |stdin, stdout, stderr, wait_thr|
|
|
17
|
+
stderr.each("r") do |line|
|
|
18
|
+
outputs << line
|
|
19
|
+
end
|
|
20
|
+
exit_code = wait_thr.value
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
handle_exit_code(exit_code, outputs, logger)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
def handle_exit_code(exit_code, outputs, logger)
|
|
28
|
+
return unless logger
|
|
29
|
+
if exit_code == 0
|
|
30
|
+
logger.info("Success!")
|
|
31
|
+
else
|
|
32
|
+
outputs.each do |output|
|
|
33
|
+
logger.error(output)
|
|
34
|
+
end
|
|
35
|
+
logger.error("Failure!")
|
|
36
|
+
end
|
|
37
|
+
exit_code
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -26,6 +26,18 @@ describe CarrierWave::Video do
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
describe ".encode_ogv" do
|
|
30
|
+
it "processes the model" do
|
|
31
|
+
TestVideoUploader.should_receive(:process).with(encode_ogv: [:opts])
|
|
32
|
+
TestVideoUploader.encode_ogv(:opts)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "does not require options" do
|
|
36
|
+
TestVideoUploader.should_receive(:process).with(encode_ogv: [{}])
|
|
37
|
+
TestVideoUploader.encode_ogv
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
29
41
|
describe "#encode_video" do
|
|
30
42
|
let(:format) { 'webm' }
|
|
31
43
|
let(:movie) { mock }
|
|
@@ -167,4 +179,44 @@ describe CarrierWave::Video do
|
|
|
167
179
|
end
|
|
168
180
|
end
|
|
169
181
|
end
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
describe "#encode_ogv" do
|
|
185
|
+
let(:movie) { mock }
|
|
186
|
+
let(:output_path) { 'video/path/tmpfile.ogv' }
|
|
187
|
+
let(:movie_path) { 'video/path/input.mov' }
|
|
188
|
+
let(:logger) { mock(:logger) }
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
before do
|
|
192
|
+
converter.model.stub(:logger).and_return(logger)
|
|
193
|
+
File.should_receive(:rename)
|
|
194
|
+
converter.stub(:current_path).and_return('video/path/input.mov')
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
context "no options set" do
|
|
198
|
+
it "calls transcode with correct format options" do
|
|
199
|
+
transcoder = mock(:transcoder)
|
|
200
|
+
CarrierWave::Video::FfmpegTheora.should_receive(:new).with(movie_path, output_path).and_return(transcoder)
|
|
201
|
+
transcoder.should_receive(:run)
|
|
202
|
+
|
|
203
|
+
converter.encode_ogv({})
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
context "with logger set" do
|
|
208
|
+
before do
|
|
209
|
+
converter.model.stub(:logger).and_return(logger)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "calls transcode with correct format options and passes logger to transcoder" do
|
|
213
|
+
transcoder = mock(:transcoder)
|
|
214
|
+
CarrierWave::Video::FfmpegTheora.should_receive(:new).with(movie_path, output_path).and_return(transcoder)
|
|
215
|
+
transcoder.should_receive(:run).with(logger)
|
|
216
|
+
|
|
217
|
+
converter.encode_ogv({logger: :logger})
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
170
222
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe CarrierWave::Video::FfmpegTheora do
|
|
4
|
+
describe "run" do
|
|
5
|
+
let(:input_file_path) { '/tmp/file.mov' }
|
|
6
|
+
let(:output_file_path) { '/tmp/file.ogv' }
|
|
7
|
+
let(:binary) { 'bunnery' }
|
|
8
|
+
|
|
9
|
+
let(:transcoder) { CarrierWave::Video::FfmpegTheora.new(input_file_path, output_file_path) }
|
|
10
|
+
|
|
11
|
+
before do
|
|
12
|
+
CarrierWave::Video.ffmpeg2theora_binary = binary
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should run the ffmpeg2theora binary" do
|
|
16
|
+
command = "#{binary} #{input_file_path} -o #{output_file_path}"
|
|
17
|
+
Open3.should_receive(:popen3).with(command)
|
|
18
|
+
|
|
19
|
+
transcoder.run
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
context "given a logger" do
|
|
23
|
+
let(:logger) { mock(:logger) }
|
|
24
|
+
|
|
25
|
+
it "should run and log results" do
|
|
26
|
+
command = "#{binary} #{input_file_path} -o #{output_file_path}"
|
|
27
|
+
Open3.should_receive(:popen3).with(command)
|
|
28
|
+
logger.should_receive(:info).with("Running....#{command}")
|
|
29
|
+
logger.should_receive(:error).with("Failure!")
|
|
30
|
+
|
|
31
|
+
transcoder.run(logger)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
metadata
CHANGED
|
@@ -1,67 +1,84 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: carrierwave-video
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
prerelease: false
|
|
5
|
+
segments:
|
|
6
|
+
- 0
|
|
7
|
+
- 2
|
|
8
|
+
- 2
|
|
9
|
+
version: 0.2.2
|
|
6
10
|
platform: ruby
|
|
7
|
-
authors:
|
|
11
|
+
authors:
|
|
8
12
|
- rheaton
|
|
9
13
|
autorequire:
|
|
10
14
|
bindir: bin
|
|
11
15
|
cert_chain: []
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
|
|
17
|
+
date: 2012-06-25 00:00:00 -04:00
|
|
18
|
+
default_executable:
|
|
19
|
+
dependencies:
|
|
20
|
+
- !ruby/object:Gem::Dependency
|
|
15
21
|
name: rspec
|
|
16
|
-
|
|
22
|
+
prerelease: false
|
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
|
17
24
|
none: false
|
|
18
|
-
requirements:
|
|
19
|
-
- -
|
|
20
|
-
- !ruby/object:Gem::Version
|
|
21
|
-
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
segments:
|
|
29
|
+
- 0
|
|
30
|
+
version: "0"
|
|
22
31
|
type: :development
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
- !ruby/object:Gem::Dependency
|
|
32
|
+
version_requirements: *id001
|
|
33
|
+
- !ruby/object:Gem::Dependency
|
|
26
34
|
name: rake
|
|
27
|
-
|
|
35
|
+
prerelease: false
|
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
|
28
37
|
none: false
|
|
29
|
-
requirements:
|
|
30
|
-
- -
|
|
31
|
-
- !ruby/object:Gem::Version
|
|
32
|
-
|
|
38
|
+
requirements:
|
|
39
|
+
- - ">="
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
segments:
|
|
42
|
+
- 0
|
|
43
|
+
version: "0"
|
|
33
44
|
type: :development
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- !ruby/object:Gem::Dependency
|
|
45
|
+
version_requirements: *id002
|
|
46
|
+
- !ruby/object:Gem::Dependency
|
|
37
47
|
name: streamio-ffmpeg
|
|
38
|
-
|
|
48
|
+
prerelease: false
|
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
|
39
50
|
none: false
|
|
40
|
-
requirements:
|
|
41
|
-
- -
|
|
42
|
-
- !ruby/object:Gem::Version
|
|
43
|
-
|
|
51
|
+
requirements:
|
|
52
|
+
- - ">="
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
segments:
|
|
55
|
+
- 0
|
|
56
|
+
version: "0"
|
|
44
57
|
type: :runtime
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
- !ruby/object:Gem::Dependency
|
|
58
|
+
version_requirements: *id003
|
|
59
|
+
- !ruby/object:Gem::Dependency
|
|
48
60
|
name: carrierwave
|
|
49
|
-
|
|
61
|
+
prerelease: false
|
|
62
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
|
50
63
|
none: false
|
|
51
|
-
requirements:
|
|
52
|
-
- -
|
|
53
|
-
- !ruby/object:Gem::Version
|
|
54
|
-
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
segments:
|
|
68
|
+
- 0
|
|
69
|
+
version: "0"
|
|
55
70
|
type: :runtime
|
|
56
|
-
|
|
57
|
-
version_requirements: *70099877312940
|
|
71
|
+
version_requirements: *id004
|
|
58
72
|
description: Transcodes to html5-friendly videos.
|
|
59
|
-
email:
|
|
73
|
+
email:
|
|
60
74
|
- rachelmheaton@gmail.com
|
|
61
75
|
executables: []
|
|
76
|
+
|
|
62
77
|
extensions: []
|
|
78
|
+
|
|
63
79
|
extra_rdoc_files: []
|
|
64
|
-
|
|
80
|
+
|
|
81
|
+
files:
|
|
65
82
|
- .gitignore
|
|
66
83
|
- .travis.yml
|
|
67
84
|
- Gemfile
|
|
@@ -71,35 +88,44 @@ files:
|
|
|
71
88
|
- lib/carrierwave-video/version.rb
|
|
72
89
|
- lib/carrierwave/video.rb
|
|
73
90
|
- lib/carrierwave/video/ffmpeg_options.rb
|
|
91
|
+
- lib/carrierwave/video/ffmpeg_theora.rb
|
|
74
92
|
- spec/lib/carrierwave_video_spec.rb
|
|
93
|
+
- spec/lib/ffmpeg_theora_spec.rb
|
|
75
94
|
- spec/spec_helper.rb
|
|
76
|
-
|
|
95
|
+
has_rdoc: true
|
|
96
|
+
homepage: ""
|
|
77
97
|
licenses: []
|
|
98
|
+
|
|
78
99
|
post_install_message:
|
|
79
100
|
rdoc_options: []
|
|
80
|
-
|
|
101
|
+
|
|
102
|
+
require_paths:
|
|
81
103
|
- lib
|
|
82
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
83
105
|
none: false
|
|
84
|
-
requirements:
|
|
85
|
-
- -
|
|
86
|
-
- !ruby/object:Gem::Version
|
|
87
|
-
|
|
88
|
-
|
|
106
|
+
requirements:
|
|
107
|
+
- - ">="
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
segments:
|
|
110
|
+
- 0
|
|
111
|
+
version: "0"
|
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
113
|
none: false
|
|
90
|
-
requirements:
|
|
91
|
-
- -
|
|
92
|
-
- !ruby/object:Gem::Version
|
|
93
|
-
|
|
94
|
-
|
|
114
|
+
requirements:
|
|
115
|
+
- - ">="
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
segments:
|
|
118
|
+
- 0
|
|
119
|
+
version: "0"
|
|
120
|
+
requirements:
|
|
95
121
|
- ruby, version 1.9 or greater
|
|
96
|
-
- ffmpeg, version 0.10 or greater with libx256, libfaac, libtheora, libvorbid, libvpx
|
|
97
|
-
enabled
|
|
122
|
+
- ffmpeg, version 0.10 or greater with libx256, libfaac, libtheora, libvorbid, libvpx enabled
|
|
98
123
|
rubyforge_project: carrierwave-video
|
|
99
|
-
rubygems_version: 1.
|
|
124
|
+
rubygems_version: 1.3.7
|
|
100
125
|
signing_key:
|
|
101
126
|
specification_version: 3
|
|
102
127
|
summary: Carrierwave extension that uses ffmpeg to transcode videos.
|
|
103
|
-
test_files:
|
|
128
|
+
test_files:
|
|
104
129
|
- spec/lib/carrierwave_video_spec.rb
|
|
130
|
+
- spec/lib/ffmpeg_theora_spec.rb
|
|
105
131
|
- spec/spec_helper.rb
|