Class: FLV::Edit::Processor::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/flv/edit/processor/base.rb

Overview

Processors are used to process FLV files. Processors form are chain and the data (header and tags) will ‘flow’ through the chain in sequence. Each processor can inspect the data and change the flow, either by modifying the data, inserting new data in the flow or stopping the propagation of data.

A FLV file can be seen as a sequence of chunks, the first one being a Header and the following ones a series of Tags with different types of bodies: Audio, Video or Event. Events store all meta data related information: onMetaData, onCuePoint, …

To tap into the flow of chunks, a processor can define any of the following methods:

on_chunk
  on_header
  on_tag
    on_audio
    on_video
      on_keyframe
      on_interframe
      on_disposable_interframe
    on_event
      
      on_cue_point
      on_other_event

All of these methods will have one argument: the current chunk being processed. For example, if the current chunk is an ‘onMetaData’ event, then the following will be called (from the most specialized to the least).

processor.(chunk)
processor.on_event(chunk)
processor.on_chunk(chunk)
# later on, the next processor will handle it:
next_processor.(chunk)
#...

The methods need not return anything. It is assumed that the chunk will continue to flow through the processing chain. When the chunk should not continue down the chain, call absorb. To insert other tags in the flow, call dispatch_instead. Finally, it’s possible to stop the processing of the file completely.

It is possible to look back at already processed chunks (up to a certain limit) with look_back or even in the future with look_ahead

Direct Known Subclasses

CommandLine, Debug, Head, Join, MetaDataMaker, Print, Reader, Save, Update

Constant Summary collapse

EVENT_TRIGGER =
{
  :on_header      => :on_chunk,
  :on_tag         => :on_chunk,
  :on_audio       => :on_tag,
  :on_video       => :on_tag,
  :on_event       => :on_tag,
  :on_meta_data   => :on_event,
  :on_cue_point   => :on_event,
  :on_last_second => :on_event,
  :on_other_event => :on_event,
  :on_keyframe    => :on_video,
  :on_interframe  => :on_video,
  :on_disposable_interframe => :on_video
}.freeze
ALL_EVENTS =
(EVENT_TRIGGER.keys | EVENT_TRIGGER.values).freeze
MAIN_EVENTS =
ALL_EVENTS.reject{ |k| EVENT_TRIGGER.has_value?(k)}.freeze
EVENT_TRIGGER_LIST =
Hash.new{|h, k| h[k] = [k] + h[EVENT_TRIGGER[k]]}.tap{|h| h[nil] = []; h.values_at(*MAIN_EVENTS)}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source = nil, options = {}) ⇒ Base

Returns a new instance of Base.



47
48
49
50
51
52
53
54
# File 'lib/flv/edit/processor/base.rb', line 47

def initialize(source=nil, options={})
  @options = options.freeze
  @source = source
  on_calls = self.class.instance_methods(false).select{|m| m.to_s.start_with?("on_")}.map(&:to_sym) #Note: to_s needed for ruby 1.9, to_sym for ruby 1.8
  unless (potential_errors = on_calls - ALL_EVENTS).empty?
    warn "The following are not events: #{potential_errors.join(',')} (class #{self.class})"
  end
end

Instance Attribute Details

#optionsObject (readonly)

Returns the value of attribute options.



45
46
47
# File 'lib/flv/edit/processor/base.rb', line 45

def options
  @options
end

Instance Method Details

#absorbObject

Note: the (*) is so that we can alias events like on_meta_data



64
65
66
# File 'lib/flv/edit/processor/base.rb', line 64

def absorb(*) # Note: the (*) is so that we can alias events like on_meta_data
  throw :absorb
end

#dispatch_chunk(chunk) ⇒ Object



94
95
96
97
98
99
100
101
102
# File 'lib/flv/edit/processor/base.rb', line 94

def dispatch_chunk(chunk)
  evt = chunk.main_event
  catch :absorb do
    EVENT_TRIGGER_LIST[evt].each do |event|
      send(event, chunk) if respond_to?(event)
    end
    @block.call chunk
  end
end

#dispatch_chunks(enum) ⇒ Object



88
89
90
91
92
# File 'lib/flv/edit/processor/base.rb', line 88

def dispatch_chunks(enum)
  enum.each do |chunk|
    dispatch_chunk(chunk)
  end
end

#dispatch_instead(*chunks) ⇒ Object



104
105
106
107
108
109
# File 'lib/flv/edit/processor/base.rb', line 104

def dispatch_instead(*chunks)
  chunks.each do |chunk|
    @block.call chunk
  end
  absorb
end

#each(&block) ⇒ Object



76
77
78
79
80
81
82
# File 'lib/flv/edit/processor/base.rb', line 76

def each(&block)
  return to_enum(:each_chunk) unless block_given?
  @block = block
  catch :stop do
    process_next_file
  end
end

#has_next_file?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/flv/edit/processor/base.rb', line 56

def has_next_file?
  @source.has_next_file?
end

#process_allObject



72
73
74
# File 'lib/flv/edit/processor/base.rb', line 72

def process_all
  each{} while has_next_file?
end

#process_next_fileObject



84
85
86
# File 'lib/flv/edit/processor/base.rb', line 84

def process_next_file
  dispatch_chunks(@source)
end

#rewindObject



60
61
62
# File 'lib/flv/edit/processor/base.rb', line 60

def rewind
  @source.rewind
end

#stdoutObject



111
112
113
# File 'lib/flv/edit/processor/base.rb', line 111

def stdout
  options[:out] || STDOUT
end

#stopObject



68
69
70
# File 'lib/flv/edit/processor/base.rb', line 68

def stop
  throw :stop
end