videoreg 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ .idea
2
+ *.iml
3
+ coverage
4
+ .bundle
5
+ tmp
6
+ old
7
+ chromedriver.log
8
+ atlassian-ide-plugin.xml
9
+ //*.gem
10
+ *.log
data/Gemfile ADDED
@@ -0,0 +1,12 @@
1
+ source :rubygems
2
+
3
+ gem 'dante'
4
+ gem 'open4'
5
+ gem 'god'
6
+ gem 'amqp'
7
+ gem 'json'
8
+
9
+ group :test do
10
+ gem 'rspec'
11
+ gem 'simplecov', :require => false
12
+ end
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