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.
@@ -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
- puts ("window_state_event #{e.to_s}")
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
- bottom_columns = Gtk::HBox.new(false, ScreencasterGtk::DEFAULT_SPACE) # children have different sizes, spaced by DEFAULT_SPACE
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
- bottom_columns.pack_start(@select_button, true, false)
62
+ control_bar.pack_start(@select_button, true, false)
57
63
 
58
- button = Gtk::Button.new("Quit")
64
+ button = Gtk::Button.new
65
+ button.image = QUIT_IMAGE
59
66
  button.signal_connect("clicked") {
60
67
  self.quit
61
68
  }
62
- bottom_columns.pack_end(button, true, false)
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
- @record_button = Gtk::Button.new("Record")
70
- @record_button.sensitive = false
71
- @record_button.signal_connect("clicked") {
72
- self.record
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
- control_columns.pack_start(@pause_button, true, false)
82
-
83
- @stop_button = Gtk::Button.new("Stop")
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
- control_columns.pack_start(@stop_button, true, false)
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
- columns = Gtk::HBox.new(false, ScreencasterGtk::DEFAULT_SPACE)
94
- @progress_bar = Gtk::ProgressBar.new
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
- columns.pack_start(@cancel_button, true, false)
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
- @record_button.sensitive = true
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 || :paused
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::MEDIA_STOP
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
- @pause.sensitive = @pause_button.sensitive = true
307
+ @record_pause_button.sensitive = true
308
+ # @pause.sensitive = @pause_button.sensitive = true
283
309
  @stop.sensitive = @stop_button.sensitive = true
284
- @record.sensitive = @record_button.sensitive = false
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 = @record_button.sensitive = ! @capture_window.nil?
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 = @record_button.sensitive = ! @capture_window.nil?
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
- @pause.sensitive = @pause_button.sensitive = false
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 = @record_button.sensitive = false
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' || '--start'
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
- record_one_file(self.new_tmp_file)
112
- end
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
- # $logger.debug "Line"
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
- t = self.time_remaining
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
 
@@ -4,7 +4,7 @@ class SaveFile
4
4
  def self.set_up_dialog(file_name = "output.mp4")
5
5
  @dialog = Gtk::FileChooserDialog.new(
6
6
  "Save File As ...",
7
- $window,
7
+ nil,
8
8
  Gtk::FileChooser::ACTION_SAVE,
9
9
  nil,
10
10
  [ Gtk::Stock::CANCEL, Gtk::Dialog::RESPONSE_CANCEL ],
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.3.alpha1
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-19 00:00:00.000000000 Z
12
+ date: 2013-11-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gdk_pixbuf2