vncrec 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44f235ad8e44ea1bab090676b4b011ba3eb53993
4
+ data.tar.gz: 314f906e6b36542cc0c8ed42b61fe14c0de4dc31
5
+ SHA512:
6
+ metadata.gz: bcab87f697e3d8ea4da518a1e2bde030235b83016d1c6c48a327168f365d75f4c962589f037fcc4465b5faa09eb88ae4b77b2470fdfe1185fb35c4677ae529a6
7
+ data.tar.gz: ee53667bcbfc8f44e2e86304cd82932d3f095090dedfeabf59618f42680fb942fac35d69dc3b2c93e3aba33f3e0f8e875a6e318f916ad43b0dfa95a81e9fc30a
data/.gitignore ADDED
@@ -0,0 +1,16 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ *.swp
15
+ mkmf.log
16
+ tags
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --warnings
3
+ --require spec_helper
4
+ -f doc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vncrec.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 slowness pc
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,36 @@
1
+ VNCRec
2
+ ===========
3
+
4
+ VNCRec is a gem that provides you
5
+ tools to record VNC session.
6
+
7
+ ##Usage
8
+ There is a binary called `vncrec`, which is a recorder tool.
9
+
10
+ With no host specified, it will listen on
11
+ given port (5900 by default) for connection
12
+ from VNC server (they refer to that mode as
13
+ _reverse connection_). This is intended to
14
+ be used when you want to record remote
15
+ desktop and you don't know if it's available.
16
+
17
+ Call `vncrec -h` for list of available options.
18
+ To stop recording send `SIGINT` (press ^C).
19
+
20
+ You can also use `VNCRec::Recorder` class in your ruby code.
21
+
22
+ ```ruby
23
+ require 'vncrec'
24
+
25
+ r = VNCRec::Recorder.new(filename: "myvncsession.mp4")
26
+ r.run
27
+ # loop do
28
+ # sleep 100
29
+ # end
30
+ ```
31
+
32
+ If you have FFmpeg installed, file extension is passed just through to it, so
33
+ you can specify encoder you want by passing .mp4 or .flv, etc. If no filename
34
+ specified, `vncrec` assumes raw. There is also a way to
35
+ record raw video by specifying filename with extension .raw. This way FFmpeg is
36
+ not required.
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/extensiontask'
3
+ Rake::ExtensionTask.new('enchex_c')
4
+
5
+ CLEAN.add '*.mp4'
6
+ CLEAN.add '*.raw'
7
+ CLEAN.add '*.jpg'
8
+ CLEAN.add 'somefile'
data/bin/vncrec ADDED
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'optparse'
5
+ require 'vncrec'
6
+
7
+ options = VNCRec::Recorder::DEFAULTS
8
+
9
+ OptionParser.new do |opts|
10
+ opts.on('--pix_fmt F', 'Specify pixel format. List available with --pix_fmts') do |d|
11
+ options[:pix_fmt] = d.dup
12
+ end
13
+ opts.on('--pix_fmts', 'List available pix_fmts') do
14
+ puts 'Available pixel formats:'
15
+ puts "bgr8\t8 bits color palette"
16
+ puts "bgra\t32 bits color palette"
17
+ puts
18
+ exit 0
19
+ end
20
+ opts.on('--debug', 'Enable debugger, gem pry-debugger required') do
21
+ require 'pry-byebug'
22
+ options[:debug] = true
23
+ end
24
+ opts.on('-e ENC', '--encoding', 'Specify encoding') do |e|
25
+ name = "ENC_#{e.upcase}".to_sym
26
+ if VNCRec.constants.index(name)
27
+ options[:encoding] = VNCRec.const_get(name)
28
+ else
29
+ puts 'Unsupported encoding type. Pass option --encodings to see a list of available encodings.'
30
+ exit 1
31
+ end
32
+ end
33
+ opts.on('--encodings', 'Print list of available encodings') do
34
+ puts 'Available encodings are:'
35
+ puts "\traw"
36
+ puts "\thextile"
37
+ puts "\tzrle(not yet supported)"
38
+ puts
39
+ exit
40
+ end
41
+ opts.on('-g GEOM', '--geometry GEOM', 'Screen resolution, <X>x<Y>') do |opt|
42
+ unless opt =~ /\d+x\d+/
43
+ puts 'Unknown screen resolution format, use <x>x<y>'
44
+ exit 1
45
+ end
46
+ options[:geometry] = opt
47
+ end
48
+ opts.on('-h', '--help', 'Display this message') do
49
+ puts opts
50
+ exit
51
+ end
52
+ opts.on('--logging', 'Enable logging to stderr') do
53
+ options[:logging] = true
54
+ end
55
+ opts.on('-o NAME', '--output', 'Specify filename to write to. Special name is "stdout"') do |f|
56
+ options[:filename] = f.to_s
57
+ end
58
+ opts.on('-p PORT', '--port', 'Choose port to listen on') do |p|
59
+ options[:port] = p.to_i
60
+ end
61
+ opts.on('-r RATE', '--framerate <rate>', 'Specify framerate') do |r|
62
+ options[:fps] = r.to_i
63
+ end
64
+ opts.on('-s', '--server SERVER', 'Specify host address') do |s|
65
+ options[:host] = s
66
+ end
67
+ end.parse!
68
+
69
+ v = VNCRec::Recorder.new(options)
70
+ v.on_exit << ->() { exit }
71
+ Signal.trap('INT') { v.running? ? v.stop : exit }
72
+ Signal.trap('USR1') do
73
+ puts v.filesize
74
+ $stdout.flush
75
+ end
76
+
77
+ v.run
78
+ loop do
79
+ sleep 100
80
+ end
data/examples/exit.rb ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'vncrec'
5
+
6
+ r = VNCRec::Recorder.new
7
+ # Append exit to the list of on_exit hooks.
8
+ r.on_exit.push(->() { exit })
data/examples/mp4.rb ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'vncrec'
5
+
6
+ VNCRec::Recorder.new(
7
+ encoding: VNCRec::EncHextile,
8
+ filename: 'file.mp4',
9
+ ffmpeg_out_opts: '-vcodec libx264 -preset ultrafast'
10
+ )
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ require 'vncrec'
5
+
6
+ VNCRec::Recorder.new(
7
+ encoding: VNCRec::EncHextile,
8
+ filename: 'file.mp4',
9
+ ffmpeg_ia_opts: '-i /path/to/audio/file.mp3',
10
+ ffmpeg_out_opts: '-map 0 -vcodec libx264 -preset ultrafast -map 1 -acodec mp3'
11
+ )
@@ -0,0 +1,215 @@
1
+ #include <ruby.h>
2
+ #include <ruby/io.h>
3
+ #include <fcntl.h>
4
+
5
+ #include <math.h>
6
+
7
+ int my_readbyte(VALUE io){
8
+ return NUM2INT( rb_funcall(io, rb_intern("readbyte"),0));
9
+ }
10
+
11
+ char *my_read(VALUE io, long nbytes){
12
+ char * result = (char*)malloc(nbytes+1);
13
+ VALUE nbytes_v = INT2NUM(nbytes);
14
+ VALUE rstr = rb_funcall(io, rb_intern("read"), 1,nbytes_v);
15
+ memcpy(
16
+ result,
17
+ RSTRING_PTR(rstr),
18
+ RSTRING_LEN(rstr)
19
+ );
20
+ return result;
21
+ }
22
+
23
+ VALUE mVNC = Qnil;
24
+ VALUE mEncHextile = Qnil;
25
+ VALUE mRFB = Qnil;
26
+
27
+ void Init_enchex_c();
28
+
29
+ static VALUE read_rect_c(VALUE self,VALUE io, VALUE _x, VALUE _y, VALUE _w, VALUE _h, VALUE bitspp, VALUE fb, VALUE fbw, VALUE fbh);
30
+
31
+ void Init_enchex_c() {
32
+ mVNC = rb_define_module("VNCRec");
33
+ mRFB = rb_define_module_under(mVNC, "RFB");
34
+ mEncHextile = rb_define_module_under(mRFB, "EncHextile");
35
+ rb_define_module_function(mEncHextile, "read_rect", read_rect_c, 9);
36
+ }
37
+
38
+ void _read_subrect_c(int rx, int ry, int rw, int rh, int tx, int ty, char *fg, VALUE io, char* fb, int fbw, int fbh, int bpp){
39
+
40
+ unsigned char xy, wh;
41
+ xy = my_readbyte(io);
42
+ wh = my_readbyte(io);
43
+
44
+ if(!fb)
45
+ return;
46
+
47
+ unsigned char stx = (xy & 0xF0) >> 4;
48
+ unsigned char stw = ((wh & 0xF0) >> 4) + 1;
49
+ unsigned char sty = (xy & 0x0F);
50
+ unsigned char sth = (wh & 0x0F) + 1;
51
+ rw *= bpp;
52
+ rx *= bpp;
53
+ tx *= bpp;
54
+ stx *= bpp;
55
+ stw *= bpp;
56
+ char *fg_row = (char*)malloc(stw);
57
+ int k,l;
58
+ for(k = 0; k < stw; k+=bpp){
59
+ for(l = 0; l < bpp; l++){
60
+ fg_row[k+l] = fg[l];
61
+ }
62
+ }
63
+
64
+ int i;
65
+ for (i = 0; i < sth; i++) {
66
+ register int row_begin = fbw*(ry+ty+sty+i) + rx + tx + stx;
67
+ memcpy(&fb[row_begin], fg_row, stw);
68
+ }
69
+ free(fg_row);
70
+ }
71
+
72
+ void _read_subrect_c_raw(int rx, int ry, int rw, int rh, int tx, int ty, int tw, int th, VALUE io, char* fb, int fbw, int fbh, int bpp){
73
+
74
+ rw *= bpp;
75
+ rx *= bpp;
76
+ tw *= bpp;
77
+ tx *= bpp;
78
+
79
+ int trow;
80
+ char *data = my_read(io, tw*th);
81
+
82
+ if(!fb){
83
+ return;
84
+ }
85
+
86
+ for (trow = 0; trow < th; trow++) {
87
+ register int row_begin = fbw*(ry+ty+trow) + rx + tx;
88
+ memcpy( &fb[row_begin], &data[trow*tw],tw);
89
+ }
90
+ free(data);
91
+ }
92
+
93
+ void _fill_tile_bg(int rx, int ry, int rw, int rh, int tx, int ty, int tw, int th, char*bg, VALUE io, char* fb, int fbw, int fbh, int bpp){
94
+ if(!fb)
95
+ return;
96
+
97
+ rw *= bpp;
98
+ rx *= bpp;
99
+ tw *=bpp;
100
+ tx *= bpp;
101
+ int trow;
102
+ char *bg_row = (char*)malloc(tw);
103
+ int k,l;
104
+ for(k = 0; k < tw; k+=bpp){
105
+ for(l = 0; l < bpp; l++){
106
+ bg_row[k+l] = bg[l];
107
+ }
108
+ }
109
+ register int base_row_begin = fbw*(ry+ty) + rx + tx;
110
+ for (trow = 0; trow < th; trow++) {
111
+ register int row_begin = base_row_begin + fbw*trow;
112
+ memcpy(&fb[row_begin], bg_row, tw);
113
+ }
114
+ free(bg_row);
115
+ }
116
+
117
+ static VALUE read_rect_c(VALUE self,VALUE io, VALUE _x, VALUE _y, VALUE _w, VALUE _h, VALUE bitspp, VALUE _fb, VALUE _fbw, VALUE _fbh){
118
+ int w = NUM2INT(_w);
119
+ int h = NUM2INT(_h);
120
+ int rx = NUM2INT(_x);
121
+ int ry = NUM2INT(_y);
122
+ int fbw = NUM2INT(_fbw);
123
+ int fbh = NUM2INT(_fbh);
124
+ int bpp = (float)NUM2INT(bitspp) / 8.0;
125
+
126
+
127
+ int tiles_row_num = ceil((float)h/16.0);
128
+ int tiles_col_num = ceil((float)w/16.0);
129
+
130
+ char *fb;
131
+ int fbsize = fbw*fbh;
132
+ if(ry > fbh || rx * bpp > fbw)
133
+ fb = NULL; // skip
134
+ else
135
+ fb = (char*)malloc(fbsize);
136
+ if(fb)
137
+ memcpy(fb,RSTRING(_fb)->as.heap.ptr,RSTRING(_fb)->as.heap.len);
138
+
139
+ int last_tile_w = w % 16;
140
+ int last_tile_h = h % 16;
141
+
142
+ char prev_tile_bg[4];
143
+ char prev_tile_fg[4];
144
+
145
+ int i,j;
146
+ int tw, th;
147
+ int ty, tx;
148
+ int ti,tj,tk;
149
+ unsigned char subenc;
150
+ for (i = 0; i < tiles_row_num; i++) {
151
+
152
+ if ((i == tiles_row_num-1) && (last_tile_h > 0))
153
+ th = last_tile_h;
154
+ else
155
+ th = 16;
156
+ ty = 16 * i;
157
+ for (j = 0; j < tiles_col_num; j++) {
158
+
159
+ if ((j == tiles_col_num-1) && (last_tile_w > 0))
160
+ tw = last_tile_w;
161
+ else
162
+ tw = 16;
163
+ tx = 16 * j;
164
+
165
+ subenc = my_readbyte(io);
166
+
167
+ if(subenc & 1){ //raw
168
+ _read_subrect_c_raw(rx,ry,w,h,tx,ty,tw,th,io,fb,fbw,fbh,bpp);
169
+ }
170
+ if(subenc & 2){//background specified
171
+ for (tk = 0; tk < bpp; tk++) {
172
+ prev_tile_bg[tk] = my_readbyte(io);
173
+ }
174
+ }
175
+ if(!(subenc & 1)){//should not refill raw
176
+ for (ti = 0; ti < th; ti++) {
177
+ for(tj = 0; tj < tw; tj++){
178
+ _fill_tile_bg(rx,ry,w,h,tx,ty,tw,th,prev_tile_bg,io,fb,fbw,fbh,bpp);
179
+ }
180
+ }
181
+ }
182
+ if(subenc & 4){//foreground specified
183
+ for (tk = 0; tk < bpp; tk++) {
184
+ prev_tile_fg[tk] = my_readbyte(io);
185
+ }
186
+ }
187
+ if(subenc & 8){//any subrect
188
+ size_t subrects_number = my_readbyte(io);
189
+ size_t subrect;
190
+ char fg[4];
191
+ for (subrect = 0; subrect < subrects_number; subrect++) {
192
+ if(subenc & 16){//subrect colored
193
+ for (tk = 0; tk < bpp; tk++) {
194
+ fg[tk] = my_readbyte(io);
195
+ }
196
+ _read_subrect_c(rx,ry,w,h,tx,ty, fg, io, fb, fbw, fbh, bpp);
197
+ }else{
198
+ _read_subrect_c(rx,ry,w,h,tx,ty, prev_tile_fg, io, fb, fbw, fbh, bpp);
199
+ }
200
+ }
201
+ }
202
+
203
+ } //for j
204
+ }//for i
205
+
206
+ if(fb) {
207
+ for (i = 0; i < fbh; i++) {
208
+ rb_str_update(_fb, i*fbw, fbw,
209
+ rb_str_new(&fb[i * fbw], fbw));
210
+ }
211
+ free(fb);
212
+ }
213
+
214
+ return Qtrue;
215
+ }
@@ -0,0 +1,5 @@
1
+ require "mkmf"
2
+
3
+ extension_name = 'enchex_c'
4
+ dir_config(extension_name)
5
+ create_makefile("vncrec/rfb/#{extension_name}")