ffmpeg-screenrecorder 1.0.0.beta9 → 1.0.0.beta10
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/.rubocop.yml +3 -0
- data/CHANGES.md +21 -0
- data/README.md +95 -82
- data/lib/ffmpeg/recorder_options.rb +10 -14
- data/lib/ffmpeg/screenrecorder.rb +1 -0
- data/lib/ffmpeg/type_checker.rb +12 -0
- data/lib/ffmpeg/version.rb +1 -1
- data/lib/ffmpeg/window_titles.rb +31 -17
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 362b8478473163a4c1b072b4bd556560dbad3fd6f50f258e6f6fbebdfb01955c
|
4
|
+
data.tar.gz: c9f64e399242f570bf87e0dd1483b92e2bd63c17e8ec97aebe2686067f446f8c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44287d64e556d2ae9ae720c55d9fddeb19acb9085943b083bc88c8eac6c15cebd97ef40f085d01d12a21bddbd4501a2e0eed2036aca5a0f2a8d44f5a52f2ba4c
|
7
|
+
data.tar.gz: f94b1e95dd4adb95f3b8f1e0c3f7c374c55009f9afafeef37475aefffb43a0c592c6dd8f27cf152ffad1a9df955a1a78df1730904ac36774352d73de58c59232
|
data/.rubocop.yml
CHANGED
data/CHANGES.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
### 1.0.0.beta10 (2019-02-05)
|
2
|
+
* Fixed an edge case in Microsoft Windows specific implementation of
|
3
|
+
`WindowTitles#fetch` where processes with mismatching names and window
|
4
|
+
titles, such as process `"Calculator.exe"` with window title `"CicMarshalWnd"`,
|
5
|
+
were omitted ([#35](https://github.com/kapoorlakshya/ffmpeg-screenrecorder/issues/35)).
|
6
|
+
This fix also prints a warning when this mismatch occurs.
|
7
|
+
* The fix for #35 introduces a mild inconvenience when using
|
8
|
+
applications like Chrome, which spawn a new process per window or
|
9
|
+
extension. `#fetch` now returns titles for these additional processes
|
10
|
+
with the visible window (web page) title. In a future release, you will
|
11
|
+
be able to use something like `full_match: true` to prevent this.
|
12
|
+
* Fixed bug in Linux specific `WindowTitles#fetch` implementation where
|
13
|
+
the filter by application name logic was removed. This filter is required
|
14
|
+
on Linux here because `wmctrl` returns all open window titles unlike
|
15
|
+
Microsoft Windows where `taskmgr` allows us get window titles by process
|
16
|
+
name.
|
17
|
+
* On Linux, you are now required to provide the `input` as `"desktop"`
|
18
|
+
or a display number, such as `":0.0"`. Run `echo $DISPLAY` to check your display number.
|
19
|
+
* QOL improvements - Type checking of inputs, spec cleanup, added more
|
20
|
+
tests, and fixed rubocop warnings.
|
21
|
+
|
1
22
|
### 1.0.0.beta9 (2019-01-22)
|
2
23
|
|
3
24
|
* :warning: `FFMPEG::RecordingRegions` is now `FFMPEG::WindowTitles`, so the module name is true to the function it provides.
|
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
[](https://badge.fury.io/rb/ffmpeg-screenrecorder)
|
4
4
|

|
5
5
|
[](https://www.rubydoc.info/github/kapoorlakshya/ffmpeg-screenrecorder/master)
|
6
|
+
[](https://codeclimate.com/github/kapoorlakshya/ffmpeg-screenrecorder/maintainability)
|
6
7
|
|
7
8
|
Ruby gem to record your computer screen - desktop or specific application/window - using [FFmpeg](https://www.ffmpeg.org/).
|
8
9
|
|
@@ -12,33 +13,18 @@ Supports Windows and Linux as of version `1.0.0-beta5`. macOS support will be ad
|
|
12
13
|
|
13
14
|
## Installation
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
p3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable
|
28
|
-
-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable
|
29
|
-
-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable
|
30
|
-
-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enab
|
31
|
-
le-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libsp
|
32
|
-
eex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --ena
|
33
|
-
ble-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth
|
34
|
-
libavutil 56. 19.101 / 56. 19.101
|
35
|
-
libavcodec 58. 32.100 / 58. 32.100
|
36
|
-
libavformat 58. 18.104 / 58. 18.104
|
37
|
-
libavdevice 58. 4.105 / 58. 4.105
|
38
|
-
libavfilter 7. 33.100 / 7. 33.100
|
39
|
-
libswscale 5. 2.100 / 5. 2.100
|
40
|
-
libswresample 3. 2.100 / 3. 2.100
|
41
|
-
libpostproc 55. 2.100 / 55. 2.100
|
16
|
+
#### 1. Setup FFmpeg
|
17
|
+
|
18
|
+
| OS | Download |
|
19
|
+
|-------------------|--------------------------------------------------------------------------------|
|
20
|
+
| Microsoft Windows | [ffmpeg.org#build-windows](https://www.ffmpeg.org/download.html#build-windows) or [libx264 enabled build](https://ffmpeg.zeranoe.com/builds/) |
|
21
|
+
| Linux | [ffmpeg.org#build-linux](https://ffmpeg.org/download.html#build-linux) |
|
22
|
+
| macOS | [ffmpeg.org#build-mac](https://www.ffmpeg.org/download.html#build-mac) |
|
23
|
+
|
24
|
+
Add location of the `ffmpeg/bin` folder to `PATH` environment variable if using Microsoft Windows ([instructions](https://windowsloop.com/install-ffmpeg-windows-10/)).
|
25
|
+
Alternatively, you can define the location using `FFMPEG.ffmpeg_binary='/path/to/binary'` in your project.
|
26
|
+
|
27
|
+
#### 2. Install gem
|
42
28
|
|
43
29
|
Next, add this line to your application's Gemfile:
|
44
30
|
|
@@ -48,65 +34,57 @@ gem 'ffmpeg-screenrecorder'
|
|
48
34
|
|
49
35
|
And then execute:
|
50
36
|
|
51
|
-
|
37
|
+
```bash
|
38
|
+
$ bundle
|
39
|
+
```
|
52
40
|
|
53
41
|
Or install it yourself as:
|
54
42
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
require ffmpeg-screenrecorder
|
60
|
-
|
61
|
-
## Usage
|
62
|
-
|
63
|
-
#### Required Options
|
64
|
-
|
65
|
-
- `:input` - `'desktop'` or application window name
|
66
|
-
- `:output` - Output file location/name
|
67
|
-
- `:framerate` - Capture FPS
|
68
|
-
|
69
|
-
#### Advanced Options
|
43
|
+
```bash
|
44
|
+
$ gem install ffmpeg-screenrecorder --pre
|
45
|
+
```
|
70
46
|
|
71
|
-
|
72
|
-
- `:log_level` for this gem
|
47
|
+
#### 3. Require gem
|
73
48
|
|
74
|
-
|
49
|
+
Require this gem in your project and start using the gem:
|
75
50
|
|
76
|
-
```
|
77
|
-
|
78
|
-
output: 'recorder-test.mp4',
|
79
|
-
framerate: 15,
|
80
|
-
log: 'recorder.log',
|
81
|
-
log_level: Logger::DEBUG, # For gem
|
82
|
-
advanced: { loglevel: 'level+debug', # For FFmpeg
|
83
|
-
video_size: '640x480',
|
84
|
-
show_region: '1' }
|
85
|
-
}
|
51
|
+
```ruby
|
52
|
+
require 'ffmpeg-screenrecorder'
|
86
53
|
```
|
87
54
|
|
88
55
|
##### Record Desktop
|
89
56
|
|
90
|
-
```
|
57
|
+
```ruby
|
91
58
|
opts = { input: 'desktop',
|
92
|
-
output: '
|
59
|
+
output: 'recording.mp4',
|
93
60
|
framerate: 15.0 }
|
94
61
|
@recorder = FFMPEG::ScreenRecorder.new(opts)
|
95
|
-
|
96
|
-
# Start recording
|
97
|
-
@recorder.start #=> #<IO:fd 5>
|
62
|
+
@recorder.start
|
98
63
|
|
99
64
|
# ... Run tests or whatever you want to record
|
100
65
|
|
101
|
-
|
102
|
-
@recorder.stop #=> #<FFMPEG::Movie...>
|
66
|
+
@recorder.stop
|
103
67
|
|
104
|
-
# Recorded file
|
105
|
-
@recorder.video
|
68
|
+
# Recorded file metadata
|
69
|
+
@recorder.video
|
70
|
+
#=> #<FFMPEG::Movie:0x00000000067e0a08
|
71
|
+
@path="screenrecorder-desktop.mp4",
|
72
|
+
@container="mov,mp4,m4a,3gp,3g2,mj2",
|
73
|
+
@duration=5.0,
|
74
|
+
@time=0.0,
|
75
|
+
@creation_time=nil,
|
76
|
+
@bitrate=1051,
|
77
|
+
@rotation=nil,
|
78
|
+
@video_stream="h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 2560x1440, 1048 kb/s, 15 fps, 15 tbr, 15360 tbn, 30 tbc (default)",
|
79
|
+
@audio_stream=nil,
|
80
|
+
@video_codec="h264 (High 4:4:4 Predictive) (avc1 / 0x31637661)", @colorspace="yuv444p",
|
81
|
+
@video_bitrate=1048,
|
82
|
+
@resolution="2560x1440">
|
106
83
|
```
|
107
84
|
|
108
|
-
##### Record Application Window
|
109
|
-
|
85
|
+
##### Record Application Window
|
86
|
+
|
87
|
+
```ruby
|
110
88
|
require 'watir'
|
111
89
|
|
112
90
|
browser = Watir::Browser.new :firefox
|
@@ -115,33 +93,62 @@ FFMPEG::WindowTitles.fetch('firefox') # Name of exe
|
|
115
93
|
#=> ["Mozilla Firefox"]
|
116
94
|
|
117
95
|
opts = { input: FFMPEG::WindowTitles.fetch('firefox').first,
|
118
|
-
output: '
|
119
|
-
framerate: 15.0
|
120
|
-
log: 'screenrecorder-firefox.log' }
|
96
|
+
output: 'recording.mp4',
|
97
|
+
framerate: 15.0 }
|
121
98
|
@recorder = FFMPEG::ScreenRecorder.new(opts)
|
122
|
-
|
123
|
-
# Start recording
|
124
99
|
@recorder.start
|
125
100
|
|
126
101
|
# Run tests or whatever you want to record
|
127
|
-
browser.goto 'watir.com'
|
128
|
-
browser.link(text: 'News').wait_until_present.click
|
129
102
|
|
130
|
-
# Stop recording
|
131
103
|
@recorder.stop
|
132
|
-
|
133
104
|
browser.quit
|
134
105
|
```
|
135
106
|
|
136
|
-
<b>
|
137
|
-
-
|
138
|
-
-
|
107
|
+
<b>Limitations</b>:
|
108
|
+
- Only works on Microsoft Windows (gdigrab).
|
109
|
+
- `#fetch` only returns titles from currently active (visible) windows.
|
110
|
+
- `#fetch` may return `ArgumentError (invalid byte sequence in UTF-8)`
|
111
|
+
for a window title with non `UTF-8` characters.
|
112
|
+
See [#38](https://github.com/kapoorlakshya/ffmpeg-screenrecorder/issues/38)
|
113
|
+
for workaround.
|
114
|
+
- Always stop the recording before closing the application. Otherwise,
|
115
|
+
ffmpeg will force exit as soon as the window disappears and may produce
|
116
|
+
an invalid video file.
|
117
|
+
- If you're launching multiple applications or testing an application
|
118
|
+
at different window sizes, recording the `desktop` is a better option.
|
119
|
+
|
120
|
+
#### Options
|
139
121
|
|
140
|
-
|
122
|
+
- `:input` - `'desktop'` or application window name
|
123
|
+
- `:output` - Output file location/name
|
124
|
+
- `:framerate` - Capture FPS
|
125
|
+
- `:log` - Defaults to `ffmpeg.log`
|
126
|
+
- `:log_level` for this gem. Default: ERROR
|
127
|
+
|
128
|
+
All other FFmpeg options can be passed through the `advanced` key. This feature is yet to be fully tested, so please feel free to report any bugs or request a feature.
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
opts = { input: 'desktop',
|
132
|
+
output: 'recorder-test.mp4',
|
133
|
+
framerate: 15,
|
134
|
+
log: 'recorder.log',
|
135
|
+
log_level: Logger::DEBUG, # For gem
|
136
|
+
advanced: { loglevel: 'level+debug', # For FFmpeg
|
137
|
+
video_size: '640x480',
|
138
|
+
show_region: '1' }
|
139
|
+
}
|
141
140
|
|
142
|
-
|
141
|
+
#
|
142
|
+
# Command to FFmpeg:
|
143
|
+
#
|
144
|
+
# ffmpeg -y -f gdigrab -r 15 -loglevel level+debug -video_size 640x480
|
145
|
+
# -show_region 1 -i desktop recorder-test.mp4 2> recorder.log
|
146
|
+
```
|
143
147
|
|
144
|
-
|
148
|
+
## Demo
|
149
|
+
|
150
|
+
You can find example video recordings [here](https://kapoorlakshya.github.io/introducing-ffmpeg-screenrecorder).
|
151
|
+
Cucumber + Watir based example is [here](https://github.com/kapoorlakshya/cucumber-watir-test-recorder-example).
|
145
152
|
|
146
153
|
## Development
|
147
154
|
|
@@ -162,6 +169,12 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
162
169
|
|
163
170
|
## Credits
|
164
171
|
|
172
|
+
[](http://streamio.com)
|
173
|
+
|
174
|
+
This gem is based on the [streamio-ffmpeg](https://github.com/streamio/streamio-ffmpeg) gem.
|
175
|
+
<br />
|
176
|
+
<br />
|
177
|
+
|
165
178
|

|
166
179
|
|
167
180
|
Thanks to [SauceLabs](https://saucelabs.com) for providing me with a free account. If you manage an open source project, you can apply for a free account [here](https://saucelabs.com/open-source).
|
@@ -4,12 +4,8 @@ module FFMPEG
|
|
4
4
|
DEFAULT_LOG_FILE = 'ffmpeg.log'.freeze
|
5
5
|
|
6
6
|
def initialize(options)
|
7
|
-
|
8
|
-
|
9
|
-
if options[:advanced]
|
10
|
-
raise ArgumentError, "Expected Hash, given: #{options.class}" unless options[:advanced].is_a? Hash
|
11
|
-
end
|
12
|
-
|
7
|
+
TypeChecker.check options, Hash
|
8
|
+
TypeChecker.check options[:advanced], Hash if options[:advanced]
|
13
9
|
@options = verify_options options
|
14
10
|
end
|
15
11
|
|
@@ -86,7 +82,8 @@ module FFMPEG
|
|
86
82
|
|
87
83
|
#
|
88
84
|
# Verifies the required options are provided and returns
|
89
|
-
# the given options Hash
|
85
|
+
# the given options Hash. Raises ArgumentError if all required
|
86
|
+
# options are not present in the given Hash.
|
90
87
|
#
|
91
88
|
def verify_options(options)
|
92
89
|
missing_options = required_options.select { |req| options[req].nil? }
|
@@ -100,12 +97,7 @@ module FFMPEG
|
|
100
97
|
# Returns Array of required options sa Symbols
|
101
98
|
#
|
102
99
|
def required_options
|
103
|
-
|
104
|
-
# -i input
|
105
|
-
# output
|
106
|
-
return %i[framerate input output] unless OS.linux?
|
107
|
-
|
108
|
-
%i[framerate output] # Linux
|
100
|
+
%i[framerate input output]
|
109
101
|
end
|
110
102
|
|
111
103
|
#
|
@@ -138,7 +130,11 @@ module FFMPEG
|
|
138
130
|
#
|
139
131
|
def determine_input
|
140
132
|
# x11grab doesn't support window capture
|
141
|
-
|
133
|
+
if OS.linux?
|
134
|
+
return ':0.0' if @options[:input] == 'desktop'
|
135
|
+
|
136
|
+
return @options[:input] # User given display number
|
137
|
+
end
|
142
138
|
|
143
139
|
return @options[:input] if @options[:input] == 'desktop'
|
144
140
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module FFMPEG
|
2
|
+
# @since 1.0.0.beta10
|
3
|
+
module TypeChecker
|
4
|
+
#
|
5
|
+
# Compares the given object's type (class) to the desired object type.
|
6
|
+
# Raises an ArgumentError if the object is not of desired type.
|
7
|
+
#
|
8
|
+
def self.check(obj, klass)
|
9
|
+
raise ArgumentError, "Expected #{klass}, given: #{obj.class}" unless obj.is_a? klass
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
data/lib/ffmpeg/version.rb
CHANGED
data/lib/ffmpeg/window_titles.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module FFMPEG
|
2
2
|
# @since 1.0.0-beta4
|
3
3
|
module WindowTitles
|
4
|
+
IGNORED_WINDOW_TITLES = %r{^Window Title:( N/A|\s+)?} # From Chrome extensions
|
5
|
+
|
4
6
|
#
|
5
7
|
# Returns a list of available window titles for the given application (process) name.
|
6
8
|
#
|
@@ -25,32 +27,33 @@ module FFMPEG
|
|
25
27
|
private
|
26
28
|
|
27
29
|
#
|
28
|
-
# Returns list of
|
30
|
+
# Returns list of window titles in FFmpeg expected format when using Microsoft Windows
|
29
31
|
#
|
30
32
|
def windows_os_window(application)
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
raise RecorderErrors::ApplicationNotFound, "No open windows found for: #{application}.exe" if
|
33
|
+
titles = `tasklist /v /fi "imagename eq #{application}.exe" /fo list | findstr Window`
|
34
|
+
.split("\n")
|
35
|
+
.map { |i| i.gsub(IGNORED_WINDOW_TITLES, '') }
|
36
|
+
.reject(&:empty?)
|
37
|
+
raise RecorderErrors::ApplicationNotFound, "No open windows found for: #{application}.exe" if titles.empty?
|
36
38
|
|
37
|
-
|
39
|
+
warn_on_mismatch(titles, application)
|
40
|
+
titles
|
38
41
|
end
|
39
42
|
|
40
43
|
#
|
41
|
-
# Returns list of
|
44
|
+
# Returns list of window titles in FFmpeg expected format when using Linux
|
42
45
|
#
|
43
46
|
def linux_os_window(application)
|
44
|
-
FFMPEG.logger.warn '
|
45
|
-
raise DependencyNotFound, 'wmctrl is not installed. Run: sudo apt
|
47
|
+
FFMPEG.logger.warn 'Default capture device on Linux (x11grab) does not support window recording.'
|
48
|
+
raise DependencyNotFound, 'wmctrl is not installed. Run: sudo apt install wmctrl.' unless wmctrl_installed?
|
46
49
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
raise RecorderErrors::ApplicationNotFound, "No open windows found for: #{application}" if
|
50
|
+
titles = `wmctrl -l | awk '{$3=""; $2=""; $1=""; print $0}'` # Returns all open windows
|
51
|
+
.split("\n")
|
52
|
+
.map(&:strip)
|
53
|
+
.select { |t| t.match?(/#{application}/i) } # Narrow down to given application
|
54
|
+
raise RecorderErrors::ApplicationNotFound, "No open windows found for: #{application}" if titles.empty?
|
52
55
|
|
53
|
-
|
56
|
+
titles
|
54
57
|
end
|
55
58
|
|
56
59
|
#
|
@@ -59,6 +62,17 @@ module FFMPEG
|
|
59
62
|
def wmctrl_installed?
|
60
63
|
!`which wmctrl`.empty? # "" when not found
|
61
64
|
end
|
62
|
-
|
65
|
+
|
66
|
+
#
|
67
|
+
# Prints a warning if the retrieved list of window titles does no include
|
68
|
+
# the given application process name, which applications commonly do.
|
69
|
+
#
|
70
|
+
def warn_on_mismatch(titles, application)
|
71
|
+
unless titles.map(&:downcase).join(',').include? application.to_s
|
72
|
+
FFMPEG.logger.warn "Process name and window title(s) do not match: #{titles}"
|
73
|
+
FFMPEG.logger.warn "Please manually provide the displayed window title."
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end # class WindowGrabber
|
63
77
|
end # module Windows
|
64
78
|
end # module FFMPEG
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ffmpeg-screenrecorder
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.beta10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lakshya Kapoor
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-02-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry-byebug
|
@@ -132,6 +132,7 @@ files:
|
|
132
132
|
- lib/ffmpeg/recorder_errors.rb
|
133
133
|
- lib/ffmpeg/recorder_options.rb
|
134
134
|
- lib/ffmpeg/screenrecorder.rb
|
135
|
+
- lib/ffmpeg/type_checker.rb
|
135
136
|
- lib/ffmpeg/version.rb
|
136
137
|
- lib/ffmpeg/window_titles.rb
|
137
138
|
homepage: http://github.com/kapoorlakshya/ffmpeg-screenrecorder
|