vcs_ruby 1.0.1 → 1.1.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.
- data/bin/vcs.rb +4 -4
- data/lib/FFmpeg/ffmpeg.rb +141 -0
- data/lib/FFmpeg/ffmpeg_audio_stream.rb +38 -0
- data/lib/FFmpeg/ffmpeg_meta_info.rb +37 -0
- data/lib/FFmpeg/ffmpeg_video_stream.rb +52 -0
- data/lib/{mplayer.rb → MPlayer/mplayer.rb} +48 -63
- data/lib/MPlayer/mplayer_audio_stream.rb +35 -0
- data/lib/MPlayer/mplayer_meta_info.rb +40 -0
- data/lib/MPlayer/mplayer_video_stream.rb +44 -0
- data/lib/capturer.rb +17 -21
- data/lib/command.rb +4 -2
- data/lib/configuration.rb +18 -7
- data/lib/contact_sheet.rb +106 -127
- data/lib/defaults.yml +4 -4
- data/lib/font.rb +12 -12
- data/lib/{thumbnail.rb → frame.rb} +45 -24
- data/lib/libAV/libav.rb +143 -0
- data/lib/libAV/libav_audio_stream.rb +38 -0
- data/lib/libAV/libav_meta_info.rb +37 -0
- data/lib/libAV/libav_video_stream.rb +52 -0
- data/lib/stream.rb +24 -0
- data/lib/tools.rb +13 -20
- data/lib/vcs.rb +16 -4
- data/lib/version.info +1 -1
- data/lib/version.rb +2 -2
- data/lib/video.rb +89 -0
- metadata +37 -8
- data/lib/ffmpeg.rb +0 -183
- data/lib/libav.rb +0 -181
@@ -1,59 +1,76 @@
|
|
1
1
|
#
|
2
|
-
#
|
2
|
+
# Frame from video
|
3
3
|
#
|
4
4
|
|
5
5
|
require 'mini_magick'
|
6
6
|
|
7
7
|
module VCSRuby
|
8
|
-
class
|
8
|
+
class Frame
|
9
9
|
attr_accessor :width, :height, :aspect
|
10
|
-
|
11
|
-
attr_accessor :time
|
12
|
-
attr_reader :filters
|
10
|
+
attr_reader :filters, :time
|
13
11
|
|
14
|
-
def initialize
|
15
|
-
@capper = capper
|
12
|
+
def initialize video, capturer, time
|
16
13
|
@video = video
|
17
|
-
@
|
14
|
+
@capturer = capturer
|
15
|
+
@time = time
|
18
16
|
@filters = []
|
19
17
|
end
|
20
18
|
|
19
|
+
def filename= file_path
|
20
|
+
@out_path = File.dirname(file_path)
|
21
|
+
@out_filename = File.basename(file_path,'.*')
|
22
|
+
end
|
23
|
+
|
24
|
+
def filename
|
25
|
+
File.join(@out_path, "#{@out_filename}.#{@capturer.format_extension}")
|
26
|
+
end
|
27
|
+
|
28
|
+
def format= fmt
|
29
|
+
@capturer.format = fmt
|
30
|
+
end
|
31
|
+
|
32
|
+
def format
|
33
|
+
@capturer.format
|
34
|
+
end
|
35
|
+
|
21
36
|
def capture
|
22
|
-
@
|
37
|
+
@capturer.grab @time, filename
|
23
38
|
end
|
24
39
|
|
25
|
-
def capture_and_evade interval
|
26
|
-
times = [TimeIndex.new] +
|
27
|
-
|
40
|
+
def capture_and_evade interval = nil
|
41
|
+
times = [TimeIndex.new] + Configuration.instance.blank_alternatives
|
42
|
+
if interval
|
43
|
+
times.select! { |t| (t < interval / 2) and (t > interval / -2) }
|
44
|
+
end
|
28
45
|
times.map! { |t| @time + t }
|
29
46
|
|
30
47
|
times.each do |time|
|
31
48
|
@time = time
|
32
49
|
capture
|
33
50
|
break unless blank?
|
34
|
-
puts "Blank frame detected. => #{@time}" unless
|
35
|
-
puts "Giving up!" if time == times.last && !
|
51
|
+
puts "Blank frame detected. => #{@time}" unless Configuration.instance.quiet?
|
52
|
+
puts "Giving up!" if time == times.last && !Configuration.instance.quiet?
|
36
53
|
end
|
37
54
|
end
|
38
55
|
|
39
56
|
def blank?
|
40
|
-
image = MiniMagick::Image.open
|
57
|
+
image = MiniMagick::Image.open filename
|
41
58
|
image.colorspace 'Gray'
|
42
59
|
mean = image['%[fx:image.mean]'].to_f
|
43
|
-
return mean <
|
60
|
+
return mean < Configuration.instance.blank_threshold
|
44
61
|
end
|
45
62
|
|
46
63
|
def apply_filters
|
47
64
|
MiniMagick::Tool::Convert.new do |convert|
|
48
65
|
convert.background 'Transparent'
|
49
66
|
convert.fill 'Transparent'
|
50
|
-
convert <<
|
67
|
+
convert << filename
|
51
68
|
|
52
69
|
sorted_filters.each do |filter|
|
53
70
|
call_filter filter, convert
|
54
71
|
end
|
55
72
|
|
56
|
-
convert <<
|
73
|
+
convert << filename
|
57
74
|
end
|
58
75
|
end
|
59
76
|
|
@@ -76,12 +93,12 @@ private
|
|
76
93
|
|
77
94
|
def timestamp_filter convert
|
78
95
|
convert.stack do |box|
|
79
|
-
box.box
|
80
|
-
box.fill
|
81
|
-
box.pointsize
|
96
|
+
box.box Configuration.instance.timestamp_background
|
97
|
+
box.fill Configuration.instance.timestamp_color
|
98
|
+
box.pointsize Configuration.instance.timestamp_font.size
|
82
99
|
box.gravity 'SouthEast'
|
83
|
-
if
|
84
|
-
box.font
|
100
|
+
if Configuration.instance.timestamp_font.exists?
|
101
|
+
box.font Configuration.instance.timestamp_font.path
|
85
102
|
end
|
86
103
|
box.annotate('+10+10', " #{@time.to_timestamp} ")
|
87
104
|
end
|
@@ -115,7 +132,11 @@ private
|
|
115
132
|
a.fill 'White'
|
116
133
|
a.background 'White'
|
117
134
|
a.bordercolor 'White'
|
118
|
-
|
135
|
+
if Tools.magick_version.major > 6
|
136
|
+
a.alpha_color 'White'
|
137
|
+
else
|
138
|
+
a.mattecolor 'White'
|
139
|
+
end
|
119
140
|
a.frame "#{border}x#{border}"
|
120
141
|
a.stack do |b|
|
121
142
|
b.flip
|
data/lib/libAV/libav.rb
ADDED
@@ -0,0 +1,143 @@
|
|
1
|
+
#
|
2
|
+
# libAV Abstraction
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'capturer'
|
6
|
+
require 'command'
|
7
|
+
|
8
|
+
module VCSRuby
|
9
|
+
class LibAV < Capturer
|
10
|
+
|
11
|
+
HEADER = 10
|
12
|
+
|
13
|
+
ENCODING_SUPPORT = 2
|
14
|
+
VIDEO_CODEC = 3
|
15
|
+
NAME = 8
|
16
|
+
|
17
|
+
attr_reader :info, :video_streams, :audio_streams
|
18
|
+
|
19
|
+
def initialize video
|
20
|
+
@video = video
|
21
|
+
@avconv = Command.new :libav, 'avconv'
|
22
|
+
@avprobe = Command.new :libav, 'avprobe'
|
23
|
+
|
24
|
+
detect_version if available?
|
25
|
+
end
|
26
|
+
|
27
|
+
def file_valid?
|
28
|
+
return probe_meta_information
|
29
|
+
end
|
30
|
+
|
31
|
+
def name
|
32
|
+
:libav
|
33
|
+
end
|
34
|
+
|
35
|
+
def available?
|
36
|
+
@avconv.available? && @avprobe.available?
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
def detect_version
|
41
|
+
info = @avconv.execute('-version')
|
42
|
+
match = /avconv ([\d|.|-|:]*)/.match(info)
|
43
|
+
if match
|
44
|
+
@version = match[1]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
|
50
|
+
def grab time, image_path
|
51
|
+
@avconv.execute "-y -ss #{time.total_seconds} -i \"#{@video.full_path}\" -an -dframes 1 -vframes 1 -vcodec #{format} -f rawvideo \"#{image_path}\""
|
52
|
+
end
|
53
|
+
|
54
|
+
def available_formats
|
55
|
+
# Ordered by priority
|
56
|
+
image_formats = ['png', 'tiff', 'bmp', 'mjpeg']
|
57
|
+
formats = []
|
58
|
+
|
59
|
+
list = @avprobe.execute "-codecs"
|
60
|
+
list.lines.drop(HEADER).each do |codec|
|
61
|
+
name, e, v = format_split(codec)
|
62
|
+
formats << name if image_formats.include?(name) && e && v
|
63
|
+
end
|
64
|
+
|
65
|
+
image_formats.select{ |format| formats.include?(format) }.map(&:to_sym)
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
"LibAV #{@version}"
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
def format_split line
|
74
|
+
correction = 0
|
75
|
+
unless line[0] == ' '
|
76
|
+
correction = 1
|
77
|
+
end
|
78
|
+
e = line[ENCODING_SUPPORT - correction] == 'E'
|
79
|
+
v = line[VIDEO_CODEC - correction] == 'V'
|
80
|
+
|
81
|
+
name = line[NAME-correction..-1].split(' ', 2).first
|
82
|
+
return name, e, v
|
83
|
+
rescue
|
84
|
+
return nil, false, false
|
85
|
+
end
|
86
|
+
|
87
|
+
def probe_meta_information
|
88
|
+
check_cache
|
89
|
+
parse_meta_info
|
90
|
+
return true
|
91
|
+
rescue Exception => e
|
92
|
+
puts e
|
93
|
+
return false
|
94
|
+
end
|
95
|
+
|
96
|
+
def check_cache
|
97
|
+
unless @cache
|
98
|
+
@cache = @avprobe.execute("\"#{@video.full_path}\" -show_format -show_streams", "2>&1")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def get_hash defines
|
103
|
+
result = {}
|
104
|
+
defines.lines.each do |line|
|
105
|
+
kv = line.split("=")
|
106
|
+
result[kv[0].strip] = kv[1].strip if kv.count == 2
|
107
|
+
end
|
108
|
+
result
|
109
|
+
end
|
110
|
+
|
111
|
+
def parse_meta_info
|
112
|
+
parse_format
|
113
|
+
parse_audio_streams
|
114
|
+
parse_video_streams
|
115
|
+
end
|
116
|
+
|
117
|
+
def parse_format
|
118
|
+
@cache.scan(/\[FORMAT\](.*?)\[\/FORMAT\]/m) do |format|
|
119
|
+
@info = LibAVMetaInfo.new(get_hash(format[0]))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def parse_audio_streams
|
124
|
+
@audio_streams = []
|
125
|
+
@cache.scan(/\[STREAM\](.*?)\[\/STREAM\]/m) do |stream|
|
126
|
+
info = get_hash(stream[0])
|
127
|
+
if info['codec_type'] == 'audio'
|
128
|
+
@audio_streams << LibAVAudioStream.new(info)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def parse_video_streams
|
134
|
+
@video_streams = []
|
135
|
+
@cache.scan(/\[STREAM\](.*?)\[\/STREAM\]/m) do |stream|
|
136
|
+
info = get_hash(stream[0])
|
137
|
+
if info['codec_type'] == 'video'
|
138
|
+
@video_streams << LibAVVideoStream.new(info)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#
|
2
|
+
# Implementes AudioStream Interface for libAV
|
3
|
+
#
|
4
|
+
|
5
|
+
# AudioStream = Struct.new(:codec, :channels, :channel_layout, :sample_rate, :bit_rate, :raw)
|
6
|
+
module VCSRuby
|
7
|
+
class LibAVAudioStream
|
8
|
+
attr_reader :raw
|
9
|
+
|
10
|
+
def initialize audio_stream
|
11
|
+
@raw = audio_stream
|
12
|
+
end
|
13
|
+
|
14
|
+
def codec short = false
|
15
|
+
if short
|
16
|
+
@raw['codec_name']
|
17
|
+
else
|
18
|
+
@raw['codec_long_name']
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def channels
|
23
|
+
@raw['channels'].to_i
|
24
|
+
end
|
25
|
+
|
26
|
+
def channel_layout
|
27
|
+
@raw['channel_layout']
|
28
|
+
end
|
29
|
+
|
30
|
+
def sample_rate
|
31
|
+
@raw['sample_rate'].to_i
|
32
|
+
end
|
33
|
+
|
34
|
+
def bit_rate
|
35
|
+
@raw['bit_rate'].to_i
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#
|
2
|
+
# Implementes MetaInfo Interface for libAV
|
3
|
+
#
|
4
|
+
|
5
|
+
# MetaInformation = Struct.new(:duration, :bit_rate, :size, :format, :extension, :raw)
|
6
|
+
|
7
|
+
require_relative '../time_index'
|
8
|
+
|
9
|
+
module VCSRuby
|
10
|
+
class LibAVMetaInfo
|
11
|
+
attr_reader :raw
|
12
|
+
|
13
|
+
def initialize meta_info
|
14
|
+
@raw = meta_info
|
15
|
+
end
|
16
|
+
|
17
|
+
def duration
|
18
|
+
TimeIndex.new(@raw['duration'].to_f)
|
19
|
+
end
|
20
|
+
|
21
|
+
def bit_rate
|
22
|
+
@raw['bit_rate'].to_i
|
23
|
+
end
|
24
|
+
|
25
|
+
def size
|
26
|
+
@raw['size'].to_i
|
27
|
+
end
|
28
|
+
|
29
|
+
def format
|
30
|
+
@raw['format_long_name']
|
31
|
+
end
|
32
|
+
|
33
|
+
def extension
|
34
|
+
@raw['format_name']
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#
|
2
|
+
# Implementes VideoStream Interface for libAV
|
3
|
+
#
|
4
|
+
|
5
|
+
# VideoStream = Struct.new(:width, :height, :codec, :color_space, :bit_rate, :frame_rate, :aspect_ratio, :raw)
|
6
|
+
|
7
|
+
module VCSRuby
|
8
|
+
class LibAVVideoStream
|
9
|
+
attr_reader :raw
|
10
|
+
|
11
|
+
def initialize video_stream
|
12
|
+
@raw = video_stream
|
13
|
+
end
|
14
|
+
|
15
|
+
def width
|
16
|
+
@raw['width'].to_i
|
17
|
+
end
|
18
|
+
|
19
|
+
def height
|
20
|
+
@raw['height'].to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
def codec short = false
|
24
|
+
if short
|
25
|
+
@raw['codec_name']
|
26
|
+
else
|
27
|
+
@raw['codec_long_name']
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def color_space
|
32
|
+
if ["unknown", "", nil].include? @raw['color_space']
|
33
|
+
@raw['pix_fmt']
|
34
|
+
else
|
35
|
+
@raw['color_space']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def bit_rate
|
40
|
+
@raw['bit_rate'].to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def frame_rate
|
45
|
+
Rational(@raw['r_frame_rate'])
|
46
|
+
end
|
47
|
+
|
48
|
+
def aspect_ratio
|
49
|
+
@raw['display_aspect_ratio']
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/stream.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
#
|
2
|
+
# Represents a stream in a video
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'vcs'
|
6
|
+
|
7
|
+
module VCSRuby
|
8
|
+
class Stream
|
9
|
+
def initialize stream
|
10
|
+
@stream = stream
|
11
|
+
create_accessors
|
12
|
+
end
|
13
|
+
|
14
|
+
def create_accessors
|
15
|
+
@stream.each do |key, value|
|
16
|
+
self.class.send :define_method, key.to_sym do
|
17
|
+
return @stream[key]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
end
|
24
|
+
end
|
data/lib/tools.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
#
|
4
4
|
|
5
5
|
module VCSRuby
|
6
|
+
|
6
7
|
class Tools
|
7
8
|
def self.windows?
|
8
9
|
return ((RUBY_PLATFORM =~ /win32/ or RUBY_PLATFORM =~ /mingw32/) or (RbConfig::CONFIG['host_os'] =~ /mswin|windows/i))
|
@@ -12,24 +13,6 @@ module VCSRuby
|
|
12
13
|
return ((RUBY_PLATFORM =~ /linux/) or (RbConfig::CONFIG['host_os'] =~ /linux/i))
|
13
14
|
end
|
14
15
|
|
15
|
-
def self.verbose= verbose
|
16
|
-
@verbose = verbose
|
17
|
-
@quiet = false if @verbose
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.verbose?
|
21
|
-
@verbose
|
22
|
-
end
|
23
|
-
|
24
|
-
def self.quiet= quiet
|
25
|
-
@quiet = quiet
|
26
|
-
@verbose = false if @quiet
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.quiet?
|
30
|
-
@quiet
|
31
|
-
end
|
32
|
-
|
33
16
|
def self.list_arguments arguments
|
34
17
|
arguments.map{ |argument| argument.to_s }.join(', ')
|
35
18
|
end
|
@@ -39,10 +22,20 @@ module VCSRuby
|
|
39
22
|
exit 0
|
40
23
|
end
|
41
24
|
|
25
|
+
MagickVersion = Struct.new(:major, :minor, :revision)
|
26
|
+
def self.magick_version
|
27
|
+
output = %x[convert -version]
|
28
|
+
m = output.match /(\d+)\.(\d+)\.(\d+)(-(\d+))?/
|
29
|
+
MagickVersion.new(m[1].to_i, m[2].to_i, m[3].to_i)
|
30
|
+
end
|
31
|
+
|
42
32
|
def self.contact_sheet_with_options video, options
|
43
|
-
|
33
|
+
Configuration.instance.load_profile options[:profile] if options[:profile]
|
34
|
+
Configuration.instance.capturer = options[:capturer]
|
35
|
+
|
36
|
+
video = VCSRuby::Video.new video
|
37
|
+
sheet = video.contact_sheet
|
44
38
|
|
45
|
-
sheet.capturer = options[:capturer]
|
46
39
|
sheet.format = options[:format] if options[:format]
|
47
40
|
sheet.title = options[:title] if options[:title]
|
48
41
|
sheet.signature = options[:signature] if options[:signature]
|
data/lib/vcs.rb
CHANGED
@@ -2,13 +2,25 @@
|
|
2
2
|
# Video Contact Sheet Ruby
|
3
3
|
#
|
4
4
|
|
5
|
+
$LOAD_PATH.unshift(File.expand_path(File.dirname(__FILE__))) unless $LOAD_PATH.include?(File.expand_path(File.dirname(__FILE__)))
|
6
|
+
|
5
7
|
require 'command'
|
6
8
|
require 'configuration'
|
7
9
|
require 'contact_sheet'
|
8
|
-
require '
|
9
|
-
require '
|
10
|
-
require 'mplayer'
|
11
|
-
require 'thumbnail'
|
10
|
+
require 'video'
|
11
|
+
require 'frame'
|
12
12
|
require 'time_index'
|
13
13
|
require 'tools'
|
14
14
|
require 'version'
|
15
|
+
require 'FFmpeg/ffmpeg'
|
16
|
+
require 'FFmpeg/ffmpeg_audio_stream'
|
17
|
+
require 'FFmpeg/ffmpeg_video_stream'
|
18
|
+
require 'FFmpeg/ffmpeg_meta_info'
|
19
|
+
require 'libAV/libav'
|
20
|
+
require 'libAV/libav_audio_stream'
|
21
|
+
require 'libAV/libav_video_stream'
|
22
|
+
require 'libAV/libav_meta_info'
|
23
|
+
require 'MPlayer/mplayer'
|
24
|
+
require 'MPlayer/mplayer_audio_stream'
|
25
|
+
require 'MPlayer/mplayer_video_stream'
|
26
|
+
require 'MPlayer/mplayer_meta_info'
|
data/lib/version.info
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.1.1
|
data/lib/version.rb
CHANGED
@@ -12,11 +12,11 @@ module VCSRuby
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.update_version
|
15
|
+
current_version = read_version
|
15
16
|
parts = File.open(version_path, &:readline).split('.').map(&:strip)
|
16
17
|
parts[2] = (parts[2].to_i + 1).to_s
|
17
18
|
File.open(version_path, 'w') {|f| f.write(parts.join('.')) }
|
18
|
-
|
19
|
-
read_version
|
19
|
+
current_version
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
data/lib/video.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#
|
2
|
+
# Represents the video file
|
3
|
+
#
|
4
|
+
|
5
|
+
require 'vcs'
|
6
|
+
|
7
|
+
module VCSRuby
|
8
|
+
class Video
|
9
|
+
attr_reader :config
|
10
|
+
|
11
|
+
def initialize video
|
12
|
+
initialize_filename video
|
13
|
+
initialize_capturers
|
14
|
+
end
|
15
|
+
|
16
|
+
def valid?
|
17
|
+
capturer.file_valid?
|
18
|
+
end
|
19
|
+
|
20
|
+
def info
|
21
|
+
capturer.info
|
22
|
+
end
|
23
|
+
|
24
|
+
def video
|
25
|
+
capturer.video_streams.first
|
26
|
+
end
|
27
|
+
|
28
|
+
def video_streams
|
29
|
+
capturer.video_streams
|
30
|
+
end
|
31
|
+
|
32
|
+
def audio
|
33
|
+
capturer.audio_streams.first
|
34
|
+
end
|
35
|
+
|
36
|
+
def audio_streams
|
37
|
+
capturer.audio_streams
|
38
|
+
end
|
39
|
+
|
40
|
+
def full_path
|
41
|
+
File.join(@path, @filename)
|
42
|
+
end
|
43
|
+
|
44
|
+
def contact_sheet
|
45
|
+
@contact_sheet ||= ContactSheet.new self, capturer
|
46
|
+
end
|
47
|
+
|
48
|
+
def frame time_index
|
49
|
+
return Frame.new self, capturer, time_index
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
def initialize_filename video
|
54
|
+
@path = File.dirname(File.absolute_path(video))
|
55
|
+
@filename = File.basename(video)
|
56
|
+
end
|
57
|
+
|
58
|
+
def initialize_capturers
|
59
|
+
@capturers = []
|
60
|
+
|
61
|
+
@capturers << LibAV.new(self)
|
62
|
+
@capturers << MPlayer.new(self)
|
63
|
+
@capturers << FFmpeg.new(self)
|
64
|
+
|
65
|
+
if Configuration.instance.verbose?
|
66
|
+
puts "Available capturers: #{available_capturers.map{ |c| c.to_s }.join(', ')}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def available_capturers
|
71
|
+
@capturers.select{ |c| c.available? }
|
72
|
+
end
|
73
|
+
|
74
|
+
def capturer
|
75
|
+
result = nil
|
76
|
+
if Configuration.instance.capturer == :any
|
77
|
+
result = available_capturers.first
|
78
|
+
else
|
79
|
+
result = available_capturers.select{ |c| c.name == Configuration.instance.capturer }.first
|
80
|
+
end
|
81
|
+
|
82
|
+
unless result
|
83
|
+
raise "Selected Capturer (#{Configuration.instance.capturer}) not available. Install one of these: #{@capturers.map{ |c| c.name }.join(', ')}"
|
84
|
+
end
|
85
|
+
|
86
|
+
return result
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|