moshy 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/moshy/inspect.rb CHANGED
@@ -1,110 +1,110 @@
1
- module Moshy
2
- class Inspect
3
- def cli(args)
4
- opts = Slop::Options.new
5
- opts.banner = "Usage: moshy -m inspect -i file.avi\nmoshy -m inspect --help for details"
6
- opts.separator 'Required Parameters:'
7
- opts.string '-i', '--input', 'Input file path - must be an .avi.'
8
- opts.on '-h', '--help' do
9
- puts opts
10
- puts "\n"
11
- puts \
12
- "Reads an .avi file and prints which video frames are keyframes (I-Frames)
13
- and which frames are delta frames (P-frames or B-frames). moshy can't
14
- tell the difference between a P-frame or a B-frame, so you will want
15
- to use avidemux or another program if you need to know.
16
-
17
- This is most useful for identifying where I-Frames exist without having
18
- to manually seek through them in a video player/editor. Works well with
19
- moshy's \"isplit\" mode because you can use the I-frames from inspect's
20
- output to decide what segment of clips you want to get by their I-frames.
21
-
22
- The output reads like this:
23
-
24
- 0: keyframe
25
- 1..359: deltaframe
26
- 360: keyframe
27
- 361..441: deltaframe
28
-
29
- Large video files will output a lot of text, so you may want to write the
30
- output to an external file like this:
31
-
32
- moshy -m inspect -i video.avi > inspect.txt"
33
- exit
34
- end
35
-
36
- parser = Slop::Parser.new(opts)
37
- @options = parser.parse(ARGV)
38
-
39
- # Check mandatory params
40
- mandatory = [:input]
41
- missing = mandatory.select{ |param| @options[param].nil? }
42
- unless missing.empty?
43
- puts "Missing options: #{missing.join(', ')}"
44
- puts @options
45
- exit
46
- end
47
-
48
- puts "Opening file " + @options[:input] + "..."
49
- a = AviGlitch.open @options[:input] # Rewrite this line for your file.
50
- puts "Opened!"
51
-
52
- inspect(a)
53
- end
54
-
55
- def inspect(clip)
56
- keyframe_counter = 0
57
- video_frame_counter = 0
58
- last_video_frame = 0
59
- start_of_frame_segment = 0
60
- last_type = nil
61
- type = nil
62
- # Harvest clip details
63
- total_frame_count = clip.frames.count
64
- clip.frames.each_with_index do |f, i|
65
- if f.is_videoframe?
66
- if f.is_keyframe?
67
- type = "keyframe"
68
- elsif f.is_deltaframe?
69
- type = "deltaframe"
70
- end
71
-
72
- if video_frame_counter == 0
73
- last_type = type
74
- end
75
-
76
- if type == last_type
77
- last_video_frame = video_frame_counter
78
- else
79
- # Found a new type segment, print out what we've got
80
- if start_of_frame_segment + 1 == last_video_frame
81
- segment_string = start_of_frame_segment.to_s + ": " + last_type
82
- else
83
- segment_string = start_of_frame_segment.to_s + ".." + (last_video_frame - 1).to_s + ": " + last_type
84
- end
85
- # Let's not add this so we don't confuse the user by making
86
- # them think they want to use isplit according to the keyframe count
87
- # if last_type == "keyframe"
88
- # segment_string += " " + keyframe_counter.to_s
89
- # keyframe_counter += 1
90
- # end
91
- puts segment_string
92
-
93
- # The new last type will be this type during the next frame segment
94
- last_type = type
95
- # Update start of the frame segment to this frame
96
- start_of_frame_segment = video_frame_counter
97
- end
98
- end
99
- video_frame_counter += 1
100
- last_video_frame = video_frame_counter
101
- end
102
- if start_of_frame_segment + 1 == last_video_frame
103
- puts start_of_frame_segment.to_s + ": " + last_type
104
- else
105
- puts start_of_frame_segment.to_s + ".." + (last_video_frame - 1).to_s + ": " + last_type
106
- end
107
- puts "All done!"
108
- end
109
- end
110
- end
1
+ module Moshy
2
+ class Inspect
3
+ def cli(args)
4
+ opts = Slop::Options.new
5
+ opts.banner = "Usage: moshy -m inspect -i file.avi\nmoshy -m inspect --help for details"
6
+ opts.separator 'Required Parameters:'
7
+ opts.string '-i', '--input', 'Input file path - must be an .avi.'
8
+ opts.on '-h', '--help' do
9
+ puts opts
10
+ puts "\n"
11
+ puts \
12
+ "Reads an .avi file and prints which video frames are keyframes (I-Frames)
13
+ and which frames are delta frames (P-frames or B-frames). moshy can't
14
+ tell the difference between a P-frame or a B-frame, so you will want
15
+ to use avidemux or another program if you need to know.
16
+
17
+ This is most useful for identifying where I-Frames exist without having
18
+ to manually seek through them in a video player/editor. Works well with
19
+ moshy's \"isplit\" mode because you can use the I-frames from inspect's
20
+ output to decide what segment of clips you want to get by their I-frames.
21
+
22
+ The output reads like this:
23
+
24
+ 0: keyframe
25
+ 1..359: deltaframe
26
+ 360: keyframe
27
+ 361..441: deltaframe
28
+
29
+ Large video files will output a lot of text, so you may want to write the
30
+ output to an external file like this:
31
+
32
+ moshy -m inspect -i video.avi > inspect.txt"
33
+ exit
34
+ end
35
+
36
+ parser = Slop::Parser.new(opts)
37
+ @options = parser.parse(ARGV)
38
+
39
+ # Check mandatory params
40
+ mandatory = [:input]
41
+ missing = mandatory.select{ |param| @options[param].nil? }
42
+ unless missing.empty?
43
+ puts "Missing options: #{missing.join(', ')}"
44
+ puts @options
45
+ exit
46
+ end
47
+
48
+ puts "Opening file " + @options[:input] + "..."
49
+ a = AviGlitch.open @options[:input] # Rewrite this line for your file.
50
+ puts "Opened!"
51
+
52
+ inspect(a)
53
+ end
54
+
55
+ def inspect(clip)
56
+ keyframe_counter = 0
57
+ video_frame_counter = 0
58
+ last_video_frame = 0
59
+ start_of_frame_segment = 0
60
+ last_type = nil
61
+ type = nil
62
+ # Harvest clip details
63
+ total_frame_count = clip.frames.count
64
+ clip.frames.each_with_index do |f, i|
65
+ if f.is_videoframe?
66
+ if f.is_keyframe?
67
+ type = "keyframe"
68
+ elsif f.is_deltaframe?
69
+ type = "deltaframe"
70
+ end
71
+
72
+ if video_frame_counter == 0
73
+ last_type = type
74
+ end
75
+
76
+ if type == last_type
77
+ last_video_frame = video_frame_counter
78
+ else
79
+ # Found a new type segment, print out what we've got
80
+ if start_of_frame_segment + 1 == last_video_frame
81
+ segment_string = start_of_frame_segment.to_s + ": " + last_type
82
+ else
83
+ segment_string = start_of_frame_segment.to_s + ".." + (last_video_frame - 1).to_s + ": " + last_type
84
+ end
85
+ # Let's not add this so we don't confuse the user by making
86
+ # them think they want to use isplit according to the keyframe count
87
+ # if last_type == "keyframe"
88
+ # segment_string += " " + keyframe_counter.to_s
89
+ # keyframe_counter += 1
90
+ # end
91
+ puts segment_string
92
+
93
+ # The new last type will be this type during the next frame segment
94
+ last_type = type
95
+ # Update start of the frame segment to this frame
96
+ start_of_frame_segment = video_frame_counter
97
+ end
98
+ end
99
+ video_frame_counter += 1
100
+ last_video_frame = video_frame_counter
101
+ end
102
+ if start_of_frame_segment + 1 == last_video_frame
103
+ puts start_of_frame_segment.to_s + ": " + last_type
104
+ else
105
+ puts start_of_frame_segment.to_s + ".." + (last_video_frame - 1).to_s + ": " + last_type
106
+ end
107
+ puts "All done!"
108
+ end
109
+ end
110
+ end
data/lib/moshy/isplit.rb CHANGED
@@ -1,129 +1,129 @@
1
- module Moshy
2
- class ISplit
3
- def cli(args)
4
- opts = Slop::Options.new
5
- opts.banner = "Usage: moshy -m isplit -i file.avi -o file_out\nmoshy -m isplit --help for details"
6
- opts.separator 'Required Parameters:'
7
- opts.string '-i', '--input', 'Input file path - must be an .avi.'
8
- opts.string '-o', '--output', 'Output file path - will be appended with -#.avi for each clip.'
9
- opts.separator 'Optional Parameters:'
10
- opts.integer '-b', '--begin', 'Index of the I-frame at which to begin clipping (inclusive)'
11
- opts.integer '-e', '--end', 'Index of the I-frame at which to stop clipping (inclusive)'
12
- opts.integer '-v', '--verbose', 'Noisy output (default: false)'
13
- opts.on '-h', '--help' do
14
- puts opts
15
- puts "\n"
16
- puts \
17
- "Extracts individual clips from an AVI where each clip is separated
18
- by I-frames in the original AVI. Great for getting specific clips out
19
- of a larger video and later doing I-frame moshing.
20
-
21
- Note that since this creates multiple clips, you should NOT specify
22
- the .avi extension in your output (-o) parameter, as moshy will
23
- automatically append \"-#.avi\" to the output parameter you pass
24
- when it spits out individual clips.
25
-
26
- If you want to only cut clips from a certain section of a larger
27
- video file, you can set the in- and out-points of where to get clips
28
- from by using the -b (--begin) and -e (--end) options, where the
29
- values used in those parameters are the indexes of the I-Frames.
30
- For example, if a video file has 12 I-Frames and you want the clips
31
- between I-Frames 3 and 7, you would use the following command:
32
-
33
- moshy -m isplit -i file.avi -o file_out -b 3 -e 7"
34
- exit
35
- end
36
-
37
- parser = Slop::Parser.new(opts)
38
- @options = parser.parse(ARGV)
39
- # puts @options.to_hash
40
-
41
- # Check mandatory params
42
- mandatory = [:input, :output]
43
- missing = mandatory.select{ |param| @options[param].nil? }
44
- unless missing.empty?
45
- puts "Missing options: #{missing.join(', ')}"
46
- puts @options
47
- exit
48
- end
49
-
50
-
51
- puts "Opening file " + @options[:input] + "..."
52
- a = AviGlitch.open @options[:input] # Rewrite this line for your file.
53
- puts "Opened!"
54
-
55
- split(a, @options[:output], @options[:begin], @options[:end], @options[:verbose])
56
- end
57
-
58
- def clip(frames, out_path, start_index, frame_count)
59
- puts "Clipping " + frame_count.to_s + " frames starting at frame " + start_index.to_s
60
- clip = frames.slice(start_index, frame_count)
61
- o = AviGlitch.open clip
62
- puts "Outputting " + out_path
63
- o.output out_path
64
- end
65
-
66
- def split(clip, output, begin_point, end_point, verbose)
67
- clip_cuts = {}
68
-
69
- clip_count = 0
70
- current_iframe = 0
71
- iframe_index = 0
72
- last_iframe_index = 0
73
- frames_in_clip = 0
74
-
75
- # Harvest clip details
76
- total_frame_count = clip.frames.count
77
- clip.frames.each_with_index do |f, i|
78
- if f.is_keyframe?
79
- iframe_index = i
80
- # Don't process frames that are before our beginning
81
- if current_iframe and begin_point and current_iframe < begin_point
82
- # puts "skipping " + current_iframe.to_s
83
- frames_in_clip = 0
84
- current_iframe = current_iframe + 1
85
- last_iframe_index = iframe_index
86
- # puts "last_iframe_index: " + last_iframe_index.to_s
87
- next
88
- end
89
- break if end_point and current_iframe > end_point
90
-
91
- if current_iframe != 0
92
- if verbose
93
- puts "Storing clip details: iframe_number=" + current_iframe.to_s + "; index=" + last_iframe_index.to_s + "; frame_count=" + frames_in_clip.to_s
94
- end
95
- clip_cuts[current_iframe] = {
96
- :index => last_iframe_index,
97
- :frame_count => frames_in_clip
98
- }
99
- end
100
- frames_in_clip = 0
101
- current_iframe = current_iframe + 1
102
- last_iframe_index = iframe_index
103
- else
104
- frames_in_clip = frames_in_clip + 1
105
- # clip last piece manually if we're at the end, because there's
106
- # no last iframe to detect and trigger the final clip
107
- if i == total_frame_count - 1
108
- if verbose
109
- puts "Storing clip details: iframe_number=" + current_iframe.to_s + "; index=" + last_iframe_index.to_s + "; frame_count=" + frames_in_clip.to_s
110
- end
111
- clip_cuts[current_iframe] = {
112
- :index => last_iframe_index,
113
- :frame_count => frames_in_clip
114
- }
115
- end
116
- end
117
- end
118
-
119
- puts clip_cuts
120
-
121
- clip_cuts.keys.each do |f|
122
- out_path = output + '-' + f.to_s + '.avi'
123
- clip(clip.frames, out_path, clip_cuts[f][:index], clip_cuts[f][:frame_count])
124
- end
125
-
126
- puts "All done!"
127
- end
128
- end
129
- end
1
+ module Moshy
2
+ class ISplit
3
+ def cli(args)
4
+ opts = Slop::Options.new
5
+ opts.banner = "Usage: moshy -m isplit -i file.avi -o file_out\nmoshy -m isplit --help for details"
6
+ opts.separator 'Required Parameters:'
7
+ opts.string '-i', '--input', 'Input file path - must be an .avi.'
8
+ opts.string '-o', '--output', 'Output file path - will be appended with -#.avi for each clip.'
9
+ opts.separator 'Optional Parameters:'
10
+ opts.integer '-b', '--begin', 'Index of the I-frame at which to begin clipping (inclusive)'
11
+ opts.integer '-e', '--end', 'Index of the I-frame at which to stop clipping (inclusive)'
12
+ opts.integer '-v', '--verbose', 'Noisy output (default: false)'
13
+ opts.on '-h', '--help' do
14
+ puts opts
15
+ puts "\n"
16
+ puts \
17
+ "Extracts individual clips from an AVI where each clip is separated
18
+ by I-frames in the original AVI. Great for getting specific clips out
19
+ of a larger video and later doing I-frame moshing.
20
+
21
+ Note that since this creates multiple clips, you should NOT specify
22
+ the .avi extension in your output (-o) parameter, as moshy will
23
+ automatically append \"-#.avi\" to the output parameter you pass
24
+ when it spits out individual clips.
25
+
26
+ If you want to only cut clips from a certain section of a larger
27
+ video file, you can set the in- and out-points of where to get clips
28
+ from by using the -b (--begin) and -e (--end) options, where the
29
+ values used in those parameters are the indexes of the I-Frames.
30
+ For example, if a video file has 12 I-Frames and you want the clips
31
+ between I-Frames 3 and 7, you would use the following command:
32
+
33
+ moshy -m isplit -i file.avi -o file_out -b 3 -e 7"
34
+ exit
35
+ end
36
+
37
+ parser = Slop::Parser.new(opts)
38
+ @options = parser.parse(ARGV)
39
+ # puts @options.to_hash
40
+
41
+ # Check mandatory params
42
+ mandatory = [:input, :output]
43
+ missing = mandatory.select{ |param| @options[param].nil? }
44
+ unless missing.empty?
45
+ puts "Missing options: #{missing.join(', ')}"
46
+ puts @options
47
+ exit
48
+ end
49
+
50
+
51
+ puts "Opening file " + @options[:input] + "..."
52
+ a = AviGlitch.open @options[:input] # Rewrite this line for your file.
53
+ puts "Opened!"
54
+
55
+ split(a, @options[:output], @options[:begin], @options[:end], @options[:verbose])
56
+ end
57
+
58
+ def clip(frames, out_path, start_index, frame_count)
59
+ puts "Clipping " + frame_count.to_s + " frames starting at frame " + start_index.to_s
60
+ clip = frames.slice(start_index, frame_count)
61
+ o = AviGlitch.open clip
62
+ puts "Outputting " + out_path
63
+ o.output out_path
64
+ end
65
+
66
+ def split(clip, output, begin_point, end_point, verbose)
67
+ clip_cuts = {}
68
+
69
+ clip_count = 0
70
+ current_iframe = 0
71
+ iframe_index = 0
72
+ last_iframe_index = 0
73
+ frames_in_clip = 0
74
+
75
+ # Harvest clip details
76
+ total_frame_count = clip.frames.count
77
+ clip.frames.each_with_index do |f, i|
78
+ if f.is_keyframe?
79
+ iframe_index = i
80
+ # Don't process frames that are before our beginning
81
+ if current_iframe and begin_point and current_iframe < begin_point
82
+ # puts "skipping " + current_iframe.to_s
83
+ frames_in_clip = 0
84
+ current_iframe = current_iframe + 1
85
+ last_iframe_index = iframe_index
86
+ # puts "last_iframe_index: " + last_iframe_index.to_s
87
+ next
88
+ end
89
+ break if end_point and current_iframe > end_point
90
+
91
+ if current_iframe != 0
92
+ if verbose
93
+ puts "Storing clip details: iframe_number=" + current_iframe.to_s + "; index=" + last_iframe_index.to_s + "; frame_count=" + frames_in_clip.to_s
94
+ end
95
+ clip_cuts[current_iframe] = {
96
+ :index => last_iframe_index,
97
+ :frame_count => frames_in_clip
98
+ }
99
+ end
100
+ frames_in_clip = 0
101
+ current_iframe = current_iframe + 1
102
+ last_iframe_index = iframe_index
103
+ else
104
+ frames_in_clip = frames_in_clip + 1
105
+ # clip last piece manually if we're at the end, because there's
106
+ # no last iframe to detect and trigger the final clip
107
+ if i == total_frame_count - 1
108
+ if verbose
109
+ puts "Storing clip details: iframe_number=" + current_iframe.to_s + "; index=" + last_iframe_index.to_s + "; frame_count=" + frames_in_clip.to_s
110
+ end
111
+ clip_cuts[current_iframe] = {
112
+ :index => last_iframe_index,
113
+ :frame_count => frames_in_clip
114
+ }
115
+ end
116
+ end
117
+ end
118
+
119
+ puts clip_cuts
120
+
121
+ clip_cuts.keys.each do |f|
122
+ out_path = output + '-' + f.to_s + '.avi'
123
+ clip(clip.frames, out_path, clip_cuts[f][:index], clip_cuts[f][:frame_count])
124
+ end
125
+
126
+ puts "All done!"
127
+ end
128
+ end
129
+ end
data/lib/moshy/pdupe.rb CHANGED
@@ -1,85 +1,85 @@
1
- module Moshy
2
- class PDupe
3
- def cli(args)
4
- opts = Slop::Options.new
5
- opts.banner = "Usage: moshy -m pdupe -i file.avi -o file_out.avi -f <integer>\nmoshy -m pdupe --help for details"
6
- opts.separator 'Required Parameters:'
7
- opts.string '-i', '--input', 'Input file path - must be an .avi.'
8
- opts.string '-o', '--output', 'Output file path, should be an .avi.'
9
- opts.integer '-f', '--frame', 'Index of the frame that should be duplicated'
10
- opts.separator 'Optional Parameters:'
11
- opts.integer '-d', '--dupes', 'Number of times to multiply the frame (default: 30)'
12
- opts.on '-h', '--help' do
13
- puts opts
14
- puts "\n"
15
- puts \
16
- "Duplicates a P-frame at a given frame a certain amount. To find
17
- out which frames are P-frames, use software like avidemux to look at the
18
- frame type. WARNING: This mode is a little glitchy. You may need to set
19
- the interval 1 or 2 above or below the frame number you actually want to
20
- duplicate. I'm not sure why this happens, but try it with a small
21
- duplication amount first. NOTE: This can mode take a while to process
22
- over 60-90 frame dupes.
23
-
24
- You can specify the number of duplicates that you want with the -d parameter."
25
- exit
26
- end
27
-
28
- default = {
29
- :dupes => 30
30
- }
31
-
32
- parser = Slop::Parser.new(opts)
33
- slop_options = parser.parse(ARGV)
34
- @options = default.merge(slop_options) { |key, oldval, newval|
35
- if newval.nil?
36
- oldval
37
- else
38
- newval
39
- end
40
- }
41
-
42
- # Check mandatory params
43
- mandatory = [:input, :output, :frame]
44
- missing = mandatory.select{ |param| @options[param].nil? }
45
- unless missing.empty?
46
- puts "Missing options: #{missing.join(', ')}"
47
- puts slop_options
48
- exit
49
- end
50
-
51
- puts "Opening file " + @options[:input] + "..."
52
- a = AviGlitch.open @options[:input] # Rewrite this line for your file.
53
- puts "Opened!"
54
-
55
- pdupe(a, @options[:output], @options[:frame], @options[:dupes])
56
- end
57
-
58
- def pdupe(clip, output, frame, duplicate_amount)
59
-
60
- puts "Size: " + clip.frames.size_of('videoframe').to_s
61
-
62
- frames = nil
63
- video_frame_counter = 0
64
-
65
- clip.frames.each_with_index do |f, i|
66
- if f.is_videoframe?
67
- video_frame_counter += 1
68
- if video_frame_counter == frame
69
- puts "On frame " + frame.to_s + ", duping " + duplicate_amount.to_s + " times"
70
- clipped = clip.frames[0..(i + 5)]
71
- dupe_clip = clip.frames[(i + 4), 1] * duplicate_amount
72
- frames = clipped + dupe_clip
73
- puts "Added dupe, grabbing rest..."
74
- frames = frames + clip.frames[i..-1]
75
- puts "Done. Output frame count: " + frames.size.to_s
76
- break
77
- end
78
- end
79
- end
80
-
81
- o = AviGlitch.open frames
82
- o.output output
83
- end
84
- end
85
- end
1
+ module Moshy
2
+ class PDupe
3
+ def cli(args)
4
+ opts = Slop::Options.new
5
+ opts.banner = "Usage: moshy -m pdupe -i file.avi -o file_out.avi -f <integer>\nmoshy -m pdupe --help for details"
6
+ opts.separator 'Required Parameters:'
7
+ opts.string '-i', '--input', 'Input file path - must be an .avi.'
8
+ opts.string '-o', '--output', 'Output file path, should be an .avi.'
9
+ opts.integer '-f', '--frame', 'Index of the frame that should be duplicated'
10
+ opts.separator 'Optional Parameters:'
11
+ opts.integer '-d', '--dupes', 'Number of times to multiply the frame (default: 30)'
12
+ opts.on '-h', '--help' do
13
+ puts opts
14
+ puts "\n"
15
+ puts \
16
+ "Duplicates a P-frame at a given frame a certain amount. To find
17
+ out which frames are P-frames, use software like avidemux to look at the
18
+ frame type. WARNING: This mode is a little glitchy. You may need to set
19
+ the interval 1 or 2 above or below the frame number you actually want to
20
+ duplicate. I'm not sure why this happens, but try it with a small
21
+ duplication amount first. NOTE: This can mode take a while to process
22
+ over 60-90 frame dupes.
23
+
24
+ You can specify the number of duplicates that you want with the -d parameter."
25
+ exit
26
+ end
27
+
28
+ default = {
29
+ :dupes => 30
30
+ }
31
+
32
+ parser = Slop::Parser.new(opts)
33
+ slop_options = parser.parse(ARGV)
34
+ @options = default.merge(slop_options) { |key, oldval, newval|
35
+ if newval.nil?
36
+ oldval
37
+ else
38
+ newval
39
+ end
40
+ }
41
+
42
+ # Check mandatory params
43
+ mandatory = [:input, :output, :frame]
44
+ missing = mandatory.select{ |param| @options[param].nil? }
45
+ unless missing.empty?
46
+ puts "Missing options: #{missing.join(', ')}"
47
+ puts slop_options
48
+ exit
49
+ end
50
+
51
+ puts "Opening file " + @options[:input] + "..."
52
+ a = AviGlitch.open @options[:input] # Rewrite this line for your file.
53
+ puts "Opened!"
54
+
55
+ pdupe(a, @options[:output], @options[:frame], @options[:dupes])
56
+ end
57
+
58
+ def pdupe(clip, output, frame, duplicate_amount)
59
+
60
+ puts "Size: " + clip.frames.size_of('videoframe').to_s
61
+
62
+ frames = nil
63
+ video_frame_counter = 0
64
+
65
+ clip.frames.each_with_index do |f, i|
66
+ if f.is_videoframe?
67
+ video_frame_counter += 1
68
+ if video_frame_counter == frame
69
+ puts "On frame " + frame.to_s + ", duping " + duplicate_amount.to_s + " times"
70
+ clipped = clip.frames[0..(i + 5)]
71
+ dupe_clip = clip.frames[(i + 4), 1] * duplicate_amount
72
+ frames = clipped + dupe_clip
73
+ puts "Added dupe, grabbing rest..."
74
+ frames = frames + clip.frames[i..-1]
75
+ puts "Done. Output frame count: " + frames.size.to_s
76
+ break
77
+ end
78
+ end
79
+ end
80
+
81
+ o = AviGlitch.open frames
82
+ o.output output
83
+ end
84
+ end
85
+ end