videojoiner 0.0.2 → 0.0.3
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/.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:
|