videoreg 0.1
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/.gitignore +10 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +42 -0
- data/README.md +205 -0
- data/Rakefile +34 -0
- data/bin/videoreg +109 -0
- data/dist/videoreg-0.1.gem +0 -0
- data/install.sh +39 -0
- data/lib/videoreg.rb +232 -0
- data/lib/videoreg/base.rb +41 -0
- data/lib/videoreg/config.rb +55 -0
- data/lib/videoreg/lockfile.rb +100 -0
- data/lib/videoreg/registrar.rb +196 -0
- data/lib/videoreg/util.rb +80 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/videoreg/lockfile_spec.rb +26 -0
- data/spec/videoreg/registrar_spec.rb +33 -0
- data/spec/videoreg_spec.rb +16 -0
- data/videoreg-sample-config.rb +38 -0
- data/videoreg-sample.god +22 -0
- data/videoreg.gemspec +26 -0
- metadata +162 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
amq-client (0.9.3)
|
5
|
+
amq-protocol (>= 0.9.1)
|
6
|
+
eventmachine
|
7
|
+
amq-protocol (0.9.3)
|
8
|
+
amqp (0.9.6)
|
9
|
+
amq-client (~> 0.9.3)
|
10
|
+
amq-protocol (>= 0.9.1)
|
11
|
+
eventmachine
|
12
|
+
dante (0.1.5)
|
13
|
+
diff-lcs (1.1.3)
|
14
|
+
eventmachine (0.12.10)
|
15
|
+
god (0.12.1)
|
16
|
+
json (1.7.3)
|
17
|
+
multi_json (1.3.6)
|
18
|
+
open4 (1.3.0)
|
19
|
+
rspec (2.10.0)
|
20
|
+
rspec-core (~> 2.10.0)
|
21
|
+
rspec-expectations (~> 2.10.0)
|
22
|
+
rspec-mocks (~> 2.10.0)
|
23
|
+
rspec-core (2.10.1)
|
24
|
+
rspec-expectations (2.10.0)
|
25
|
+
diff-lcs (~> 1.1.3)
|
26
|
+
rspec-mocks (2.10.1)
|
27
|
+
simplecov (0.6.4)
|
28
|
+
multi_json (~> 1.0)
|
29
|
+
simplecov-html (~> 0.5.3)
|
30
|
+
simplecov-html (0.5.3)
|
31
|
+
|
32
|
+
PLATFORMS
|
33
|
+
ruby
|
34
|
+
|
35
|
+
DEPENDENCIES
|
36
|
+
amqp
|
37
|
+
dante
|
38
|
+
god
|
39
|
+
json
|
40
|
+
open4
|
41
|
+
rspec
|
42
|
+
simplecov
|
data/README.md
ADDED
@@ -0,0 +1,205 @@
|
|
1
|
+
## Videoreg: script for continuous video recording from the plugged webcams
|
2
|
+
|
3
|
+
### Prerequisites: you will need to install the required libraries
|
4
|
+
|
5
|
+
RabbitMQ and Ruby are required to use this script.
|
6
|
+
|
7
|
+
```bash
|
8
|
+
sudo echo "deb http://www.rabbitmq.com/debian/ testing main" >> /etc/apt/sources.list
|
9
|
+
sudo wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
|
10
|
+
sudo apt-key add rabbitmq-signing-key-public.asc
|
11
|
+
sudo apt-get update
|
12
|
+
apt-get install -y mencoder ffmpeg qc-usb-utils v4l-utils rabbitmq-server ruby1.9.1 rubygems ruby1.9.1-dev
|
13
|
+
```
|
14
|
+
|
15
|
+
### Then write the configuration file according to your setup:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
reg {
|
19
|
+
device '/dev/webcam0'
|
20
|
+
resolution '640x480'
|
21
|
+
fps 25
|
22
|
+
duration 60
|
23
|
+
filename '#{time}-webcam0.avi'
|
24
|
+
storage '/tmp/webcam0'
|
25
|
+
lockfile '/tmp/videoreg.webcam0.lock'
|
26
|
+
store_max 5
|
27
|
+
}
|
28
|
+
|
29
|
+
reg {
|
30
|
+
device '/dev/webcam1'
|
31
|
+
resolution '640x480'
|
32
|
+
fps 25
|
33
|
+
duration 60
|
34
|
+
filename '#{time}-webcam1.avi'
|
35
|
+
storage '/tmp/webcam1'
|
36
|
+
lockfile '/tmp/videoreg.webcam1.lock'
|
37
|
+
store_max 3
|
38
|
+
}
|
39
|
+
|
40
|
+
reg {
|
41
|
+
device '/dev/webcam2'
|
42
|
+
resolution '640x480'
|
43
|
+
fps 25
|
44
|
+
duration 60
|
45
|
+
filename '#{time}-webcam2.avi'
|
46
|
+
storage '/tmp/webcam2'
|
47
|
+
lockfile '/tmp/videoreg.webcam2.lock'
|
48
|
+
store_max 3
|
49
|
+
}
|
50
|
+
|
51
|
+
log_path '/tmp/videoreg.log'
|
52
|
+
pid_path '/tmp/videoreg.pid'
|
53
|
+
mq_queue 'com.ifree.videoreg.daemon'
|
54
|
+
mq_host 'localhost'
|
55
|
+
```
|
56
|
+
|
57
|
+
### After the installation you are able to manage the process using 'videoreg' command:
|
58
|
+
|
59
|
+
```
|
60
|
+
$ videoreg -h
|
61
|
+
Usage: videoreg [options]
|
62
|
+
-c, --config CONFIG Use the specified config
|
63
|
+
-d, --device DEVICE Run only the specified device
|
64
|
+
-H, --halt DEVICE Halt (SIGKILL) recording process
|
65
|
+
-P, --pause DEVICE Pause (SIGSTOP) recording process
|
66
|
+
-R, --resume DEVICE Resume (SIGCONT) recording process
|
67
|
+
-r, --recover DEVICE Recover the recording process
|
68
|
+
-p, --pid PID Set the PID file for the capture process
|
69
|
+
-l, --log LOGFILE Set the logfile for daemon
|
70
|
+
-e, --ensure Check the state of the daemon
|
71
|
+
-C, --clear Clear the state (remove lock-files)
|
72
|
+
-k, --kill Kills the capture processes
|
73
|
+
-v, --version Show the version
|
74
|
+
-h, --help Show this help message
|
75
|
+
-U, --udev Generate udev rules for current config
|
76
|
+
-I, --info Show info about plugged devices
|
77
|
+
```
|
78
|
+
### To get the current daemon status:
|
79
|
+
|
80
|
+
```
|
81
|
+
$ videoreg -c config.rb -e
|
82
|
+
Running command 'ensure' for device(s): 'all'...
|
83
|
+
DAEMON: [RUNNING]
|
84
|
+
Uptime: 4sec
|
85
|
+
/dev/webcam0: [RUNNING]
|
86
|
+
/dev/webcam1: [RUNNING]
|
87
|
+
/dev/webcam2: [NO DEVICE]
|
88
|
+
```
|
89
|
+
### To run the daemon:
|
90
|
+
|
91
|
+
```
|
92
|
+
$ videoreg -c config.rb
|
93
|
+
Daemon has started successfully
|
94
|
+
```
|
95
|
+
### To stop the daemon:
|
96
|
+
|
97
|
+
```
|
98
|
+
$ videoreg -c config.rb --k
|
99
|
+
Stopped PID: 3870 at /tmp/videoreg.pid
|
100
|
+
```
|
101
|
+
### To stop recording from the specified device:
|
102
|
+
|
103
|
+
```
|
104
|
+
$ videoreg -c config.rb -H /dev/webcam0
|
105
|
+
Running command 'halt' for device(s): '/dev/webcam0'...
|
106
|
+
I, [2012-07-03T14:00:35.802428 #8115] INFO -- : Publish message to RabbitMQ 'HALT' with arg '/dev/webcam0' to 'com.ifree.videoreg.daemon'...
|
107
|
+
I, [2012-07-03T14:00:36.347704 #8115] INFO -- : Disconnecting from RabbitMQ...
|
108
|
+
|
109
|
+
$ videoreg -c config.rb -e
|
110
|
+
Running command 'ensure' for device(s): 'all'...
|
111
|
+
DAEMON: [RUNNING]
|
112
|
+
Uptime: 1min 18sec
|
113
|
+
/dev/webcam0: [NOT RUNNING]
|
114
|
+
/dev/webcam1: [RUNNING]
|
115
|
+
/dev/webcam2: [NO DEVICE]
|
116
|
+
```
|
117
|
+
### To run recording from the specified device:
|
118
|
+
|
119
|
+
```
|
120
|
+
$ videoreg -c config.rb -r /dev/webcam0
|
121
|
+
Running command 'recover' for device(s): '/dev/webcam0'...
|
122
|
+
I, [2012-07-03T14:02:12.375352 #8193] INFO -- : Publish message to RabbitMQ 'RECOVER' with arg '/dev/webcam0' to 'com.ifree.videoreg.daemon'...
|
123
|
+
I, [2012-07-03T14:02:12.920787 #8193] INFO -- : Disconnecting from RabbitMQ...
|
124
|
+
|
125
|
+
$ videoreg -c config.rb -e
|
126
|
+
Running command 'ensure' for device(s): 'all'...
|
127
|
+
DAEMON: [RUNNING]
|
128
|
+
Uptime: 2min 34sec
|
129
|
+
/dev/webcam0: [RUNNING]
|
130
|
+
/dev/webcam1: [RUNNING]
|
131
|
+
/dev/webcam2: [NO DEVICE]
|
132
|
+
```
|
133
|
+
### To pause the device:
|
134
|
+
|
135
|
+
```
|
136
|
+
$ videoreg -c config.rb -P /dev/webcam0
|
137
|
+
Running command 'pause' for device(s): '/dev/webcam0'...
|
138
|
+
I, [2012-07-03T14:03:28.840693 #8254] INFO -- : Publish message to RabbitMQ 'PAUSE' with arg '/dev/webcam0' to 'com.ifree.videoreg.daemon'...
|
139
|
+
I, [2012-07-03T14:03:29.386111 #8254] INFO -- : Disconnecting from RabbitMQ...
|
140
|
+
|
141
|
+
$ videoreg -c config.rb -e
|
142
|
+
Running command 'ensure' for device(s): 'all'...
|
143
|
+
DAEMON: [RUNNING]
|
144
|
+
Uptime: 3min 50sec
|
145
|
+
/dev/webcam0: [PAUSED]
|
146
|
+
/dev/webcam1: [RUNNING]
|
147
|
+
/dev/webcam2: [NO DEVICE]
|
148
|
+
```
|
149
|
+
### To resume the device:
|
150
|
+
|
151
|
+
```
|
152
|
+
$ videoreg -c config.rb -R /dev/webcam0
|
153
|
+
Running command 'resume' for device(s): '/dev/webcam0'...
|
154
|
+
I, [2012-07-03T14:04:34.870130 #8308] INFO -- : Publish message to RabbitMQ 'RESUME' with arg '/dev/webcam0' to 'com.ifree.videoreg.daemon'...
|
155
|
+
I, [2012-07-03T14:04:35.415852 #8308] INFO -- : Disconnecting from RabbitMQ...
|
156
|
+
|
157
|
+
$ videoreg -c config.rb -e
|
158
|
+
Running command 'ensure' for device(s): 'all'...
|
159
|
+
DAEMON: [RUNNING]
|
160
|
+
Uptime: 4min 58sec
|
161
|
+
/dev/webcam0: [RUNNING]
|
162
|
+
/dev/webcam1: [RUNNING]
|
163
|
+
/dev/webcam2: [NO DEVICE]
|
164
|
+
```
|
165
|
+
### Get the information about the plugged webcams:
|
166
|
+
|
167
|
+
```
|
168
|
+
$ videoreg -I
|
169
|
+
usb1[1-1] --> /dev/webcam0
|
170
|
+
usb2[2-1] --> /dev/webcam1
|
171
|
+
```
|
172
|
+
### To generate the udev rules file (create the user-friendly symlinks to the webcam devices):
|
173
|
+
|
174
|
+
```
|
175
|
+
$ videoreg -U
|
176
|
+
Writing the rules to /etc/udev/rules.d/50-udev-videoreg.rules file:
|
177
|
+
BUS=="usb" ACTION=="add" DEVPATH=="/devices/pci0000:00/0000:00:1a.0/usb1/1-1/*/video4linux/video*" SYMLINK+="webcam0" GROUP="video"
|
178
|
+
BUS=="usb" ACTION=="add" DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb2/2-1/*/video4linux/video*" SYMLINK+="webcam1" GROUP="video"
|
179
|
+
File has been written successfully! Now restart udev (/etc/init.d/udev restart) and replug the webcams!
|
180
|
+
```
|
181
|
+
|
182
|
+
# Changelog
|
183
|
+
|
184
|
+
## 03.07.2012
|
185
|
+
### Current status
|
186
|
+
* Реализация правил udev (добавление симлинков на девайсы по определённым правилам)
|
187
|
+
|
188
|
+
## 29.06.2012
|
189
|
+
### Current status
|
190
|
+
* Проверка наличия всех девайсов (камер)
|
191
|
+
* По команде прервать запись с определенной камеры и начать заново (это нужно чтобы вытащить кадр из текущего кусочка записи)
|
192
|
+
* "Ленивая" инициализация заданной камеры: пауза/запуск процесса записи
|
193
|
+
|
194
|
+
## 28.06.2012
|
195
|
+
### Current status
|
196
|
+
* Запуск видеозаписи
|
197
|
+
* Параметры для всех камер хранятся в одном конфиге (разрешение, фпс, длительность каждого файла)
|
198
|
+
* Запись по кускам (по 10минут в один файл например)
|
199
|
+
* Слежение
|
200
|
+
|
201
|
+
### TODO
|
202
|
+
* Состояние системы (свободное место на винте, время работы с момента последней перезагрузки и тп) – тоже в конфиге как-то хранить
|
203
|
+
* Слежение за свободным местом на диске (например записи с камер 1 и 2 должны хранится 12 часов, но все вместе не более 15Гб)
|
204
|
+
* Алерты об ошибках в Приложение1
|
205
|
+
* Запуск Приложения3 – при появлении файлов с определенной камеры надо запускать нашу программку (Приложение2), потом файлик удалять (или не удалять – параметр в конфиге)
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
require_relative 'lib/videoreg'
|
3
|
+
|
4
|
+
task :default => :help
|
5
|
+
|
6
|
+
desc "Build gem"
|
7
|
+
task :install do
|
8
|
+
%x[gem build videoreg.gemspec]
|
9
|
+
%x[sudo gem install #{Dir["*.gem"].sort.last}]
|
10
|
+
end
|
11
|
+
|
12
|
+
desc "Run specs"
|
13
|
+
task :spec do
|
14
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
15
|
+
t.pattern = './spec/**/*_spec.rb'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Show help menu"
|
20
|
+
task :help do
|
21
|
+
puts "Available rake tasks: "
|
22
|
+
puts "rake spec - Run specs and calculate coverage"
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
desc "Capture the video from the device"
|
27
|
+
task :videoreg, :device, :duration, :storage do |t, args|
|
28
|
+
Videoreg::Registrar.new do |c|
|
29
|
+
c.device = args[:device]
|
30
|
+
c.duration = args[:duration]
|
31
|
+
c.storage = args[:storage]
|
32
|
+
end.continuous
|
33
|
+
end
|
34
|
+
|
data/bin/videoreg
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ostruct'
|
5
|
+
require 'optparse'
|
6
|
+
require 'dante'
|
7
|
+
require_relative '../lib/videoreg'
|
8
|
+
|
9
|
+
|
10
|
+
def colorize(text, color)
|
11
|
+
"\e[#{color}m#{text}\e[0m"
|
12
|
+
end
|
13
|
+
|
14
|
+
def red(text)
|
15
|
+
colorize(text, 31)
|
16
|
+
end
|
17
|
+
|
18
|
+
def green(text)
|
19
|
+
colorize(text, 32)
|
20
|
+
end
|
21
|
+
|
22
|
+
def blue(text)
|
23
|
+
colorize(text, 34)
|
24
|
+
end
|
25
|
+
|
26
|
+
def running_state(is_running)
|
27
|
+
is_running ? green("RUNNING") : red("NOT RUNNING")
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
MAX_DEVICES_COUNT = 10
|
32
|
+
|
33
|
+
ARGV.options do |parser|
|
34
|
+
Videoreg.class_eval {
|
35
|
+
parser.banner = "Usage: #{File.basename($0)} [options]"
|
36
|
+
parser.on('-c', '--config CONFIG', 'Use the specified config') { |s| opt.script = s }
|
37
|
+
parser.on('-d', '--device DEVICE', 'Run only the specified device') { |d| opt.device = d }
|
38
|
+
parser.on('-H', '--halt DEVICE', 'Halt (SIGKILL) recording process') { |d| opt.action= :halt; opt.device = d }
|
39
|
+
parser.on('-P', '--pause DEVICE', 'Pause (SIGSTOP) recording process') { |d| opt.action= :pause; opt.device= d }
|
40
|
+
parser.on('-R', '--resume DEVICE', 'Resume (SIGCONT) recording process') { |d| opt.action= :resume; opt.device= d }
|
41
|
+
parser.on('-r', '--recover DEVICE', 'Recover the recording process') { |d| opt.action= :recover; opt.device = d }
|
42
|
+
parser.on('-p', '--pid PID', 'Set the PID file for the capture process') { |pid| opt.pid_path = pid }
|
43
|
+
parser.on('-l', '--log LOGFILE', 'Set the logfile for daemon') { |log| opt.log_path = log }
|
44
|
+
parser.on('-e', '--ensure', 'Check the state of the daemon') { opt.action = :ensure }
|
45
|
+
parser.on('-C', '--clear', 'Clear the state (remove lock-files)') { opt.action = :reset }
|
46
|
+
parser.on('-k', '--kill', 'Kills the capture processes') { opt.action = :kill }
|
47
|
+
parser.on('-v', '--version', 'Show the version') { puts "#{Videoreg.version_info}"; exit }
|
48
|
+
parser.on('-h', '--help', 'Show this help message') { puts parser; exit }
|
49
|
+
parser.on('-U', '--udev', 'Generate udev rules for current config') {
|
50
|
+
opt.action = :info
|
51
|
+
config = Videoreg::Util.udevinfo(MAX_DEVICES_COUNT).each_with_index.map do |info, index|
|
52
|
+
<<-RULE
|
53
|
+
BUS=="usb" ACTION=="add" DEVPATH=="#{info[:prefix]}#{info[:usbhub]}/#{info[:usbport]}/*/video4linux/video*" SYMLINK+="#{Videoreg::DEV_SYMLINK}#{index}" GROUP="video"
|
54
|
+
RULE
|
55
|
+
end.join
|
56
|
+
puts "Writing the rules to #{green(Videoreg::UDEV_RULES_FILE)} file:"
|
57
|
+
puts config
|
58
|
+
begin
|
59
|
+
File.open(Videoreg::UDEV_RULES_FILE, "w+") do |f|
|
60
|
+
f.puts(config)
|
61
|
+
end
|
62
|
+
puts green("File has been written successfully! Now restart udev (/etc/init.d/udev restart) and replug the webcams!")
|
63
|
+
rescue => e
|
64
|
+
puts red("Failed to write file: #{e.message}. Please do this manually!")
|
65
|
+
end
|
66
|
+
}
|
67
|
+
parser.on('-I', '--info', 'Show info about plugged devices') {
|
68
|
+
opt.action = :info
|
69
|
+
Videoreg::Util.udevinfo(MAX_DEVICES_COUNT).each_with_index do |info|
|
70
|
+
puts "#{green(info[:usbhub])}[#{blue(info[:usbport])}] --> #{blue("/dev/#{Videoreg::DEV_SYMLINK}#{info[:devnum]}")}"
|
71
|
+
end
|
72
|
+
}
|
73
|
+
parser.parse!
|
74
|
+
|
75
|
+
case
|
76
|
+
when opt.action == :info
|
77
|
+
# do nothing
|
78
|
+
when opt.script then
|
79
|
+
unless File.exists?(opt.script)
|
80
|
+
puts "File #{opt.script} does not exist!"
|
81
|
+
exit
|
82
|
+
end
|
83
|
+
begin
|
84
|
+
eval(File.open(File.expand_path(opt.script)).read)
|
85
|
+
res = run(opt.device, opt.action)
|
86
|
+
|
87
|
+
case opt.action
|
88
|
+
when :ensure
|
89
|
+
puts "#{blue("DAEMON")}:\t\t [#{running_state(res[0][:daemon_running?])}]"
|
90
|
+
puts "Uptime:\t\t #{Videoreg::Util.humanize(res[0][:uptime])}" if res[0][:daemon_running?]
|
91
|
+
res[1..-1].each do |status|
|
92
|
+
proc_status = if status[:device_exists?] then
|
93
|
+
status[:paused?] ? red("PAUSED") : running_state(status[:process_alive?])
|
94
|
+
else
|
95
|
+
red("NO DEVICE")
|
96
|
+
end
|
97
|
+
puts "#{status[:device]}: \t [#{proc_status}]"
|
98
|
+
end
|
99
|
+
else
|
100
|
+
end
|
101
|
+
rescue => e
|
102
|
+
puts "An error has occured during config processing: #{e.message} \n #{e.backtrace.join("\n")}"
|
103
|
+
end
|
104
|
+
else
|
105
|
+
puts parser
|
106
|
+
end
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
Binary file
|
data/install.sh
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
CURDIR=`pwd`
|
3
|
+
cd /tmp
|
4
|
+
if grep -q "deb http://www.rabbitmq.com/debian/ testing main" /etc/apt/sources.list
|
5
|
+
then
|
6
|
+
echo "It seems you are installing env second time..."
|
7
|
+
else
|
8
|
+
echo "deb http://www.rabbitmq.com/debian/ testing main" >> /etc/apt/sources.list
|
9
|
+
wget http://www.rabbitmq.com/rabbitmq-signing-key-public.asc
|
10
|
+
apt-key add rabbitmq-signing-key-public.asc
|
11
|
+
apt-get update
|
12
|
+
fi
|
13
|
+
apt-get install -y mencoder ffmpeg qc-usb-utils v4l-utils rabbitmq-server ruby1.9.1 rubygems ruby1.9.1-dev
|
14
|
+
ln -sf /usr/bin/ruby1.9.1 /usr/bin/ruby
|
15
|
+
ln -sf /usr/bin/rake1.9.1 /usr/bin/rake
|
16
|
+
ln -sf /usr/bin/gem1.9.1 /usr/bin/gem
|
17
|
+
ln -sf /usr/bin/irb1.9.1 /usr/bin/irb
|
18
|
+
export GEM_BIN=/var/lib/gems/1.9.1/bin
|
19
|
+
export PATH=$PATH:$GEM_BIN
|
20
|
+
cd $CURDIR
|
21
|
+
gem install bundler --no-rdoc --no-ri
|
22
|
+
if [ -f $GEM_BIN/bundle ];
|
23
|
+
then
|
24
|
+
export BUNDLER=$GEM_BIN/bundle
|
25
|
+
else
|
26
|
+
export BUNDLER=/var/lib/gems/1.8/bin/bundle
|
27
|
+
fi
|
28
|
+
|
29
|
+
if [ -f $BUNDLER ];
|
30
|
+
then
|
31
|
+
$BUNDLER install
|
32
|
+
$BUNDLER exec gem install dist/videoreg-0.1.gem
|
33
|
+
|
34
|
+
echo "Information about plugged devices:"
|
35
|
+
videoreg -I
|
36
|
+
videoreg -U
|
37
|
+
else
|
38
|
+
echo "Bundler executable not found ($BUNDLER)! Installation FAILED!"
|
39
|
+
fi
|