Class: Videojoiner::FFMpeg::Joiner

Inherits:
Object
  • Object
show all
Defined in:
lib/videojoiner/joiner.rb

Defined Under Namespace

Classes: ConfigurationError

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, video_sources) ⇒ Joiner

Initialize a new joiner object

Parameters:

  • id (string)

    The joiner job ID

  • video_sources (array)

    An array of video files



12
13
14
15
16
17
18
19
20
# File 'lib/videojoiner/joiner.rb', line 12

def initialize( id, video_sources )
  @id = id
  @output_file = ""
  @video_list = self.class.probe_videos( video_sources )
  @process = Videojoiner::FFMpeg::JoinerProcess.new
  @process.log_path = "log/"
  # Path to a text file with the list of videos to be used for ffmpeg's concat demuxer
  @config_file = "#{self.class.config_path}#{id}_#{Time.now.to_i}.ffmpeg"
end

Class Attribute Details

.config_pathObject

Returns the value of attribute config_path.



74
75
76
# File 'lib/videojoiner/joiner.rb', line 74

def config_path
  @config_path
end

Instance Attribute Details

#config_fileObject (readonly)

Returns the value of attribute config_file.



7
8
9
# File 'lib/videojoiner/joiner.rb', line 7

def config_file
  @config_file
end

#idObject (readonly)

Returns the value of attribute id.



7
8
9
# File 'lib/videojoiner/joiner.rb', line 7

def id
  @id
end

#output_fileObject (readonly)

Returns the value of attribute output_file.



7
8
9
# File 'lib/videojoiner/joiner.rb', line 7

def output_file
  @output_file
end

#processObject (readonly)

Returns the value of attribute process.



7
8
9
# File 'lib/videojoiner/joiner.rb', line 7

def process
  @process
end

#video_listObject (readonly)

Returns the value of attribute video_list.



7
8
9
# File 'lib/videojoiner/joiner.rb', line 7

def video_list
  @video_list
end

Class Method Details

.add_job(id, joiner) ⇒ Object

Adds a video joiner job to the job list

Parameters:

Returns:

  • false if the job exists already



112
113
114
115
116
117
118
# File 'lib/videojoiner/joiner.rb', line 112

def add_job( id, joiner )
  if exist?( id )
    false
  else
    job_list.store( id, joiner )
  end
end

.clear_listObject

Clears the job list



104
105
106
# File 'lib/videojoiner/joiner.rb', line 104

def clear_list
  job_list.clear unless empty?
end

.configure {|_self| ... } ⇒ Object

Yields the current object to configure some required parameters

Yields:

  • (_self)

Yield Parameters:



148
149
150
# File 'lib/videojoiner/joiner.rb', line 148

def configure( &block )
  yield self
end

.empty?Boolean

Check if the job list is empty

Returns:

  • (Boolean)

    true if the list is empty

  • false otherwise



79
80
81
# File 'lib/videojoiner/joiner.rb', line 79

def empty?
  job_list.empty?
end

.exist?(id) ⇒ Boolean

Check if a job exist in the job list

Parameters:

  • id (string)

    the job ID

Returns:

  • (Boolean)

    true if the job exist

  • false otherwise



99
100
101
# File 'lib/videojoiner/joiner.rb', line 99

def exist?( id )
  job_list.has_key?( id ) unless empty?
end

.fetch(id) ⇒ Object

Fetches a job from the job list by it ID

Parameters:

  • id (string)

    the job ID

Returns:

  • the job with that ID

  • false otherwise



87
88
89
90
91
92
93
# File 'lib/videojoiner/joiner.rb', line 87

def fetch( id )
  begin
    job_list.fetch( id ) unless empty?
  rescue KeyError
    false
  end
end

.probe_videos(video_sources) ⇒ Object

Check that the video sources passed has parameters are valid for the joining process

Parameters:

  • video_sources (array)

    an array with the source videos

Returns:

  • a hash with the source videos, its validation status and size



134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/videojoiner/joiner.rb', line 134

def probe_videos( video_sources )
  output = Hash.new
  video_sources.each do |source|
    inspector = RVideo::Inspector.new( :file => "#{source}" ) unless !File.exist?( source )
    if inspector && ( inspector.valid? ) && ( inspector.duration > 0 )
      output.store( source, { status: 'valid', size: File.size( source ) } )
    else
      output.store( source, { status: 'invalid' } )
    end
  end
  output
end

.remove_job(id) ⇒ Object

Removes a video joiner job from the job list

Parameters:

  • id (string)

    the job ID

Returns:

  • false if the job don’t exists



123
124
125
126
127
128
129
# File 'lib/videojoiner/joiner.rb', line 123

def remove_job( id )
  if exist?( id ) 
    job_list.delete( id )
  else
    false
  end
end

Instance Method Details

#create(opts = {}) ⇒ Object

Starts the video joiner job and adds it to the job list

Parameters:

  • opts (hash) (defaults to: {})

    A hash with configuration options for the transcoder



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/videojoiner/joiner.rb', line 24

def create( opts = {} )
  # FFMpeg options hash
  options = {
    :vcodec    => $1 || "copy",
    :acodec    => $2 || "copy",
    :filename  => $3 || "#{@id}_#{Time.now.to_i}",
    :extension => $4 || "mp4"
  }.merge( opts )

  if self.class.exist?( @id )
    false
  else
    Videojoiner::FFMpeg::JoinerProcess.make_ffmpeg_config( @video_list, @config_file )
    @process.start( @id, @config_file, options )
    self.class.add_job( @id, self )
    @output_file = "#{options[:filename]}.#{options[:extension]}"
  end
end

#deleteObject

Delete a previously created video joiner job and remove it from the job list

Returns:

  • true if the job removal was sucessful

  • false otherwise



46
47
48
49
50
51
52
53
54
# File 'lib/videojoiner/joiner.rb', line 46

def delete
  if self.class.exist?( @id ) 
    self.class.remove_job( @id )
    File.delete( "#{@config_file}" ) unless !File.exist?( "#{@config_file}" )
    File.delete( "#{@output_file}" ) unless !File.exist?( "#{@output_file}" )
  else
    false
  end
end

#finished?Boolean

Method that check if the join process has finished

Returns:

  • (Boolean)

    true if the job has finished

  • false otherwise



59
60
61
62
# File 'lib/videojoiner/joiner.rb', line 59

def finished?
  output = @process.std_err
  output.include?( "No more output streams to write to, finishing." ) && output.include?( "muxing overhead" ) 
end

#sizeObject

Method that returns the total file size of the valid input videos

Returns:

  • the total file size



66
67
68
69
70
# File 'lib/videojoiner/joiner.rb', line 66

def size
  total_size = 0
  @video_list.each_value{ | element | total_size += element[ :size ] unless element[ :status ] == 'invalid' }
  total_size
end