screen-recorder 1.5.0 → 1.7.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c04070110a0bb4d14c22683e2e226f68a2245ec8d0ae5ebf098e8a028fc22050
4
- data.tar.gz: eac8f6a6036d62a7634fd61b77a0a864ea589aa3b4d2d5e1693f6a813692d4cd
3
+ metadata.gz: cda2f72664c3d2fa2d47ddb6436b39c934008d48088cf007ccab16c211a6b3f6
4
+ data.tar.gz: 9a919178c367f76f3b808633e9b1e3827f3c4548eb8f7969db3ae44365370d42
5
5
  SHA512:
6
- metadata.gz: 1cd22bbff801124ed2e3c42d94aa50cf8f568b473dcdff045e150bf25e543d0ff81d7d8a99da78ef2e6d8fffb5e57bc8d00a291dec4b72c7abe8f37453bf5e2e
7
- data.tar.gz: ca1af2f484ca9e360dcf94096f7066013e9fe645471c36173d417c589c1cbe12d533bc1269ae44f27fe17a61252a2e1ede833ce9dfc45bcf9daaaeb038866f18
6
+ metadata.gz: 4deb566bbd4b0c70452b6bbd20c68b0e45d27134e79a404cf677dd9bb0d901ccb3e3714970efd0baed0e2c3bb0ce45d09239a28f222ba77c45dbae2fcbd79191
7
+ data.tar.gz: 8f3835f4f6753b14b2b8147d68de68956e3ec6667260d69c20e807dea7a014b7d78f713154731e705619bc07b62b02eb09a8a56e7b9ac578f2e952b033995f24
@@ -3,95 +3,90 @@ name: Tests
3
3
 
4
4
  on: [push, pull_request]
5
5
 
6
+ concurrency:
7
+ group: ${{ github.workflow }}-${{ github.ref }}
8
+ cancel-in-progress: true
9
+
6
10
  jobs:
7
11
  lint:
8
- runs-on: ubuntu-18.04
12
+ runs-on: ubuntu-latest
9
13
  steps:
10
- - name: Cancel any previous run(s) on new commit push
11
- uses: styfle/cancel-workflow-action@0.8.0
12
- with:
13
- access_token: ${{ secrets.GITHUB_TOKEN }}
14
- - uses: actions/checkout@v2
14
+ - uses: actions/checkout@v4
15
15
  - name: Set up Ruby
16
16
  uses: ruby/setup-ruby@v1
17
17
  with:
18
- ruby-version: 2.5
18
+ ruby-version: 3.3
19
19
  bundler-cache: true
20
20
  - name: Run rubocop
21
21
  run: bundle exec rake rubocop
22
22
 
23
23
  test-ubuntu:
24
24
  runs-on: ubuntu-latest
25
+ needs: lint
25
26
  strategy:
26
27
  matrix:
27
- ruby-version: [2.7, jruby]
28
+ ruby-version: [3.0, jruby]
28
29
  env:
29
30
  DISPLAY: ":0"
30
31
  steps:
31
- - name: Cancel any previous run(s) on new commit push
32
- uses: styfle/cancel-workflow-action@0.8.0
33
- with:
34
- access_token: ${{ secrets.GITHUB_TOKEN }}
35
- - uses: actions/checkout@v2
32
+ - uses: actions/checkout@v4
36
33
  - name: Set up ffmpeg
37
- uses: FedericoCarboni/setup-ffmpeg@v1
34
+ uses: FedericoCarboni/setup-ffmpeg@v3
38
35
  with:
39
- token: ${{ secrets.GITHUB_TOKEN }}
36
+ github-token: ${{ secrets.GITHUB_TOKEN }}
40
37
  id: setup-ffmpeg
41
38
  - name: Set up Ruby
42
39
  uses: ruby/setup-ruby@v1
43
40
  with:
44
41
  ruby-version: ${{ matrix.ruby-version }}
45
42
  bundler-cache: true
46
- - name: Start xvfb
47
- run: Xvfb -ac $DISPLAY -screen 0 1024x768x24 > /dev/null 2>&1 &
43
+ - run: bundle list
48
44
  - name: Run tests
49
- run: bundle exec rake spec
45
+ uses: coactions/setup-xvfb@v1
46
+ with:
47
+ run: bundle exec rake spec
48
+ options: :99 -ac -screen 0 640x480x24
50
49
 
51
50
  test-windows:
52
51
  runs-on: windows-latest
52
+ needs: lint
53
53
  strategy:
54
54
  matrix:
55
- ruby-version: [2.5, jruby]
55
+ ruby-version: [3.0]
56
56
  steps:
57
- - name: Cancel any previous run(s) on new commit push
58
- uses: styfle/cancel-workflow-action@0.8.0
59
- with:
60
- access_token: ${{ secrets.GITHUB_TOKEN }}
61
- - uses: actions/checkout@v2
57
+ - uses: actions/checkout@v4
62
58
  - name: Set up ffmpeg
63
- uses: FedericoCarboni/setup-ffmpeg@v1
59
+ uses: FedericoCarboni/setup-ffmpeg@v3
64
60
  with:
65
- token: ${{ secrets.GITHUB_TOKEN }}
61
+ github-token: ${{ secrets.GITHUB_TOKEN }}
66
62
  id: setup-ffmpeg
67
63
  - name: Set up Ruby
68
64
  uses: ruby/setup-ruby@v1
69
65
  with:
70
66
  ruby-version: ${{ matrix.ruby-version }}
71
67
  bundler-cache: true
68
+ - run: bundle list
72
69
  - name: Run tests
73
70
  run: bundle exec rake spec
74
71
 
75
72
  test-macos:
76
- runs-on: macos-latest
73
+ runs-on: macos-13
74
+ needs: lint
77
75
  strategy:
78
76
  matrix:
79
- ruby-version: [2.5, 2.7]
77
+ ruby-version: [3.0]
80
78
  steps:
81
- - name: Cancel any previous run(s) on new commit push
82
- uses: styfle/cancel-workflow-action@0.8.0
83
- with:
84
- access_token: ${{ secrets.GITHUB_TOKEN }}
85
- - uses: actions/checkout@v2
79
+ - uses: actions/checkout@v4
86
80
  - name: Set up ffmpeg
87
- uses: FedericoCarboni/setup-ffmpeg@v1
81
+ uses: FedericoCarboni/setup-ffmpeg@v3
88
82
  with:
