screencaster-gtk 0.0.3.alpha1 → 0.0.4.alpha1
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/lib/screencaster-gtk.rb
CHANGED
@@ -22,13 +22,19 @@ class ScreencasterGtk
|
|
22
22
|
PIDFILE = File.join(SCREENCASTER_DIR, "run", "screencaster.pid")
|
23
23
|
|
24
24
|
DEFAULT_SPACE = 10
|
25
|
+
RECORD_IMAGE = Gtk::Image.new(Gtk::Stock::MEDIA_RECORD, Gtk::IconSize::SMALL_TOOLBAR)
|
26
|
+
PAUSE_IMAGE = Gtk::Image.new(Gtk::Stock::MEDIA_PAUSE, Gtk::IconSize::SMALL_TOOLBAR)
|
27
|
+
STOP_IMAGE = Gtk::Image.new(Gtk::Stock::MEDIA_STOP, Gtk::IconSize::SMALL_TOOLBAR)
|
28
|
+
CANCEL_IMAGE = Gtk::Image.new(Gtk::Stock::CANCEL, Gtk::IconSize::SMALL_TOOLBAR)
|
29
|
+
QUIT_IMAGE = Gtk::Image.new(Gtk::Stock::QUIT, Gtk::IconSize::SMALL_TOOLBAR)
|
30
|
+
|
25
31
|
|
26
32
|
def initialize
|
27
33
|
#### Create Main Window
|
28
34
|
|
29
35
|
LOGGER.info "Started"
|
30
|
-
|
31
|
-
@window = Gtk::Window.new
|
36
|
+
|
37
|
+
@window = Gtk::Window.new("Screencaster")
|
32
38
|
@window.signal_connect("delete_event") {
|
33
39
|
LOGGER.debug "delete event occurred"
|
34
40
|
#true
|
@@ -42,70 +48,71 @@ class ScreencasterGtk
|
|
42
48
|
|
43
49
|
# The following gets minimize and restore events, but not iconify and de-iconify
|
44
50
|
@window.signal_connect("window_state_event") { |w, e|
|
45
|
-
|
51
|
+
LOGGER.debug "window_state_event #{e.to_s}"
|
46
52
|
}
|
47
53
|
|
48
54
|
@window.border_width = DEFAULT_SPACE
|
55
|
+
|
56
|
+
control_bar = Gtk::HBox.new(false, ScreencasterGtk::DEFAULT_SPACE)
|
49
57
|
|
50
|
-
|
51
|
-
|
52
|
-
@select_button = Gtk::Button.new("Select Window to Record")
|
58
|
+
@select_button = Gtk::Button.new("Select Window")
|
53
59
|
@select_button.signal_connect("clicked") {
|
54
60
|
self.select
|
55
61
|
}
|
56
|
-
|
62
|
+
control_bar.pack_start(@select_button, true, false)
|
57
63
|
|
58
|
-
button = Gtk::Button.new
|
64
|
+
button = Gtk::Button.new
|
65
|
+
button.image = QUIT_IMAGE
|
59
66
|
button.signal_connect("clicked") {
|
60
67
|
self.quit
|
61
68
|
}
|
62
|
-
|
63
|
-
|
64
|
-
bottom_row = Gtk::VBox.new(false, ScreencasterGtk::DEFAULT_SPACE) # children have different sizes, spaced by DEFAULT_SPACE
|
65
|
-
bottom_row.pack_end(bottom_columns, false)
|
69
|
+
control_bar.pack_end(button, true, false)
|
66
70
|
|
67
71
|
control_columns = Gtk::HBox.new(false, ScreencasterGtk::DEFAULT_SPACE) # children have different sizes, spaced by DEFAULT_SPACE
|
68
72
|
|
69
|
-
@
|
70
|
-
@
|
71
|
-
@
|
72
|
-
|
73
|
-
|
74
|
-
control_columns.pack_start(@record_button, true, false)
|
75
|
-
|
76
|
-
@pause_button = Gtk::Button.new("Pause")
|
77
|
-
@pause_button.sensitive = false
|
78
|
-
@pause_button.signal_connect("clicked") {
|
79
|
-
self.pause
|
73
|
+
@record_pause_button = Gtk::Button.new
|
74
|
+
@record_pause_button.image = RECORD_IMAGE
|
75
|
+
@record_pause_button.sensitive = false
|
76
|
+
@record_pause_button.signal_connect("clicked") {
|
77
|
+
self.record_pause
|
80
78
|
}
|
81
|
-
|
82
|
-
|
83
|
-
@
|
79
|
+
control_bar.pack_start(@record_pause_button, true, false)
|
80
|
+
|
81
|
+
# @pause_button = Gtk::Button.new(Gtk::Stock::MEDIA_PAUSE)
|
82
|
+
# @pause_button.sensitive = false
|
83
|
+
# @pause_button.signal_connect("clicked") {
|
84
|
+
# self.pause
|
85
|
+
# }
|
86
|
+
# control_columns.pack_start(@pause_button, true, false)
|
87
|
+
#
|
88
|
+
@stop_button = Gtk::Button.new
|
89
|
+
@stop_button.image = STOP_IMAGE
|
84
90
|
@stop_button.sensitive = false
|
85
91
|
@stop_button.signal_connect("clicked") {
|
86
92
|
self.stop_recording
|
87
93
|
}
|
88
|
-
|
89
|
-
|
90
|
-
control_row = Gtk::VBox.new(false, ScreencasterGtk::DEFAULT_SPACE) # children have different sizes, spaced by DEFAULT_SPACE
|
91
|
-
control_row.pack_start(control_columns, true, false)
|
94
|
+
control_bar.pack_start(@stop_button, true, false)
|
92
95
|
|
93
|
-
|
94
|
-
@
|
95
|
-
columns.pack_start(@progress_bar, true, false)
|
96
|
-
|
97
|
-
@cancel_button = Gtk::Button.new("Cancel")
|
96
|
+
@cancel_button = Gtk::Button.new
|
97
|
+
@cancel_button.image = CANCEL_IMAGE
|
98
98
|
@cancel_button.sensitive = false
|
99
99
|
@cancel_button.signal_connect("clicked") {
|
100
100
|
self.stop_encoding
|
101
101
|
}
|
102
|
-
|
102
|
+
control_bar.pack_start(@cancel_button, true, false)
|
103
|
+
|
104
|
+
control_row = Gtk::VBox.new(false, ScreencasterGtk::DEFAULT_SPACE) # children have different sizes, spaced by DEFAULT_SPACE
|
105
|
+
control_row.pack_start(control_bar, true, false)
|
106
|
+
|
107
|
+
columns = Gtk::HBox.new(false, ScreencasterGtk::DEFAULT_SPACE)
|
108
|
+
@progress_bar = Gtk::ProgressBar.new
|
109
|
+
@progress_bar.text = "Select Window to Record"
|
110
|
+
columns.pack_start(@progress_bar, true, true)
|
103
111
|
|
104
112
|
progress_row = Gtk::VBox.new(false, ScreencasterGtk::DEFAULT_SPACE) # children have different sizes, spaced by DEFAULT_SPACE
|
105
113
|
progress_row.pack_start(columns, true, false)
|
106
114
|
|
107
115
|
the_box = Gtk::VBox.new(false, ScreencasterGtk::DEFAULT_SPACE)
|
108
|
-
the_box.pack_end(bottom_row, false, false)
|
109
116
|
the_box.pack_end(progress_row, false, false)
|
110
117
|
the_box.pack_end(control_row, false, false)
|
111
118
|
|
@@ -208,13 +215,30 @@ class ScreencasterGtk
|
|
208
215
|
LOGGER.debug "Selecting Window"
|
209
216
|
@capture_window = Capture.new
|
210
217
|
@capture_window.get_window_to_capture
|
211
|
-
@
|
218
|
+
@record_pause_button.sensitive = true
|
219
|
+
end
|
220
|
+
|
221
|
+
def record_pause
|
222
|
+
LOGGER.debug "Record/Pause state: #{@capture_window.state}"
|
223
|
+
case @capture_window.state
|
224
|
+
when :recording
|
225
|
+
LOGGER.debug "Record/Pause -- pause"
|
226
|
+
pause
|
227
|
+
when :paused, :stopped
|
228
|
+
LOGGER.debug "Record/Pause -- record"
|
229
|
+
record
|
230
|
+
else
|
231
|
+
LOGGER.error "#{__FILE__} #{__LINE__}: Can't happen (state #{@capture_window.state})."
|
232
|
+
end
|
212
233
|
end
|
213
234
|
|
214
235
|
def record
|
215
236
|
LOGGER.debug "Recording"
|
216
237
|
recording
|
217
|
-
@capture_window.record
|
238
|
+
@capture_window.record { |percent, time_elapsed|
|
239
|
+
@progress_bar.text = time_elapsed
|
240
|
+
LOGGER.debug "Did elapsed time: #{time_elapsed}"
|
241
|
+
}
|
218
242
|
end
|
219
243
|
|
220
244
|
def pause
|
@@ -248,14 +272,14 @@ class ScreencasterGtk
|
|
248
272
|
|
249
273
|
def stop
|
250
274
|
case @capture_window.state
|
251
|
-
when :recording
|
275
|
+
when :recording, :paused
|
252
276
|
stop_recording
|
253
277
|
when :encoding
|
254
278
|
stop_encoding
|
255
279
|
when :stopped
|
256
280
|
# Do nothing
|
257
281
|
else
|
258
|
-
LOGGER.error "#{__FILE__} #{__LINE__}: Can't happen."
|
282
|
+
LOGGER.error "#{__FILE__} #{__LINE__}: Can't happen (state #{@capture_window.state})."
|
259
283
|
end
|
260
284
|
end
|
261
285
|
|
@@ -272,42 +296,48 @@ class ScreencasterGtk
|
|
272
296
|
when :stopped
|
273
297
|
# Do nothing
|
274
298
|
else
|
275
|
-
LOGGER.error "#{__FILE__} #{__LINE__}: Can't happen."
|
299
|
+
LOGGER.error "#{__FILE__} #{__LINE__}: Can't happen (state #{@capture_window.state})."
|
276
300
|
end
|
277
301
|
end
|
278
302
|
|
279
303
|
def recording
|
280
|
-
self.status_icon.stock = Gtk::Stock::
|
304
|
+
self.status_icon.stock = Gtk::Stock::MEDIA_PAUSE
|
305
|
+
@record_pause_button.image = PAUSE_IMAGE
|
281
306
|
@select.sensitive = @select_button.sensitive = false
|
282
|
-
@
|
307
|
+
@record_pause_button.sensitive = true
|
308
|
+
# @pause.sensitive = @pause_button.sensitive = true
|
283
309
|
@stop.sensitive = @stop_button.sensitive = true
|
284
|
-
@record.sensitive =
|
310
|
+
@record.sensitive = false
|
285
311
|
@cancel_button.sensitive = false
|
286
312
|
end
|
287
313
|
|
288
314
|
def not_recording
|
289
315
|
self.status_icon.stock = Gtk::Stock::MEDIA_RECORD
|
316
|
+
@record_pause_button.image = RECORD_IMAGE
|
290
317
|
@select.sensitive = @select_button.sensitive = true
|
291
|
-
@pause.sensitive = @pause_button.sensitive = false
|
318
|
+
# @pause.sensitive = @pause_button.sensitive = false
|
292
319
|
@stop.sensitive = @stop_button.sensitive = false
|
293
|
-
@record.sensitive = @
|
320
|
+
@record.sensitive = @record_pause_button.sensitive = ! @capture_window.nil?
|
294
321
|
@cancel_button.sensitive = false
|
295
322
|
end
|
296
323
|
|
297
324
|
def paused
|
298
325
|
self.status_icon.stock = Gtk::Stock::MEDIA_RECORD
|
326
|
+
@record_pause_button.image = RECORD_IMAGE
|
327
|
+
@record_pause_button.sensitive = true
|
299
328
|
@select.sensitive = @select_button.sensitive = false
|
300
|
-
@pause.sensitive = @pause_button.sensitive = false
|
329
|
+
# @pause.sensitive = @pause_button.sensitive = false
|
301
330
|
@stop.sensitive = @stop_button.sensitive = true
|
302
|
-
@record.sensitive =
|
331
|
+
@record.sensitive = ! @capture_window.nil?
|
303
332
|
@cancel_button.sensitive = true
|
304
333
|
end
|
305
334
|
|
306
335
|
def encoding
|
307
336
|
self.status_icon.stock = Gtk::Stock::MEDIA_STOP
|
308
|
-
@
|
337
|
+
@record_pause_button.image = RECORD_IMAGE
|
338
|
+
# @pause.sensitive = @pause_button.sensitive = false
|
309
339
|
@stop.sensitive = @stop_button.sensitive = false
|
310
|
-
@record.sensitive = @
|
340
|
+
@record.sensitive = @record_pause_button.sensitive = false
|
311
341
|
@cancel_button.sensitive = true
|
312
342
|
end
|
313
343
|
|
@@ -403,7 +433,7 @@ class ScreencasterGtk
|
|
403
433
|
Pause a running capture, or restart a paused capture
|
404
434
|
EOF
|
405
435
|
exit 0
|
406
|
-
when '--pause'
|
436
|
+
when '--pause', '--start'
|
407
437
|
if existing_pid then
|
408
438
|
ScreencasterGtk::LOGGER.debug("Got a pause for PID #{existing_pid}")
|
409
439
|
begin
|
@@ -108,10 +108,9 @@ class Capture
|
|
108
108
|
@tmp_files = []
|
109
109
|
self.total_amount = 0.0
|
110
110
|
end
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
def record_one_file(output_file)
|
111
|
+
|
112
|
+
output_file = self.new_tmp_file
|
113
|
+
|
115
114
|
@state = :recording
|
116
115
|
capture_fps=24
|
117
116
|
audio_options="-f alsa -ac 1 -ab 192k -i pulse -acodec pcm_s16le"
|
@@ -160,9 +159,12 @@ class Capture
|
|
160
159
|
$logger.debug "****" + line
|
161
160
|
if (line =~ /time=([0-9]*\.[0-9]*)/)
|
162
161
|
duration = $1.to_f
|
162
|
+
$logger.debug "Recording about to yield #{self.total_amount + duration}"
|
163
|
+
yield 0.0, ProgressTracker::format_seconds(self.total_amount + duration)
|
163
164
|
end
|
164
165
|
end
|
165
166
|
self.total_amount += duration
|
167
|
+
yield 0.0, ProgressTracker::format_seconds(self.total_amount)
|
166
168
|
end
|
167
169
|
end
|
168
170
|
|
@@ -211,27 +213,40 @@ class Capture
|
|
211
213
|
|
212
214
|
def merge(output_file, input_files, feedback = proc {} )
|
213
215
|
$logger.debug("Merging #{input_files.size.to_s} files: #{Capture.format_input_files_for_mkvmerge(input_files)}")
|
216
|
+
$logger.debug("Feedback #{feedback}")
|
214
217
|
|
218
|
+
# TODO: cp doesn't give feedback like mkvmerge does...
|
215
219
|
if input_files.size == 1
|
216
|
-
cmd_line = "cp #{input_files[0]} #{output_file}"
|
220
|
+
cmd_line = "cp -v #{input_files[0]} #{output_file}"
|
217
221
|
#cmd_line = "sleep 5"
|
218
222
|
else
|
219
223
|
cmd_line = "mkvmerge -v -o #{output_file} #{Capture.format_input_files_for_mkvmerge(input_files)}"
|
220
224
|
end
|
221
225
|
$logger.debug "Merge command line: #{cmd_line}"
|
222
226
|
i, oe, t = Open3.popen2e(cmd_line)
|
227
|
+
$logger.debug "Thread from popen2e: #{t}"
|
223
228
|
@pid = t.pid
|
224
229
|
Process.detach(@pid)
|
225
230
|
$logger.debug "@pid: #{@pid.to_s}"
|
226
231
|
|
227
232
|
t = Thread.new do
|
233
|
+
$logger.debug "Thread from Thread.new: #{t}"
|
228
234
|
# $logger.debug "Sleeping..."
|
229
235
|
# sleep 2
|
230
236
|
# $logger.debug "Awake!"
|
231
|
-
while oe.gets do
|
232
|
-
#
|
237
|
+
while l = oe.gets do
|
238
|
+
# TODO: Lots for duplicate code in this line to clean up.
|
239
|
+
if block_given?
|
240
|
+
yield 0.5, ""
|
241
|
+
else
|
242
|
+
feedback.call 0.5, ""
|
243
|
+
end
|
244
|
+
end
|
245
|
+
if block_given?
|
246
|
+
yield 1.0, "Done"
|
247
|
+
else
|
248
|
+
feedback.call 1.0, "Done"
|
233
249
|
end
|
234
|
-
feedback.call 1.0, "Done"
|
235
250
|
end
|
236
251
|
return t
|
237
252
|
end
|
@@ -34,12 +34,14 @@ module ProgressTracker
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def time_remaining_s(format = "%dh %02dm %02ds remaining")
|
37
|
-
|
37
|
+
ProgressTracker.format_seconds(self.time_remaining, format)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.format_seconds(t, format = "%dh %02dm %02ds")
|
38
41
|
h = (t / 3600).to_i
|
39
42
|
m = ((t - h * 3600) / 60).to_i
|
40
43
|
s = (t % 60).to_i
|
41
44
|
sprintf(format, h, m, s)
|
42
45
|
end
|
43
|
-
|
44
46
|
end
|
45
47
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: screencaster-gtk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4.alpha1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: gdk_pixbuf2
|