moshy 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +22 -22
- data/DEVNOTES.md +7 -0
- data/Gemfile +4 -4
- data/LICENSE.txt +22 -22
- data/README.md +94 -71
- data/Rakefile +2 -2
- data/bin/moshy +106 -104
- data/lib/moshy/bake.rb +68 -68
- data/lib/moshy/inspect.rb +110 -110
- data/lib/moshy/isplit.rb +129 -129
- data/lib/moshy/pdupe.rb +85 -85
- data/lib/moshy/ppulse.rb +153 -153
- data/lib/moshy/prep.rb +78 -78
- data/lib/moshy/version.rb +3 -3
- data/lib/moshy.rb +13 -13
- data/moshy.gemspec +27 -27
- metadata +15 -15
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
|