89
- token: ${{ secrets.GITHUB_TOKEN }}
83
+ github-token: ${{ secrets.GITHUB_TOKEN }}
90
84
  id: setup-ffmpeg
91
85
  - name: Set up Ruby
92
86
  uses: ruby/setup-ruby@v1
93
87
  with:
94
88
  ruby-version: ${{ matrix.ruby-version }}
95
89
  bundler-cache: true
90
+ - run: bundle list
96
91
  - name: Run tests
97
92
  run: bundle exec rake spec
data/.gitignore CHANGED
@@ -20,6 +20,7 @@ Gemfile.lock # Part of best practice
20
20
  *.mp4
21
21
  *.avi
22
22
  *.gif
23
+ *.png
23
24
 
24
25
  Gemfile.lock
25
26
 
data/.rubocop.yml CHANGED
@@ -1,6 +1,7 @@
1
1
  require:
2
2
  - rubocop-rspec
3
3
  - rubocop-performance
4
+ - rubocop-rake
4
5
 
5
6
  AllCops:
6
7
  DisplayCopNames: true
@@ -84,6 +85,9 @@ RSpec/ExampleLength:
84
85
  RSpec/MultipleExpectations:
85
86
  Enabled: false
86
87
 
88
+ RSpec/SpecFilePathFormat:
89
+ Enabled: False
90
+
87
91
  Style/BlockDelimiters:
88
92
  EnforcedStyle: braces_for_chaining
89
93
 
@@ -0,0 +1,3 @@
1
+ {
2
+ "github-actions.workflows.pinned.workflows": []
3
+ }
data/CHANGELOG.md CHANGED
@@ -2,10 +2,21 @@
2
2
 
