module AviGlitch # Base is the object that provides interfaces mainly used. # To glitch, and save file. The instance is returned through AviGlitch#open. # class Base # AviGlitch::Frames object generated from the +file+. attr_reader :frames # The input file attr_reader :avi ## # Creates a new instance of AviGlitch::Base, open the file and # make it ready to manipulate. # It requires +path+ as Pathname or an instance of AviGlirtch::Avi. def initialize path_or_object if path_or_object.kind_of?(Avi) @avi = path_or_object else unless AviGlitch::Base.surely_formatted? path_or_object raise 'Unsupported file passed.' end @avi = Avi.new path_or_object end @frames = Frames.new @avi end ## # Outputs the glitched file to +path+, and close the file. def output path, do_file_close = true @avi.output path close if do_file_close self end ## # An explicit file close. def close @avi.close end ## # Glitches each frame data. # It is a convenient method to iterate each frame. # # The argument +target+ takes symbols listed below: # [:keyframe or :iframe] select video key frames (aka I-frame) # [:deltaframe or :pframe] select video delta frames (difference frames) # [:videoframe] select both of keyframe and deltaframe # [:audioframe] select audio frames # [:all] select all frames # # It also requires a block. In the block, you take the frame data # as a String parameter. # To modify the data, simply return a modified data. # Without a block it returns Enumerator, with a block it returns +self+. def glitch target = :all, &block # :yield: data if block_given? @frames.each do |frame| if frame.is? target frame.data = yield frame.data end end self else self.enum_for :glitch, target end end ## # Do glitch with index. def glitch_with_index target = :all, &block # :yield: data, index if block_given? self.glitch(target).with_index do |x, i| yield x, i end self else self.glitch target end end ## # Mutates all (or in +range+) keyframes into deltaframes. # It's an alias for Frames#mutate_keyframes_into_deltaframes! def mutate_keyframes_into_deltaframes! range = nil self.frames.mutate_keyframes_into_deltaframes! range self end ## # Check if it has keyframes. def has_keyframe? result = false self.frames.each do |f| if f.is_keyframe? result = true break end end result end ## # Removes all keyframes. # It is same as +glitch(:keyframes){|f| nil }+ def remove_all_keyframes! self.glitch :keyframe do |f| nil end self end ## # Swaps the frames with other Frames data. def frames= other raise TypeError unless other.kind_of?(Frames) @frames.clear @frames.concat other end alias_method :write, :output alias_method :has_keyframes?, :has_keyframe? class << self ## # Checks if the +file+ is a correctly formetted AVI file. # +file+ can be String or Pathname or IO. def surely_formatted? file, debug = false passed = true begin riff = Avi.rifftree file { 'RIFF-AVI sign': /^RIFF \(\d+\) ’AVI ’$/, 'movi': /^\s+LIST \(\d+\) ’movi’$/, 'idx1': /^\s+idx1 \(\d+\)$/ }.each do |m, r| unless riff =~ r warn "#{m} is not found." if debug passed = false end end rescue => e warn e.message if debug passed = false end passed end end end end