class Moshy::PPulse
Public Instance Methods
cli(args)
click to toggle source
# File lib/moshy/ppulse.rb, line 3 def cli(args) opts = Slop::Options.new opts.banner = "Usage: moshy -m ppulse -i file.avi -o file_out.avi [options]\nmoshy -m inspect --help for details" opts.separator 'Required Parameters:' opts.string '-i', '--input', 'Input file path - must be an .avi. Clip to split in split mode, first clip in stitch mode' opts.string '-o', '--output', 'Output file path - will be appended with -#.avi for each frame in split mode' opts.separator 'Optional Parameters:' opts.string '-k', '--keep', 'Whether or not to keep standard frames. (default: true)', default: "true" opts.integer '-c', '--count', 'How many frames to grab forward from each interval. (default: 1)', default: 1 opts.integer '-d', '--dupes', 'Number of times to multiply the frame (default: 30)', default: 30 opts.integer '-n', '--interval', 'Which nth frames should be duplicated (default: 30)', default: 30 opts.on '-h', '--help' do puts opts puts "\n" puts \ "Takes c number of frames and every n frames and duplicates them a given amount, resulting in a consistent P-duplication datamosh that's good for creating rhythmic effects. This was originally created to create mosh effects in sync with a beat for a music video. You can specify what interval to get frames at with -n (--interval). You can specify how many frames to get from the current interval with -c (--count). You can specify how many times to duplicate a given frame with -d (--dupes). You can then specify whether or not to keep the original video's frames between the end of the duplication and where the next interval occurs with -k (--keep). Keeping original frames causes the original motion to continue after the P-frame dupe effect, whereas dropping original frames causes the video to snap into the motion of the frames at each interval. This is a more complex effect so I recommend experimenting with it!" exit end default = { :dupes => 30, :interval => 30, :count => 1, :keep => true } parser = Slop::Parser.new(opts) slop_options = parser.parse(ARGV) @options = default.merge(slop_options) { |key, oldval, newval| if newval.nil? oldval else newval end } if @options[:keep] == "false" @options[:keep] = false else @options[:keep] = true end # Check mandatory params mandatory = [:input, :output] missing = mandatory.select{ |param| @options[param].nil? } unless missing.empty? puts "Missing options: #{missing.join(', ')}" puts slop_options exit end puts "Opening file " + @options[:input] + "..." a = AviGlitch.open @options[:input] # Rewrite this line for your file. puts "Opened!" ppulse(a, @options[:output], @options[:interval], @options[:count], @options[:dupes], @options[:keep]) end
ppulse(clip, output, interval = 30, count = 1, duplicate_amount = 30, leave_originals = true)
click to toggle source
Loops through a video file and grabs every ‘interval` frames then duplicates them `duplicate_amount` times
‘leave_originals` will copy standard frames and only p-frame the last one every `interval`
# File lib/moshy/ppulse.rb, line 79 def ppulse(clip, output, interval = 30, count = 1, duplicate_amount = 30, leave_originals = true) puts "Size: " + clip.frames.size_of('videoframe').to_s frames = nil video_frame_counter = 0 have_iframe = false if leave_originals first_index = 0 second_index = 0 clip.frames.each_with_index do |f, i| if f.is_videoframe? video_frame_counter += 1 if video_frame_counter % interval == 0 second_index = i puts "first index: " + first_index.to_s puts "second index: " + second_index.to_s clipped = clip.frames[first_index..(i + 5)] dupe_clip = clip.frames[i, count] * duplicate_amount if frames.nil? frames = clipped + dupe_clip else frames = frames + clipped + dupe_clip end puts "Current expected output frame count: " + frames.size.to_s first_index = i + 5 end end end else # Harvest clip details clip.frames.each_with_index do |f, i| if f.is_videoframe? if !have_iframe && f.is_keyframe? puts "Added first iframe (necessary to avoid total corruption)" # no idea why i need to get 5 frames = clip.frames[i, 1] have_iframe = true end # +1 to offset the first iframe if video_frame_counter % interval == 0 && f.is_deltaframe? puts "Processing frame " + video_frame_counter.to_s + " at index " + i.to_s # You might ask why we need to check if frames are nil when we already check # whether or not we have an i frame and if the above is a keyframe - that's # because datamoshers are crazy and might pass use clip with no leading iframe :) if frames.nil? puts "First frame, setting" clipped = clip.frames[i, count] frames = frames.concat( clipped * duplicate_amount ) puts "Frame size" puts frames.size_of('videoframe') else puts "Current i: " + i.to_s puts "Duping frame " + i.to_s + " " + duplicate_amount.to_s + " times" frames = frames.concat( clip.frames[i, count] * duplicate_amount ) puts "Next frame, size: " + frames.size.to_s end end video_frame_counter += 1 end end end o = AviGlitch.open frames o.output output puts "Done! File processed to: " + output end