3
3
  This project adheres to [Semantic Versioning](https://semver.org/).
4
4
 
5
+ ### 1.7.0 (2024-07-30)
6
+
7
+ * Remove dependency on `childprocess` and `os` gems.
8
+
9
+ ### 1.6.0 (2021-08-22)
10
+
11
+ * Match "childprocess" gem version to `selenium-webdriver`. Closes [#99](https://github.com/kapoorlakshya/screen-recorder/issues/99).
12
+ * Add support for screenshot resolution. Closes [#98](https://github.com/kapoorlakshya/screen-recorder/issues/98).
13
+
5
14
  ### 1.5.0 (2021-03-23)
15
+
6
16
  * Relax "os" gem version to minor level ([#97](https://github.com/kapoorlakshya/screen-recorder/pull/97)). Thanks, [hlascelles](https://github.com/hlascelles)!
7
17
 
8
18
  ### 1.4.0 (2020-01-27)
19
+
9
20
  * Users can now select a ffmpeg [capture device](https://ffmpeg.org/ffmpeg-devices.html) from advanced -> input.
10
21
  * Fix a bug where some advanced parameters were not parsed correctly.
11
22
  * Add support for audio stream capture ([#15](https://github.com/kapoorlakshya/screen-recorder/issues/15))
@@ -14,59 +25,68 @@ This project adheres to [Semantic Versioning](https://semver.org/).
14
25
  * Add support for capturing screenshots in both desktop and window modes ([#44](https://github.com/kapoorlakshya/screen-recorder/issues/44)).
15
26
 
16
27
  ### 1.3.1 (2019-10-20)
28
+
17
29
  * Reattempt `ffprobe` execution up to times if the first try raises `Errno::EAGAIN`.
18
30
  Hopefully fixes [#79](https://github.com/kapoorlakshya/screen-recorder/issues/79).
19
31
 
20
32
  ### 1.3.0 (2019-07-26)
33
+
21
34
  * Support JRuby 9.2+ ([#58](https://github.com/kapoorlakshya/screen-recorder/issues/58))
22
35
  * Add `ScreenRecorder::` as an alias for `ScreenRecorder::Window.fetch_title`.
23
36
  The `Titles` class will be removed in version 2.0.
24
37
 
25
38
  ### 1.2.0 (2019-05-12)
26
- * Separate input/output specific `ffmpeg` arguments through the `advanced`
39
+
40
+ * Separate input/output specific `ffmpeg` arguments through the `advanced`
27
41
  Hash. See example [here](https://github.com/kapoorlakshya/screen-recorder#advanced-options).
28
- * Check for errors after starting the `ffmpeg` process to make sure the
29
- recording does not stop silently because of an error. Prints the error
42
+ * Check for errors after starting the `ffmpeg` process to make sure the
43
+ recording does not stop silently because of an error. Prints the error
30
44
  from the log if the process exists unexpectedly.
31
45
  * Now using [`childprocess`](https://github.com/enkessler/childprocess) gem
32
- to manage the `ffmpeg` process. This requires the `ffi` gem to be
46
+ to manage the `ffmpeg` process. This requires the `ffi` gem to be
33
47
  installed on Windows. See [childprocess#132](https://github.com/enkessler/childprocess/issues/150)
34
48
  for more information.
35
49
 
36
50
  ### 1.1.0 (2019-04-14)
37
- * <b>Add support for macOS</b> ([#55](https://github.com/kapoorlakshya/screen-recorder/issues/55)).
51
+
52
+ * <b>Add support for macOS</b> ([#55](https://github.com/kapoorlakshya/screen-recorder/issues/55)).
38
53
  Thanks to [Denys Bazarnyi](https://github.com/bazarnyi) for testing this and providing feedback.
39
54
  * Force kill `ffmpeg` if it takes more than 10s to quit ([#60](https://github.com/kapoorlakshya/screen-recorder/issues/60)).
40
55
  * Fix a bug where `ScreenRecorder.ffmpeg_binary=()` was not properly defined.
41
- * `ScreenRecorder::Titles#fetch` will now raise `NotImplementedError` when used in a
56
+ * `ScreenRecorder::Titles#fetch` will now raise `NotImplementedError` when used in a
42
57
  Linux or a macOS environment. Only works on Windows.
43
58
  * Default `input` value on Linux is now `:0`.
44
59
 
45
60
  ### 1.0.0 (2019-03-15)
61
+
46
62
  * Released first major version.
47
- * Now uses `ScreenRecorder` as top level module. `FFMPEG` is not directly
63
+ * Now uses `ScreenRecorder` as top level module. `FFMPEG` is not directly
48
64
  exposed anymore.
49
- * The recording modes are now available through `ScreenRecorder::Desktop`
65
+ * The recording modes are now available through `ScreenRecorder::Desktop`
50
66
  and `ScreenRecorder::Window` classes to make the usage (parameters) simpler.
51
67
  * Method parameters are now keywords instead of an `opts` Hash. This means
52
68
  at least Ruby 2.0.0 is required.
53
- * `framerate:` is now to be passed through the `advanced` Hash.
69
+ * `framerate:` is now to be passed through the `advanced` Hash.
54
70
 
55
71
  ### 1.0.0.beta13 (2019-03-15)
56
- * Gem will now be renamed to `screen-recorder`. Please refer to Issue
72
+
73
+ * Gem will now be renamed to `screen-recorder`. Please refer to Issue
57
74
  [#45](https://github.com/kapoorlakshya/screen-recorder/issues/45)
58
75
  for more information.
59
76
 
60
77
  ### 1.0.0.beta12 (2019-03-12)
78
+
61
79
  * Reverted post install message as `screen_recorder` is already taken.
62
80
 
63
81
  ### 1.0.0.beta11 (2019-03-12)
82
+
64
83
  * Recording FPS (`framerate`) is defaulted to 15.0.
65
- * Gem will soon be renamed to `screen_recorder`. Please refer to Issue
84
+ * Gem will soon be renamed to `screen_recorder`. Please refer to Issue
66
85
  [#45](https://github.com/kapoorlakshya/screen-recorder/issues/45)
67
86
  for more information.
68
87
 
69
88
  ### 1.0.0.beta10 (2019-02-05)
89
+
70
90
  * Fixed an edge case in Microsoft Windows specific implementation of
71
91
  `WindowTitles#fetch` where processes with mismatching names and window
72
92
  titles, such as process `"Calculator.exe"` with window title `"CicMarshalWnd"`,
@@ -112,4 +132,4 @@ tests, and fixed rubocop warnings.
112
132
  * Add support for Linux.
113
133
  * Now an exception raised if the gem fails to find `ffmpeg`.
114
134
  * Fix a bug where a file named `nul` was created instead of directing the output to `NUL`.
115
- * Fix a bug where `RecordingRegions#window_titles` was not returning anything because of missing return keyword.
135
+ * Fix a bug where `RecordingRegions#window_titles` was not returning anything because of missing return keyword.
data/Gemfile CHANGED
@@ -1,3 +1,15 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
+ ruby '~> 3.0'
4
+
3
5
  gemspec
6
+
7
+ gem 'pry-byebug', '~> 3.10' unless RUBY_PLATFORM == 'java'
8
+ gem 'rake', '>= 12.0'
9
+ gem 'rspec', '~> 3.0'
10
+ gem 'rubocop', '~> 1.64'
11
+ gem 'rubocop-performance', '~> 1.0'
12
+ gem 'rubocop-rake', '~> 0.6.0'
13
+ gem 'rubocop-rspec', '~> 2.0'
14
+ gem 'simplecov', '~> 0.22'
15
+ gem 'watir', '~> 7.0'
data/README.md CHANGED
@@ -6,10 +6,11 @@
6
6
 
7
7
  A Ruby gem to video record or take screenshots of your computer screen - desktop or specific
8
8
  window - using [FFmpeg](https://www.ffmpeg.org/). Primarily
9
- geared towards recording automated UI (Selenium) test executions for
9
+ geared towards recording automated UI (Selenium) test executions for
10
10
  debugging and documentation.
11
11
 
12
12
  #### Demo
13
+
13
14
  [https://kapoorlakshya.github.io/introducing-screen-recorder-ruby-gem](https://kapoorlakshya.github.io/introducing-screen-recorder-ruby-gem)
14
15
 
15
16
  ## Compatibility
@@ -20,43 +21,25 @@ Works on Windows, Linux, and macOS. Requires Ruby 2.0+ or JRuby 9.2+.
20
21
 
21
22
  ##### 1. Setup FFmpeg
22
23
 
23
- Linux and macOS instructions are [here](https://trac.ffmpeg.org/wiki/CompilationGuide).
24
+ Download from [here](https://ffmpeg.org/download.html) and add to `PATH` or use `brew` / `winget` / `apt` to install.
24
25
 
25
26
  > macOS: Follow [these steps](https://github.com/kapoorlakshya/screen-recorder/issues/88#issuecomment-629139032) to avoid
26
27
  > issues related to Privacy settings.
27
28
 
28
- For Microsoft Windows, download the binary from [here](https://www.videohelp.com/software/ffmpeg). Once downloaded,
29
- add location of the `ffmpeg/bin` folder to the `PATH` environment variable ([instructions](https://windowsloop.com/install-ffmpeg-windows-10/)).
30
-
31
- Alternatively, you can point to the binary file using
32
- `ScreenRecorder.ffmpeg_binary = '/path/to/ffmpeg'` in your project.
29
+ Alternatively, you can point to the binary file using `ScreenRecorder.ffmpeg_binary = '/path/to/ffmpeg'` in your project.
33
30
 
34
31
  ##### 2. Install gem
35
32
 
36
33
  Next, add these lines to your application's Gemfile:
37
34
 
38
35
  ```ruby
39
- gem 'ffi' # Windows only
40
36
  gem 'screen-recorder', '~> 1.0'
41
37
  ```
42
38
 
43
- The [`ffi`](https://github.com/ffi/ffi) gem is used by the
44
- [`childprocess`](https://github.com/enkessler/childprocess) gem on
45
- Windows, but it does not explicitly require it. More information
46
- on this [here](https://github.com/enkessler/childprocess/issues/160).
47
-
48
-
49
39
  And then execute:
50
40
 
51
41
  ```bash
52
- $ bundle
53
- ```
54
-
55
- Or install it yourself as:
56
-
57
- ```bash
58
- $ gem install ffi # Windows only
59
- $ gem install screen-recorder
42
+ bundle install
60
43
  ```
61
44
 
62
45
  ##### 3. Require gem
@@ -95,7 +78,8 @@ browser = Watir::Browser.new :firefox
95
78
  @recorder.stop
96
79
  browser.quit
97
80
  ```
98
- This mode has a few limitations which are listed in the wiki
81
+
82
+ This mode has a few limitations which are listed in the wiki
99
83
  [here](https://github.com/kapoorlakshya/screen-recorder/wiki/Window-Capture-Limitations).
100
84
 
101
85
  ##### Fetch Title
@@ -104,10 +88,10 @@ A helper method is available to fetch the title of the active window
104
88
  for the given process name.
105
89
 
106
90
  ```ruby
107
- ScreenRecorder::('firefox') # Name of exe
91
+ ScreenRecorder::Window.fetch_title('firefox') # Name of exe
108
92
  #=> ["Mozilla Firefox"]
109
93
 
110
- ScreenRecorder::('chrome')
94
+ ScreenRecorder::Window.fetch_title('chrome')
111
95
  #=> ["New Tab - Google Chrome"]
112
96
  ```
113
97
 
@@ -166,6 +150,13 @@ window_title = ScreenRecorder::('chrome').first
166
150
  @recorder.screenshot('after-recording.png')
167
151
  browser.quit
168
152
  ```
153
+
154
+ You can even specify a custom capture resolution:
155
+
156
+ ```rb
157
+ @recorder.screenshot('screenshot.png', '1024x768')
158
+ ```
159
+
169
160
  #### Video Output
170
161
 
171
162
  Once the recorder is stopped, you can view the video metadata or transcode
@@ -191,11 +182,11 @@ See [`streamio-ffmpeg`](https://github.com/streamio/streamio-ffmpeg) gem for mor
191
182
 
192
183
  If your test passes or you do not want the recording for any reason,
193
184
  simply call `@recorder.discard` or `@recorder.delete` to delete
194
- the video file.
185
+ the video file.
195
186
 
196
187
  #### Advanced Options
197
188
 
198
- You can provide additional parameters to FFmpeg using the `advanced`
189
+ You can provide additional parameters to FFmpeg using the `advanced`
199
190
  parameter. You can specify input/output specific parameters using `input: {}`
200
191
  and `output: {}` within the `advanced` Hash.
201
192
 
@@ -234,7 +225,7 @@ Also refer to the `ffmpeg.log` file for details.
234
225
 
235
226
  #### Use with Cucumber
236
227
 
237
- A Cucumber + Watir based example is available
228
+ A Cucumber + Watir based example is available
238
229
  [here](https://github.com/kapoorlakshya/cucumber-watir-test-recorder-example).
239
230
 
240
231
  ## Wiki
@@ -243,15 +234,15 @@ Please see the [wiki](https://github.com/kapoorlakshya/screen-recorder/wiki) for
243
234
 
244
235
  ## Development
245
236
 
246
- After checking out the repo, run `bin/setup` to install dependencies.
247
- Then, run `bundle exec rake` to run the tests and rubocop. You can also run
237
+ After checking out the repo, run `bin/setup` to install dependencies.
238
+ Then, run `bundle exec rake` to run the tests and rubocop. You can also run
248
239
  `bin/console` for an interactive prompt that will allow you to experiment.
249
240
 
250
- To install this gem onto your local machine, run `bundle exec rake install`.
241
+ To install this gem onto your local machine, run `bundle exec rake install`.
251
242
 
252
243
  ### Contributing
253
244
 
254
- Bug reports and pull requests are welcome.
245
+ Bug reports and pull requests are welcome.
255
246
 
256
247
  - Please update the specs for your code changes and run them locally with `bundle exec rake spec`.
257
248
  - Follow the Ruby style guide and format your code - <https://github.com/rubocop-hq/ruby-style-guide>
@@ -262,20 +253,14 @@ The gem is available as open source under the terms of the [MIT License](https:/
262
253
 
263
254
  ## Credits
264
255
 
265
- Thanks to [Denys Bazarnyi](https://github.com/bazarnyi) for testing
256
+ Thanks to [Denys Bazarnyi](https://github.com/bazarnyi) for testing
266
257
  macOS compatibility in v1.1.0.
267
258
  <br />
268
259
  <br />
269
260
 
270
261
  [![Streamio](http://d253c4ja9jigvu.cloudfront.net/assets/small-logo.png)](http://streamio.com)
271
262
 
272
- This gem relies on the [streamio-ffmpeg](https://github.com/streamio/streamio-ffmpeg)
263
+ This gem relies on the [streamio-ffmpeg](https://github.com/streamio/streamio-ffmpeg)
273
264
  gem to extract metadata from the output file.
274
265
  <br />
275
266
  <br />
276
-
277
- ![SauceLabs Logo](https://saucelabs.com/content/images/logo.png)
278
-
279
- Thanks to [SauceLabs](https://saucelabs.com) for providing me with a
280
- free account. If you manage an open source project, you can apply for
281
- a free account [here](https://saucelabs.com/open-source).
data/bin/console CHANGED
File without changes
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ScreenRecorder
4
+ #
5
+ # @api private
6
+ #
7
+ # @since 1.7.0
8
+ #
9
+ # Combined version of:
10
+ # https://github.com/SeleniumHQ/selenium/blob/trunk/rb/lib/selenium/webdriver/common/child_process.rb
11
+ # https://github.com/enkessler/childprocess/blob/master/lib/childprocess/process_spawn_process.rb
12
+ class ChildProcess
13
+ TimeoutError = Class.new(StandardError)
14
+
15
+ SIGINT = 'INT'
16
+ SIGTERM = 'TERM'
17
+ SIGKILL = 'KILL'
18
+
19
+ POLL_INTERVAL = 0.1
20
+
21
+ attr_accessor :detach, :pid
22
+ attr_writer :io
23
+
24
+ def initialize(*command)
25
+ @command = command
26
+ @detach = false
27
+ @pid = nil
28
+ @status = nil
29
+ end
30
+
31
+ def io
32
+ @io ||= ::IO.pipe
33
+ end
34
+
35
+ def start
36
+ options = { :in => io, %i[out err] => io } # to log file
37
+
38
+ if OS.windows?
39
+ options[:new_pgroup] = true
40
+ else
41
+ options[:pgroup] = true
42
+ end
43
+
44
+ @pid = Process.spawn(*@command, options)
45
+ ScreenRecorder.logger.debug(" -> pid: #{@pid}")
46
+
47
+ Process.detach(@pid) if detach
48
+ end
49
+
50
+ def stop(timeout = 3)
51
+ return unless @pid
52
+ return if exited?
53
+
54
+ ScreenRecorder.logger.debug("Sending TERM to process: #{@pid}")
55
+ interrupt
56
+ poll_for_exit(timeout)
57
+
58
+ ScreenRecorder.logger.debug(" -> stopped #{@pid}")
59
+ rescue TimeoutError, Errno::EINVAL
60
+ ScreenRecorder.logger.debug(" -> sending KILL to process: #{@pid}")
61
+ kill
62
+ wait
63
+ ScreenRecorder.logger.debug(" -> killed #{@pid}")
64
+ end
65
+
66
+ def alive?
67
+ @pid && !exited?
68
+ end
69
+
70
+ def exited?
71
+ return true if @exit_code
72
+
73
+ ScreenRecorder.logger.debug("Checking if #{@pid} is exited...")
74
+ pid, @status = ::Process.waitpid2(@pid, ::Process::WNOHANG | ::Process::WUNTRACED)
75
+ return false if @status.nil?
76
+
77
+ pid = nil if pid.zero? # may happen on jruby
78
+ @exit_code = @status.exitstatus || @status.termsig if pid
79
+ ScreenRecorder.logger.debug(" -> exit code is #{@exit_code.inspect}")
80
+
81
+ !!pid
82
+ rescue Errno::ECHILD
83
+ # may be thrown for detached processes
84
+ true
85
+ end
86
+
87
+ def poll_for_exit(timeout)
88
+ ScreenRecorder.logger.debug("Polling #{timeout} seconds for exit of #{@pid}")
89
+
90
+ end_time = Time.now + timeout
91
+ sleep POLL_INTERVAL until exited? || Time.now > end_time
92
+
93
+ raise TimeoutError, " -> #{@pid} still alive after #{timeout} seconds" unless exited?
94
+ end
95
+
96
+ def wait
97
+ return if exited?
98
+
99
+ _, @status = waitpid2(@pid)
100
+ end
101
+
102
+ private
103
+
104
+ def exit_code=(status)
105
+ @exit_code = status.exitstatus || status.termsig
106
+ end
107
+
108
+ def interrupt
109
+ return if exited?
110
+
111
+ send_signal(SIGINT)
112
+ end
113
+
114
+ def terminate
115
+ return if exited?
116
+
117
+ send_signal(SIGTERM)
118
+ end
119
+
120
+ def kill
121
+ return if exited?
122
+
123
+ send_signal(SIGKILL)
124
+ rescue Errno::ECHILD, Errno::ESRCH
125
+ # already dead
126
+ end
127
+
128
+ def send_signal(sig)
129
+ ScreenRecorder.logger.debug("Sending #{sig} to process: #{@pid}")
130
+ if OS.windows?
131
+ Process.kill sig, @pid # process only
132
+ return
133
+ end
134
+
135
+ Process.kill sig, -@pid # negative pid == process group
136
+ end
137
+
138
+ def waitpid2(pid, flags = 0)
139
+ Process.waitpid2(pid, flags)
140
+ rescue Errno::ECHILD
141
+ true # already dead
142
+ end
143
+ end # ChildProcess
144
+ end # Common
@@ -21,8 +21,10 @@ module ScreenRecorder
21
21
  #
22
22
  def start
23
23
  ScreenRecorder.logger.debug 'Starting recorder...'
24
- @video = nil # New file
24
+ @video = nil # New file
25
25
  @process = start_ffmpeg
26
+ raise 'FFmpeg process failed to start.' unless @process.alive?
27
+
26
28
  ScreenRecorder.logger.info 'Recording...'
27
29
  @process
28
30
  end
@@ -32,26 +34,19 @@ module ScreenRecorder
32
34
  #
33
35
  def stop
34
36
  ScreenRecorder.logger.debug 'Stopping ffmpeg...'
35
- exit_code = stop_ffmpeg
36
- return if exit_code == 1 # recording failed
37
37
 
38
- ScreenRecorder.logger.debug 'Stopped ffmpeg.'
39
- ScreenRecorder.logger.info 'Recording complete.'
40
- @video = prepare_video unless exit_code == 1
41
- end
38
+ @process.stop
42
39
 
43
- #
44
- # Takes a screenshot in the current context (input) - desktop or current window
45
- #
46
- def screenshot(filename)
47
- process = execute_command(screenshot_cmd(filename))
48
- exit_code = wait_for_process_exit(process) # 0 (success) or 1 (fail)
49
- if exit_code&.zero?
50
- ScreenRecorder.logger.info "Screenshot: #{filename}"
51
- return filename
40
+ @process.poll_for_exit(PROCESS_TIMEOUT)
41
+ if @process.alive?
42
+ ScreenRecorder.logger.error "Failed to stop ffmpeg (pid: #{@process.pid}). Please kill it manually."
43
+ return
52
44
  end
53
- ScreenRecorder.logger.error 'Failed to take a screenshot.'
54
- nil
45
+
46
+ ScreenRecorder.logger.debug 'Stopped ffmpeg.'
47
+ ScreenRecorder.logger.info 'Preparing video...'
48
+ @video = prepare_video
49
+ ScreenRecorder.logger.info 'Recording ready.'
55
50
  end
56
51
 
57
52
  #
@@ -72,25 +67,17 @@ module ScreenRecorder
72
67
  # the given options.
73
68
  #
74
69
  def start_ffmpeg
75
- process = execute_command(ffmpeg_command, options.log)
70
+ process = execute_command(ffmpeg_command)
76
71
  sleep(1.5) # Takes ~1.5s to initialize ffmpeg
77
72
  # Check if it exited unexpectedly
78
- raise FFMPEG::Error, "Failed to start ffmpeg. Reason: #{lines_from_log(:last, 2)}" if process.exited?
73
+ if process.exited?
74
+ raise FFMPEG::Error,
75
+ "Failed to start command: #{ffmpeg_command}\n\nReason: #{lines_from_log(:last, 10)}"
76
+ end
79
77
 
80
78
  process
81
79
  end
82
80
 
83
- #
84
- # Sends 'q' to the ffmpeg binary to gracefully stop the process.
85
- # Forcefully terminates it if it takes more than 5s.
86
- #
87
- def stop_ffmpeg
88
- @process.io.stdin.puts 'q' # Gracefully exit ffmpeg
89
- @process.io.stdin.close
90
- @log_file.close
91
- wait_for_process_exit(@process)
92
- end
93
-
94
81
  #
95
82
  # Runs ffprobe on the output video file and returns
96
83
  # a FFMPEG::Movie object.
@@ -121,15 +108,11 @@ module ScreenRecorder
121
108
  # options.
122
109
  #
123
110
  def ffmpeg_command
124
- "#{ffmpeg_bin} #{@options.parsed}"
125
- end
111
+ cmd = "#{ffmpeg_bin} #{@options.parsed}"
126
112
 
127
- #
128
- # Parameters to capture a single frame
129
- #
130
- def screenshot_cmd(filename)
131
- # -f overwrites existing file
132
- "#{ffmpeg_bin} -f #{options.capture_device} -i #{options.input} -framerate 1 -frames:v 1 #{filename}"
113
+ return "</dev/null #{cmd}" unless OS.windows?
114
+
115
+ cmd
133
116
  end
134
117
 
135
118
  #
@@ -158,47 +141,28 @@ module ScreenRecorder
158
141
 
159
142
  #
160
143
  # Executes the given command and outputs to the
161
- # optional logfile
162
144
  #
163
- def execute_command(cmd, logfile = nil)
145
+ def execute_command(cmd, log = options.log)
146
+ ScreenRecorder.logger.debug "Log: #{log}"
164
147
  ScreenRecorder.logger.debug "Executing command: #{cmd}"
165
- process = new_process(cmd)
166
- process.duplex = true
167
- if logfile
168
- @log_file = File.new(logfile, 'w+')
169
- process.io.stdout = process.io.stderr = @log_file
170
- @log_file.sync = true
171
- end
148
+ process = new_process(cmd)
149
+ process.detach = true
150
+ FileUtils.touch(log)
151
+ process.io = log
172
152
  process.start
173
153
  process
174
154
  end
175
155
 
176
156
  #
177
- # Calls Childprocess.new with OS specific arguments
157
+ # Calls ChildProcess.new with OS specific arguments
178
158
  # to start the given process.
179
159
  #
180
160
  def new_process(process)
181
- ChildProcess.posix_spawn = true if RUBY_PLATFORM == 'java' # Support JRuby.
182
161
  if OS.windows?
183
- ChildProcess.new('cmd.exe', '/c', process)
162
+ ChildProcess.new('powershell.exe', '/c', process)
184
163
  else
185
- ChildProcess.new('sh', '-c', process)
164
+ ChildProcess.new(process)
186
165
  end
187
166
  end
188
-
189
- #
190
- # Waits for given process to exit.
191
- # Forcefully kills the process if it does not exit within 5 seconds.
192
- # Returns exit code.
193
- #
194
- def wait_for_process_exit(process)
195
- process.poll_for_exit(PROCESS_TIMEOUT)
196
- process.exit_code # 0
197
- rescue ChildProcess::TimeoutError
198
- ScreenRecorder.logger.error 'ffmpeg failed to stop. Force killing it...'
199
- process.stop # Tries increasingly harsher methods to kill the process.
200
- ScreenRecorder.logger.error 'Forcefully killed ffmpeg. Recording failed!'
201
- 1
202
- end
203
167
  end
204
- end
168
+ end
@@ -2,9 +2,11 @@
2
2
  module ScreenRecorder
3
3
  # @since 1.0.0-beta11
4
4
  class Desktop < Common
5
+ include Screenshot
6
+
5
7
  DEFAULT_INPUT_WIN = 'desktop'.freeze
6
- DEFAULT_INPUT_LINUX = ':0'.freeze
7
- DEFAULT_INPUT_MAC = '1'.freeze
8
+ DEFAULT_INPUT_LINUX = ENV.fetch('DISPLAY', ':0').freeze
9
+ DEFAULT_INPUT_MAC = ENV.fetch('DISPLAY', '1').freeze
8
10
 
9
11
  #
10
12
  # Desktop recording mode.
@@ -10,7 +10,6 @@ module ScreenRecorder
10
10
  DEFAULT_FPS = 15.0
11
11
  DEFAULT_MAC_INPUT_PIX_FMT = 'uyvy422'.freeze # For avfoundation
12
12
  DEFAULT_PIX_FMT = 'yuv420p'.freeze
13
- YUV420P_SCALING = '"scale=trunc(iw/2)*2:trunc(ih/2)*2"'.freeze
14
13
 
15
14
  def initialize(options)
16
15
  # @todo Consider using OpenStruct
@@ -18,10 +17,6 @@ module ScreenRecorder
18
17
  advanced[:input] = default_advanced_input.merge(advanced_input)
19
18
  advanced[:output] = default_advanced_output.merge(advanced_output)
20
19
  advanced[:log] ||= DEFAULT_LOG_FILE
21
-
22
- # Fix for using yuv420p pixel format for output
23
- # @see https://www.reck.dk/ffmpeg-libx264-height-not-divisible-by-2/
24
- advanced_output[:vf] = YUV420P_SCALING if advanced_output[:pix_fmt] == 'yuv420p'
25
20
  end
26
21
 
27
22
  #
@@ -0,0 +1,92 @@
1
+ module ScreenRecorder
2
+ # @api private
3
+ module OS
4
+ module_function
5
+
6
+ def home
7
+ @home ||= Dir.home
8
+ end
9
+
10
+ def engine
11
+ @engine ||= RUBY_ENGINE.to_sym
12
+ end
13
+
14
+ def os
15
+ host_os = RbConfig::CONFIG['host_os']
16
+ @os ||= case host_os
17
+ when /mswin|msys|mingw|cygwin|bccwin|wince|emc/
18
+ :windows
19
+ when /darwin|mac os/
20
+ :macosx
21
+ when /linux/
22
+ :linux
23
+ when /solaris|bsd/
24
+ :unix
25
+ else
26
+ raise Error::WebDriverError, "unknown os: #{host_os.inspect}"
27
+ end
28
+ end
29
+
30
+ def jruby?
31
+ engine == :jruby
32
+ end
33
+
34
+ def truffleruby?
35
+ engine == :truffleruby
36
+ end
37
+
38
+ def ruby_version
39
+ RUBY_VERSION
40
+ end
41
+
42
+ def windows?
43
+ os == :windows
44
+ end
45
+
46
+ def mac?
47
+ os == :macosx
48
+ end
49
+
50
+ def linux?
51
+ os == :linux
52
+ end
53
+
54
+ def unix?
55
+ os == :unix
56
+ end
57
+
58
+ def wsl?
59
+ return false unless linux?
60
+
61
+ File.read('/proc/version').downcase.include?('microsoft')
62
+ rescue Errno::EACCES
63
+ # the file cannot be accessed on Linux on DeX
64
+ false
65
+ end
66
+
67
+ def cygwin?
68
+ RUBY_PLATFORM.include?('cygwin')
69
+ end
70
+
71
+ def null_device
72
+ File::NULL
73
+ end
74
+
75
+ def cygwin_path(path, only_cygwin: false, **opts)
76
+ return path if only_cygwin && !cygwin?
77
+
78
+ flags = []
79
+ opts.each { |k, v| flags << "--#{k}" if v }
80
+
81
+ `cygpath #{flags.join ' '} "#{path}"`.strip
82
+ end
83
+
84
+ def unix_path(path)
85
+ path.tr(File::ALT_SEPARATOR, File::SEPARATOR)
86
+ end
87
+
88
+ def windows_path(path)
89
+ path.tr(File::SEPARATOR, File::ALT_SEPARATOR)
90
+ end
91
+ end # OS
92
+ end
@@ -0,0 +1,40 @@
1
+ module ScreenRecorder
2
+ # All screenshot related code
3
+ module Screenshot
4
+ #
5
+ # Takes a screenshot in the current context (input) - desktop or current window
6
+ #
7
+ def screenshot(filename, resolution = nil, log = 'ffmpeg.log')
8
+ ScreenRecorder.logger.debug "Screenshot filename: #{filename}, resolution: #{resolution}"
9
+ cmd = screenshot_cmd(filename: filename, resolution: resolution)
10
+ process = execute_command(cmd, log) # exits when done
11
+ process.poll_for_exit(5)
12
+
13
+ if process.exited?
14
+ ScreenRecorder.logger.info "Screenshot: #{filename}"
15
+ return filename
16
+ end
17
+
18
+ ScreenRecorder.logger.error 'Failed to take a screenshot.'
19
+ nil
20
+ end
21
+
22
+ #
23
+ # Parameters to capture a single frame
24
+ #
25
+ def screenshot_cmd(filename:, resolution: nil)
26
+ resolution = resolution ? resolution_arg(resolution) : nil
27
+ # -f overwrites existing file
28
+ "#{ffmpeg_bin} -f #{options.capture_device} -i #{options.input} -framerate 1 -frames:v 1 #{resolution}#{filename}"
29
+ end
30
+
31
+ private
32
+
33
+ #
34
+ # Returns OS specific video resolution arg for ffmpeg
35
+ #
36
+ def resolution_arg(size)
37
+ "-s #{size} "
38
+ end
39
+ end
40
+ end
@@ -1,3 +1,3 @@
1
1
  module ScreenRecorder
2
- VERSION = '1.5.0'.freeze
3
- end
2
+ VERSION = '1.7.0'.freeze
3
+ end
@@ -2,13 +2,15 @@
2
2
  module ScreenRecorder
3
3
  # @since 1.0.0-beta11
4
4
  class Window < Common
5
+ include Screenshot
6
+
5
7
  #
6
8
  # Window recording mode.
7
9
  #
8
10
  def initialize(title:, output:, advanced: {})
9
11
  raise 'Window recording is only supported on Microsoft Windows.' unless OS.windows?
10
12
 
11
- super(input: %("title=#{title}"), output: output, advanced: advanced)
13
+ super(input: %(title="#{title}"), output: output, advanced: advanced)
12
14
  end
13
15
 
14
16
  class << self
@@ -36,7 +38,9 @@ module ScreenRecorder
36
38
  def window_title_for(process_name)
37
39
  raise NotImplementedError, 'Only Microsoft Windows (gdigrab) supports window capture.' unless OS.windows?
38
40
 
39
- titles = `tasklist /v /fi "imagename eq #{process_name}.exe" /fo list | findstr Window`
41
+ output = `tasklist /v /fi "imagename eq #{process_name}.exe" /fo list | findstr Window`
42
+ # output = output.encode('iso-8859-1').force_encoding('utf-8') unless output.valid_encoding?
43
+ titles = output
40
44
  .split("\n")
41
45
  .map { |i| i.gsub(FILTERED_TITLES, '') }
42
46
  .reject(&:empty?)
@@ -56,4 +60,4 @@ module ScreenRecorder
56
60
  end
57
61
  end
58
62
  end
59
- end
63
+ end
@@ -1,6 +1,4 @@
1
- require 'childprocess'
2
1
  require 'logger'
3
- require 'os'
4
2
  require 'streamio-ffmpeg'
5
3
 
6
4
  # @since 1.0.0.beta11
@@ -78,5 +76,8 @@ require 'screen-recorder/errors'
78
76
  require 'screen-recorder/options'
79
77
  require 'screen-recorder/titles'
80
78
  require 'screen-recorder/common'
79
+ require 'screen-recorder/screenshot'
81
80
  require 'screen-recorder/desktop'
82
- require 'screen-recorder/window'
81
+ require 'screen-recorder/window'
82
+ require 'screen-recorder/childprocess'
83
+ require 'screen-recorder/os'
@@ -10,8 +10,8 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ['kapoorlakshya@gmail.com']
11
11
  spec.homepage = 'http://github.com/kapoorlakshya/screen-recorder'
12
12
  spec.summary = 'Video record and take screenshots your computer screen using FFmpeg.'
13
- spec.description = 'A Ruby gem to video record and take screenshots of your desktop or ' \
14
- ' specific application window. Works on Windows, Linux, and macOS.'
13
+ spec.description = 'A Ruby gem to video record and take screenshots of your desktop or ' \
14
+ 'specific application window. Works on Windows, Linux, and macOS.'
15
15
  spec.license = 'MIT'
16
16
  # noinspection RubyStringKeysInHashInspection
17
17
  spec.metadata = {
@@ -19,7 +19,8 @@ Gem::Specification.new do |spec|
19
19
  'source_code_uri' => "https://github.com/kapoorlakshya/screen-recorder/tree/v#{ScreenRecorder::VERSION}",
20
20
  'documentation_uri' => "https://www.rubydoc.info/gems/screen-recorder/#{ScreenRecorder::VERSION}",
21
21
  'bug_tracker_uri' => 'https://github.com/kapoorlakshya/screen-recorder/issues',
22
- 'wiki_uri' => 'https://github.com/kapoorlakshya/screen-recorder/wiki'
22
+ 'wiki_uri' => 'https://github.com/kapoorlakshya/screen-recorder/wiki',
23
+ 'rubygems_mfa_required' => 'true'
23
24
  }
24
25
 
25
26
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
@@ -28,17 +29,5 @@ Gem::Specification.new do |spec|
28
29
 
29
30
  spec.require_paths = ['lib']
30
31
 
31
- spec.add_development_dependency 'ffi' # For selenium-webdriver on Windows
32
- spec.add_development_dependency 'rake', '>= 12.0'
33
- spec.add_development_dependency 'rspec', '~> 3.0'
34
- spec.add_development_dependency 'rubocop', '~> 0.75'
35
- spec.add_development_dependency 'rubocop-performance', '~> 1.0'
36
- spec.add_development_dependency 'rubocop-rspec', '~> 1.0'
37
- spec.add_development_dependency 'simplecov', '~> 0.16'
38
- spec.add_development_dependency 'watir', '~> 6.0'
39
- spec.add_development_dependency 'webdrivers', '~> 4.0'
40
-
41
- spec.add_runtime_dependency 'childprocess', '>= 1.0', '< 4.0' # Roughly match Selenium
42
- spec.add_runtime_dependency 'os', '~> 1.0'
43
- spec.add_runtime_dependency 'streamio-ffmpeg', '~> 3.0'
32
+ spec.add_dependency 'streamio-ffmpeg', '~> 3.0'
44
33
  end
metadata CHANGED
@@ -1,175 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: screen-recorder
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lakshya Kapoor
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-03-24 00:00:00.000000000 Z
11
+ date: 2024-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: ffi
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - ">="
18
- - !ruby/object:Gem::Version
19
- version: '0'
20
- type: :development
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - ">="
25
- - !ruby/object:Gem::Version
26
- version: '0'
27
- - !ruby/object:Gem::Dependency
28
- name: rake
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: '12.0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '12.0'
41
- - !ruby/object:Gem::Dependency
42
- name: rspec
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - "~>"
46
- - !ruby/object:Gem::Version
47
- version: '3.0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - "~>"
53
- - !ruby/object:Gem::Version
54
- version: '3.0'
55
- - !ruby/object:Gem::Dependency
56
- name: rubocop
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '0.75'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '0.75'
69
- - !ruby/object:Gem::Dependency
70
- name: rubocop-performance
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - "~>"
74
- - !ruby/object:Gem::Version
75
- version: '1.0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - "~>"
81
- - !ruby/object:Gem::Version
82
- version: '1.0'
83
- - !ruby/object:Gem::Dependency
84
- name: rubocop-rspec
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '1.0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '1.0'
97
- - !ruby/object:Gem::Dependency
98
- name: simplecov
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - "~>"
102
- - !ruby/object:Gem::Version
103
- version: '0.16'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: '0.16'
111
- - !ruby/object:Gem::Dependency
112
- name: watir
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - "~>"
116
- - !ruby/object:Gem::Version
117
- version: '6.0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - "~>"
123
- - !ruby/object:Gem::Version
124
- version: '6.0'
125
- - !ruby/object:Gem::Dependency
126
- name: webdrivers
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - "~>"
130
- - !ruby/object:Gem::Version
131
- version: '4.0'
132
- type: :development
133
- prerelease: false
134
- version_requirements: !ruby/object:Gem::Requirement
135
- requirements:
136
- - - "~>"
137
- - !ruby/object:Gem::Version
138
- version: '4.0'
139
- - !ruby/object:Gem::Dependency
140
- name: childprocess
141
- requirement: !ruby/object:Gem::Requirement
142
- requirements:
143
- - - ">="
144
- - !ruby/object:Gem::Version
145
- version: '1.0'
146
- - - "<"
147
- - !ruby/object:Gem::Version
148
- version: '4.0'
149
- type: :runtime
150
- prerelease: false
151
- version_requirements: !ruby/object:Gem::Requirement
152
- requirements:
153
- - - ">="
154
- - !ruby/object:Gem::Version
155
- version: '1.0'
156
- - - "<"
157
- - !ruby/object:Gem::Version
158
- version: '4.0'
159
- - !ruby/object:Gem::Dependency
160
- name: os
161
- requirement: !ruby/object:Gem::Requirement
162
- requirements:
163
- - - "~>"
164
- - !ruby/object:Gem::Version
165
- version: '1.0'
166
- type: :runtime
167
- prerelease: false
168
- version_requirements: !ruby/object:Gem::Requirement
169
- requirements:
170
- - - "~>"
171
- - !ruby/object:Gem::Version
172
- version: '1.0'
173
13
  - !ruby/object:Gem::Dependency
174
14
  name: streamio-ffmpeg
175
15
  requirement: !ruby/object:Gem::Requirement
@@ -197,6 +37,7 @@ files:
197
37
  - ".gitignore"
198
38
  - ".rspec"
199
39
  - ".rubocop.yml"
40
+ - ".vscode/settings.json"
200
41
  - CHANGELOG.md
201
42
  - Gemfile
202
43
  - LICENSE.txt
@@ -205,10 +46,13 @@ files:
205
46
  - bin/console
206
47
  - bin/setup
207
48
  - lib/screen-recorder.rb
49
+ - lib/screen-recorder/childprocess.rb
208
50
  - lib/screen-recorder/common.rb
209
51
  - lib/screen-recorder/desktop.rb
210
52
  - lib/screen-recorder/errors.rb
211
53
  - lib/screen-recorder/options.rb
54
+ - lib/screen-recorder/os.rb
55
+ - lib/screen-recorder/screenshot.rb
212
56
  - lib/screen-recorder/titles.rb
213
57
  - lib/screen-recorder/type_checker.rb
214
58
  - lib/screen-recorder/version.rb
@@ -219,11 +63,12 @@ licenses:
219
63
  - MIT
220
64
  metadata:
221
65
  changelog_uri: https://github.com/kapoorlakshya/screen-recorder/blob/master/CHANGELOG.md
222
- source_code_uri: https://github.com/kapoorlakshya/screen-recorder/tree/v1.5.0
223
- documentation_uri: https://www.rubydoc.info/gems/screen-recorder/1.5.0
66
+ source_code_uri: https://github.com/kapoorlakshya/screen-recorder/tree/v1.7.0
67
+ documentation_uri: https://www.rubydoc.info/gems/screen-recorder/1.7.0
224
68
  bug_tracker_uri: https://github.com/kapoorlakshya/screen-recorder/issues
225
69
  wiki_uri: https://github.com/kapoorlakshya/screen-recorder/wiki
226
- post_install_message:
70
+ rubygems_mfa_required: 'true'
71
+ post_install_message:
227
72
  rdoc_options: []
228
73
  require_paths:
229
74
  - lib
@@ -238,8 +83,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
238
83
  - !ruby/object:Gem::Version
239
84
  version: '0'
240
85
  requirements: []
241
- rubygems_version: 3.1.4
242
- signing_key:
86
+ rubygems_version: 3.5.14
87
+ signing_key:
243
88
  specification_version: 4
244
89
  summary: Video record and take screenshots your computer screen using FFmpeg.
245
90
  test_files: []