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 +4 -4
- data/.github/workflows/tests.yml +30 -35
- data/.gitignore +1 -0
- data/.rubocop.yml +4 -0
- data/.vscode/settings.json +3 -0
- data/CHANGELOG.md +32 -12
- data/Gemfile +12 -0
- data/README.md +25 -40
- data/bin/console +0 -0
- data/lib/screen-recorder/childprocess.rb +144 -0
- data/lib/screen-recorder/common.rb +32 -68
- data/lib/screen-recorder/desktop.rb +4 -2
- data/lib/screen-recorder/options.rb +0 -5
- data/lib/screen-recorder/os.rb +92 -0
- data/lib/screen-recorder/screenshot.rb +40 -0
- data/lib/screen-recorder/version.rb +2 -2
- data/lib/screen-recorder/window.rb +7 -3
- data/lib/screen-recorder.rb +4 -3
- data/screen-recorder.gemspec +5 -16
- metadata +13 -168
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cda2f72664c3d2fa2d47ddb6436b39c934008d48088cf007ccab16c211a6b3f6
|
4
|
+
data.tar.gz: 9a919178c367f76f3b808633e9b1e3827f3c4548eb8f7969db3ae44365370d42
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4deb566bbd4b0c70452b6bbd20c68b0e45d27134e79a404cf677dd9bb0d901ccb3e3714970efd0baed0e2c3bb0ce45d09239a28f222ba77c45dbae2fcbd79191
|
7
|
+
data.tar.gz: 8f3835f4f6753b14b2b8147d68de68956e3ec6667260d69c20e807dea7a014b7d78f713154731e705619bc07b62b02eb09a8a56e7b9ac578f2e952b033995f24
|
data/.github/workflows/tests.yml
CHANGED
@@ -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-
|
12
|
+
runs-on: ubuntu-latest
|
9
13
|
steps:
|
10
|
-
-
|
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:
|
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: [
|
28
|
+
ruby-version: [3.0, jruby]
|
28
29
|
env:
|
29
30
|
DISPLAY: ":0"
|
30
31
|
steps:
|
31
|
-
-
|
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@
|
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
|
-
-
|
47
|
-
run: Xvfb -ac $DISPLAY -screen 0 1024x768x24 > /dev/null 2>&1 &
|
43
|
+
- run: bundle list
|
48
44
|
- name: Run tests
|
49
|
-
|
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: [
|
55
|
+
ruby-version: [3.0]
|
56
56
|
steps:
|
57
|
-
-
|
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@
|
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-
|
73
|
+
runs-on: macos-13
|
74
|
+
needs: lint
|
77
75
|
strategy:
|
78
76
|
matrix:
|
79
|
-
ruby-version: [
|
77
|
+
ruby-version: [3.0]
|
80
78
|
steps:
|
81
|
-
-
|
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@
|
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
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
|
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
[](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
|
-

|
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
|
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
|
-
|
39
|
-
ScreenRecorder.logger.info 'Recording complete.'
|
40
|
-
@video = prepare_video unless exit_code == 1
|
41
|
-
end
|
38
|
+
@process.stop
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
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
|
-
|
54
|
-
|
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
|
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
|
-
|
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
|
-
|
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,
|
145
|
+
def execute_command(cmd, log = options.log)
|
146
|
+
ScreenRecorder.logger.debug "Log: #{log}"
|
164
147
|
ScreenRecorder.logger.debug "Executing command: #{cmd}"
|
165
|
-
process
|
166
|
-
process.
|
167
|
-
|
168
|
-
|
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
|
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('
|
162
|
+
ChildProcess.new('powershell.exe', '/c', process)
|
184
163
|
else
|
185
|
-
ChildProcess.new(
|
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.
|
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: %("
|
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
|
-
|
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
|
data/lib/screen-recorder.rb
CHANGED
@@ -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'
|
data/screen-recorder.gemspec
CHANGED
@@ -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
|
-
|
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.
|
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.
|
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:
|
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.
|
223
|
-
documentation_uri: https://www.rubydoc.info/gems/screen-recorder/1.
|
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
|
-
|
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.
|
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: []
|