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 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