videojoiner 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +1 -1
- data/README.rdoc +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/features/create_joined_video.feature +1 -0
- data/features/step_definitions/join_steps.rb +7 -2
- data/lib/videojoiner/joiner.rb +49 -28
- data/spec/joiner_spec.rb +26 -0
- data/spec/spec_helper.rb +15 -0
- data/videojoiner.gemspec +5 -3
- metadata +6 -4
data/.rspec
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--color
|
1
|
+
--color --format doc
|
data/README.rdoc
CHANGED
data/Rakefile
CHANGED
@@ -15,7 +15,7 @@ require 'jeweler'
|
|
15
15
|
Jeweler::Tasks.new do |gem|
|
16
16
|
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
17
|
gem.name = "videojoiner"
|
18
|
-
gem.homepage = "https://
|
18
|
+
gem.homepage = "https://github.com/rcpj/videojoiner"
|
19
19
|
gem.license = "GPLv3"
|
20
20
|
gem.summary = %Q{Gem to join sets of video files into a single video file using ffmpeg}
|
21
21
|
gem.description = %Q{This gem contains modules to create a single video file using a set of videos as input, via ffmpeg concat demuxer.}
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.3
|
@@ -9,6 +9,7 @@ Feature: Join a set of videos into a single file
|
|
9
9
|
And the video joiner job has finished
|
10
10
|
Then there should be a valid video file
|
11
11
|
And it should report all included videos as valid
|
12
|
+
And the destination video size should be correct
|
12
13
|
|
13
14
|
Scenario: Create a joined video file from a set of invalid videos
|
14
15
|
Given I have a set of invalid videos
|
@@ -8,7 +8,7 @@ end
|
|
8
8
|
|
9
9
|
When /^I create the video joiner job with id "(.*?)"$/ do | id |
|
10
10
|
@joiner_job = Videojoiner::FFMpeg::Joiner.new( id, @video_routes )
|
11
|
-
|
11
|
+
@joiner_job.create( { filename: "video_root/#{id}_#{Time.now.to_i}" } )
|
12
12
|
end
|
13
13
|
|
14
14
|
When /^the video joiner job has finished$/ do
|
@@ -25,7 +25,7 @@ end
|
|
25
25
|
|
26
26
|
Then /^it should report all included videos as valid$/ do
|
27
27
|
job = Videojoiner::FFMpeg::Joiner.fetch( @joiner_job.id )
|
28
|
-
job.video_list.each_value{ |value| value.should == "valid" }
|
28
|
+
job.video_list.each_value{ |value| value[ :status ].should == "valid" }
|
29
29
|
end
|
30
30
|
|
31
31
|
Given /^I have a set of invalid videos$/ do
|
@@ -57,3 +57,8 @@ end
|
|
57
57
|
Then /^it should report that the job deletion was unsucessful$/ do
|
58
58
|
@status.should be_false
|
59
59
|
end
|
60
|
+
|
61
|
+
Then /^the destination video size should be correct$/ do
|
62
|
+
job = Videojoiner::FFMpeg::Joiner.fetch( @joiner_job.id )
|
63
|
+
job.size.should >= File.size?( job.output_file )
|
64
|
+
end
|
data/lib/videojoiner/joiner.rb
CHANGED
@@ -11,8 +11,8 @@ module Videojoiner
|
|
11
11
|
# @param video_sources [array] An array of video files
|
12
12
|
def initialize( id, video_sources )
|
13
13
|
@id = id
|
14
|
-
@video_list = self.class.probe_videos( video_sources )
|
15
14
|
@output_file = ""
|
15
|
+
@video_list = self.class.probe_videos( video_sources )
|
16
16
|
@process = Videojoiner::FFMpeg::JoinerProcess.new
|
17
17
|
@process.log_path = "log/"
|
18
18
|
# Path to a text file with the list of videos to be used for ffmpeg's concat demuxer
|
@@ -44,7 +44,7 @@ module Videojoiner
|
|
44
44
|
# @return true if the job removal was sucessful
|
45
45
|
# @return false otherwise
|
46
46
|
def delete
|
47
|
-
if self.class.exist?( @id )
|
47
|
+
if self.class.exist?( @id )
|
48
48
|
self.class.remove_job( @id )
|
49
49
|
File.delete( "#{@config_file}" ) unless !File.exist?( "#{@config_file}" )
|
50
50
|
File.delete( "#{@output_file}" ) unless !File.exist?( "#{@output_file}" )
|
@@ -61,39 +61,35 @@ module Videojoiner
|
|
61
61
|
output.include?( "No more output streams to write to, finishing." ) && output.include?( "muxing overhead" )
|
62
62
|
end
|
63
63
|
|
64
|
+
# Method that returns the total file size of the valid input videos
|
65
|
+
# @return the total file size
|
66
|
+
def size
|
67
|
+
total_size = 0
|
68
|
+
@video_list.each_value{ | element | total_size += element[ :size ] unless element[ :status ] == 'invalid' }
|
69
|
+
total_size
|
70
|
+
end
|
71
|
+
|
64
72
|
class << self
|
65
73
|
|
66
74
|
attr_accessor :config_path
|
67
75
|
|
68
|
-
# Check that the video sources passed has parameters are valid for the joining process
|
69
|
-
# @param video_sources [array] an array with the source videos
|
70
|
-
# @return a hash with the source videos and its validation status
|
71
|
-
def probe_videos( video_sources )
|
72
|
-
video_list = Hash.new
|
73
|
-
|
74
|
-
video_sources.each do |source|
|
75
|
-
inspector = RVideo::Inspector.new( :file => "#{source}" )
|
76
|
-
if ( inspector.valid? ) && ( inspector.duration > 0 )
|
77
|
-
video_list.store( source, 'valid' )
|
78
|
-
else
|
79
|
-
video_list.store( source, 'invalid' )
|
80
|
-
end
|
81
|
-
end
|
82
|
-
video_list
|
83
|
-
end
|
84
|
-
|
85
76
|
# Check if the job list is empty
|
86
77
|
# @return true if the list is empty
|
87
78
|
# @return false otherwise
|
88
79
|
def empty?
|
89
|
-
|
80
|
+
job_list.empty?
|
90
81
|
end
|
91
82
|
|
92
83
|
# Fetches a job from the job list by it ID
|
93
84
|
# @param id [string] the job ID
|
94
85
|
# @return the job with that ID
|
86
|
+
# @return false otherwise
|
95
87
|
def fetch( id )
|
96
|
-
|
88
|
+
begin
|
89
|
+
job_list.fetch( id ) unless empty?
|
90
|
+
rescue KeyError
|
91
|
+
false
|
92
|
+
end
|
97
93
|
end
|
98
94
|
|
99
95
|
# Check if a job exist in the job list
|
@@ -101,26 +97,51 @@ module Videojoiner
|
|
101
97
|
# @return true if the job exist
|
102
98
|
# @return false otherwise
|
103
99
|
def exist?( id )
|
104
|
-
|
100
|
+
job_list.has_key?( id ) unless empty?
|
105
101
|
end
|
106
102
|
|
107
103
|
# Clears the job list
|
108
104
|
def clear_list
|
109
|
-
|
105
|
+
job_list.clear unless empty?
|
110
106
|
end
|
111
107
|
|
112
108
|
# Adds a video joiner job to the job list
|
113
109
|
# @param id [string] the job ID
|
114
110
|
# @param joiner [Videojoiner::FFMpeg::Joiner] the joiner job object
|
111
|
+
# @return false if the job exists already
|
115
112
|
def add_job( id, joiner )
|
116
|
-
|
113
|
+
if exist?( id )
|
114
|
+
false
|
115
|
+
else
|
116
|
+
job_list.store( id, joiner )
|
117
|
+
end
|
117
118
|
end
|
118
119
|
|
119
120
|
# Removes a video joiner job from the job list
|
120
121
|
# @param id [string] the job ID
|
122
|
+
# @return false if the job don't exists
|
121
123
|
def remove_job( id )
|
122
|
-
|
123
|
-
|
124
|
+
if exist?( id )
|
125
|
+
job_list.delete( id )
|
126
|
+
else
|
127
|
+
false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Check that the video sources passed has parameters are valid for the joining process
|
132
|
+
# @param video_sources [array] an array with the source videos
|
133
|
+
# @return a hash with the source videos, its validation status and size
|
134
|
+
def probe_videos( video_sources )
|
135
|
+
output = Hash.new
|
136
|
+
video_sources.each do |source|
|
137
|
+
inspector = RVideo::Inspector.new( :file => "#{source}" ) unless !File.exist?( source )
|
138
|
+
if inspector && ( inspector.valid? ) && ( inspector.duration > 0 )
|
139
|
+
output.store( source, { status: 'valid', size: File.size( source ) } )
|
140
|
+
else
|
141
|
+
output.store( source, 'invalid' )
|
142
|
+
end
|
143
|
+
end
|
144
|
+
output
|
124
145
|
end
|
125
146
|
|
126
147
|
# Yields the current object to configure some required parameters
|
@@ -132,10 +153,10 @@ module Videojoiner
|
|
132
153
|
|
133
154
|
# Return the joiner job list, or generate an empty list if it don't exist already
|
134
155
|
# It requires the setting of the config_path parameter previously
|
135
|
-
def
|
156
|
+
def job_list
|
136
157
|
raise ConfigurationError, "Missing configuration: please check Joiner.config_path" unless configured?
|
137
158
|
raise ConfigPathError, "Config path not exist" unless Dir.exist?( config_path )
|
138
|
-
@
|
159
|
+
@job_list ||= Hash.new
|
139
160
|
end
|
140
161
|
|
141
162
|
# Return the configuration status of the object
|
data/spec/joiner_spec.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Videojoiner::FFMpeg::Joiner do
|
4
|
+
|
5
|
+
before do
|
6
|
+
Videojoiner::FFMpeg::Joiner.configure do |c|
|
7
|
+
c.config_path = "/tmp/"
|
8
|
+
end
|
9
|
+
@joiner = Videojoiner::FFMpeg::Joiner.new( "test", [ "aaa.mp4", "bbb.mp4", "ccc.mp4" ] )
|
10
|
+
Videojoiner::FFMpeg::Joiner.add_job( "test", @joiner )
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should return false when adding an existent joiner job" do
|
14
|
+
Videojoiner::FFMpeg::Joiner.add_job( "test", @joiner ).should be_false
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should return false when deleting an unexistent joiner job" do
|
18
|
+
Videojoiner::FFMpeg::Joiner.remove_job( "unexistent_job" ).should be_false
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should return false when fetching an unexistent joiner job" do
|
22
|
+
Videojoiner::FFMpeg::Joiner.fetch( "unexistent_job" ).should be_false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter 'lib/videojoiner/rvideo_patch.rb'
|
5
|
+
end
|
6
|
+
|
7
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
8
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
9
|
+
|
10
|
+
require 'rspec'
|
11
|
+
require 'videojoiner'
|
12
|
+
|
13
|
+
# Requires supporting files with custom matchers and macros, etc,
|
14
|
+
# in ./support/ and its subdirectories.
|
15
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
data/videojoiner.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "videojoiner"
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Rafael Perez", "Luis Ciudad"]
|
12
|
-
s.date = "2013-01-
|
12
|
+
s.date = "2013-01-25"
|
13
13
|
s.description = "This gem contains modules to create a single video file using a set of videos as input, via ffmpeg concat demuxer."
|
14
14
|
s.email = ["rperez@nosolosoftware.biz", "lciudad@nosolosoftware.biz"]
|
15
15
|
s.extra_rdoc_files = [
|
@@ -35,10 +35,12 @@ Gem::Specification.new do |s|
|
|
35
35
|
"lib/videojoiner/joiner.rb",
|
36
36
|
"lib/videojoiner/rvideo_patch.rb",
|
37
37
|
"log/.gitkeep",
|
38
|
+
"spec/joiner_spec.rb",
|
39
|
+
"spec/spec_helper.rb",
|
38
40
|
"video_root/.gitkeep",
|
39
41
|
"videojoiner.gemspec"
|
40
42
|
]
|
41
|
-
s.homepage = "https://
|
43
|
+
s.homepage = "https://github.com/rcpj/videojoiner"
|
42
44
|
s.licenses = ["GPLv3"]
|
43
45
|
s.require_paths = ["lib"]
|
44
46
|
s.rubygems_version = "1.8.24"
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: videojoiner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-01-
|
13
|
+
date: 2013-01-25 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: runnable
|
@@ -329,9 +329,11 @@ files:
|
|
329
329
|
- lib/videojoiner/joiner.rb
|
330
330
|
- lib/videojoiner/rvideo_patch.rb
|
331
331
|
- log/.gitkeep
|
332
|
+
- spec/joiner_spec.rb
|
333
|
+
- spec/spec_helper.rb
|
332
334
|
- video_root/.gitkeep
|
333
335
|
- videojoiner.gemspec
|
334
|
-
homepage: https://
|
336
|
+
homepage: https://github.com/rcpj/videojoiner
|
335
337
|
licenses:
|
336
338
|
- GPLv3
|
337
339
|
post_install_message:
|
@@ -346,7 +348,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
346
348
|
version: '0'
|
347
349
|
segments:
|
348
350
|
- 0
|
349
|
-
hash: -
|
351
|
+
hash: -3929381644104050705
|
350
352
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
351
353
|
none: false
|
352
354
|
requirements:
|