ffmpeg-screenrecorder 1.0.0.beta9 → 1.0.0.beta10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/ffmpeg-screenrecorder.svg)](https://badge.fury.io/rb/ffmpeg-screenrecorder)
|
4
4
|
![https://rubygems.org/gems/ffmpeg-screenrecorder](https://ruby-gem-downloads-badge.herokuapp.com/ffmpeg-screenrecorder?type=total)
|
5
5
|
[![Yard Docs](http://img.shields.io/badge/yard-docs-blue.svg)](https://www.rubydoc.info/github/kapoorlakshya/ffmpeg-screenrecorder/master)
|
6
|
+
[![Maintainability](https://api.codeclimate.com/v1/badges/a176dc755e06a23e5db8/maintainability)](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
|
+
[![Streamio](http://d253c4ja9jigvu.cloudfront.net/assets/small-logo.png)](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
|
![SauceLabs Logo](https://saucelabs.com/content/images/logo.png)
|
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
|