ffmpeg-screenrecorder 1.0.0.beta → 1.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a02c5c9cc4db8684c4a6f3f2f557b0857089c488ef26fc0f6986d7db32ff95cf
4
- data.tar.gz: 03c1e725b98ed53f12d954ad084cf86ebfe41514319ebe14e58aec091029809a
3
+ metadata.gz: e85788e1924b1350003ba607d5cec470878cb2ecc49a5cf53d5508c4604cb38d
4
+ data.tar.gz: b438f32841d00eb3c6d3b6a996379f61a9c5e1c4a74335729bd6fc725bf23bae
5
5
  SHA512:
6
- metadata.gz: 9c3582ca908bb205de16bf887db6750574b5ade7ad3d83e57bb4aada8a092715a121a8681dbcbf3676cce70ec711545a2472d6e46234e6015232b6c0f1af5237
7
- data.tar.gz: 2226a59c6416d4d54a60313e849f09fdff30f6efda276678256b3799b56667d91f126793794c6bf44b72c32005eb8122e058cee88056f42edae033d0ae537f5c
6
+ metadata.gz: f36dafd064d1363b8dd5c42e39c2b840bc6a68db1cc7d42b8c65a667b78e45140c304a47581350a32913a79e6860f34d82778cb89510ec4c1f5925b35f22ee8f
7
+ data.tar.gz: 98763086b2b600ee80cc319b0b5a86bd598aa5e561f309c929afc613ae002caccf535ebb0d00050ad1a75380fd2d87f3e44b106dd13304571b2d13b5499f6a88
data/.gitignore CHANGED
@@ -14,6 +14,7 @@ Gemfile.lock # Part of best practice
14
14
  /pkg/
15
15
  /spec/reports/
16
16
  /tmp/
17
+ /webdrivers_bin
17
18
 
18
19
  Gemfile.lock
19
20
 
@@ -1,5 +1,5 @@
1
1
  Style/EndOfLine:
2
- EnforcedStyle: lf
2
+ EnforcedStyle: crlf
3
3
 
4
4
  Metrics/LineLength:
5
5
  Max: 120
data/README.md CHANGED
@@ -1,6 +1,10 @@
1
1
  # FFMPEG::Screenrecorder
2
2
 
3
- Ruby gem to record your computer screen using [FFMPEG](https://www.ffmpeg.org/).
3
+ Ruby gem to record your computer screen - desktop or specific application/window - using [FFMPEG](https://www.ffmpeg.org/).
4
+
5
+ ## Support
6
+
7
+ Only supports Windows OS as of version `1.0.0-beta2`.
4
8
 
5
9
  ## Installation
6
10
 
@@ -20,7 +24,53 @@ Or install it yourself as:
20
24
 
21
25
  ## Usage
22
26
 
23
- TODO: Write usage instructions here
27
+ ##### Record Desktop
28
+
29
+ ```
30
+ opts = { output: 'ffmpeg-screenrecorder-output.mp4',
31
+ input: 'desktop',
32
+ framerate: 30.0,
33
+ device: 'gdigrab',
34
+ log: 'ffmpeg-screenrecorder-log.txt' }
35
+ @recorder = FFMPEG::Screenrecorder.new(opts)
36
+
37
+ # Start recording
38
+ @recorder.start
39
+
40
+ # ... Run tests or whatever you want to record
41
+
42
+ # Stop recording
43
+ @recorder.stop
44
+
45
+ # Recording file will be available: ffmpeg-screenrecorder-output.mp4
46
+ ```
47
+
48
+ ##### Record Specific Application/Window
49
+ ```
50
+ require 'watir'
51
+
52
+ browser = Watir::Browser.new :firefox
53
+
54
+ FFMPEG::Screenrecorder.window_titles('firefox') # Name of exe
55
+ #=> "Mozilla Firefox"
56
+
57
+ opts = { output: 'ffmpeg-screenrecorder-firefox.mp4',
58
+ input: 'Mozilla Firefox',
59
+ framerate: 30.0,
60
+ device: 'gdigrab',
61
+ log: 'ffmpeg-screenrecorder-firefox.txt' }
62
+ @recorder = FFMPEG::Screenrecorder.new(opts)
63
+
64
+ # Start recording
65
+ @recorder.start
66
+
67
+ # ... Run tests or whatever you want to record
68
+
69
+ # Stop recording
70
+ @recorder.stop
71
+
72
+ # Recording file will be available: ffmpeg-screenrecorder-output.mp4
73
+ ```
24
74
 
25
75
  ## Development
26
76
 
@@ -1,30 +1,31 @@
1
- lib = File.expand_path('lib', __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
-
4
- Gem::Specification.new do |spec|
5
- spec.name = 'ffmpeg-screenrecorder'
6
- spec.version = '1.0.0.beta'
7
- spec.authors = ['Lakshya Kapoor']
8
- spec.email = ['kapoorlakshya@gmail.com']
9
-
10
- spec.summary = 'Record your computer screen using ffmpeg via Ruby.'
11
- spec.description = 'A ruby gem based on streamio-ffmpeg gem to record your computer screen in various formats.'
12
- spec.homepage = 'https://github.com/kapoorlakshya/ruby-ffmpeg_screenrecorder'
13
- spec.license = 'MIT'
14
-
15
- spec.files = Dir.chdir(File.expand_path(__dir__)) do
16
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
- end
18
-
19
- spec.require_paths = ['lib']
20
-
21
- spec.add_development_dependency 'bundler', '~> 1.16'
22
- spec.add_development_dependency 'pry-byebug', '~> 3.6'
23
- spec.add_development_dependency 'rake', '~> 10.0'
24
- spec.add_development_dependency 'rspec', '~> 3.0'
25
- spec.add_development_dependency 'watir', '~> 6.0'
26
- spec.add_development_dependency 'webdrivers', '~> 3.0'
27
-
28
- spec.add_runtime_dependency 'os', '~> 0.9.0'
29
- spec.add_runtime_dependency 'streamio-ffmpeg', '~> 1.0'
30
- end
1
+ lib = File.expand_path('lib', __dir__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ Gem::Specification.new do |spec|
5
+ spec.name = 'ffmpeg-screenrecorder'
6
+ spec.version = '1.0.0.beta2'
7
+ spec.authors = ['Lakshya Kapoor']
8
+ spec.email = ['kapoorlakshya@gmail.com']
9
+
10
+ spec.summary = 'Record your computer screen using ffmpeg via Ruby.'
11
+ spec.description = 'Ruby gem to record your computer screen - desktop or specific application/window' \
12
+ ' - using [FFMPEG](https://www.ffmpeg.org/).'
13
+ spec.homepage = 'https://github.com/kapoorlakshya/ffmpeg-screenrecorder'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
17
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ end
19
+
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.add_development_dependency 'bundler', '~> 1.16'
23
+ spec.add_development_dependency 'pry-byebug', '~> 3.6'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ spec.add_development_dependency 'watir', '~> 6.0'
27
+ spec.add_development_dependency 'webdrivers', '~> 3.0'
28
+
29
+ spec.add_runtime_dependency 'os', '~> 0.9.0'
30
+ spec.add_runtime_dependency 'streamio-ffmpeg', '~> 1.0'
31
+ end
@@ -0,0 +1,106 @@
1
+ module FFMPEG
2
+ class RecorderOptions
3
+
4
+ def initialize(options)
5
+ @options = verify_options options
6
+ end
7
+
8
+ def format
9
+ @options[:format]
10
+ end
11
+
12
+ def framerate
13
+ @options[:framerate]
14
+ end
15
+
16
+ def infile
17
+ @options[:infile]
18
+ end
19
+
20
+ def output
21
+ @options[:output]
22
+ end
23
+
24
+ def advanced
25
+ @options[:advanced]
26
+ end
27
+
28
+ def log
29
+ @options[:log]
30
+ end
31
+
32
+ def log_level
33
+ @options[:log_level]
34
+ end
35
+
36
+ def all
37
+ @options
38
+ end
39
+
40
+ def parsed
41
+ vals = "-f #{@options[:format]} "
42
+ vals << "-r #{@options[:framerate]} "
43
+ vals << advanced_options if @options[:advanced]
44
+ vals << "-i #{determine_infile @options[:infile]} "
45
+ vals << @options[:output]
46
+ vals << ffmpeg_log_to(@options[:log]) # If provided
47
+ end
48
+
49
+ private
50
+
51
+ #
52
+ # Verifies the required options are provided
53
+ #
54
+ def verify_options(options)
55
+ missing_options = required_options.select { |req| options[req].nil? }
56
+ err = "Required options are missing: #{missing_options}"
57
+ raise(ArgumentError, err) unless missing_options.empty?
58
+
59
+ options
60
+ end
61
+
62
+ #
63
+ # Returns Array of require options a Symbols
64
+ #
65
+ def required_options
66
+ # -f format
67
+ # -r framerate
68
+ # -i input
69
+ # output
70
+ %i[format framerate infile output]
71
+ end
72
+
73
+ #
74
+ # Returns advanced options parsed and ready for ffmpeg to receive.
75
+ #
76
+ def advanced_options
77
+ return nil unless @options[:advanced]
78
+ raise(ArgumentError, ':advanced cannot be empty.') if options[:advanced].empty?
79
+
80
+ arr = []
81
+ options[:advanced].each { |k, v|
82
+ arr.push "-#{k} #{v}"
83
+ }
84
+ arr.join(' ') + ' '
85
+ end
86
+
87
+ #
88
+ # Determines if the ffmpeg output will be to a log
89
+ # file based on given options.
90
+ #
91
+ def ffmpeg_log_to(file)
92
+ return " 2> #{file}" if file
93
+ ' > nul 2>&1' # No log file given
94
+ end
95
+
96
+ #
97
+ # Returns final infile parameter.
98
+ # Adds title= qualifier to infile parameter
99
+ # unless the user is recording the desktop.
100
+ #
101
+ def determine_infile(opt)
102
+ return opt if opt == 'desktop'
103
+ %Q("title=#{opt}")
104
+ end
105
+ end
106
+ end
@@ -1,111 +1,75 @@
1
- require 'streamio-ffmpeg'
2
- require 'os'
3
-
4
- module FFMPEG
5
- class Screenrecorder
6
- attr_reader :opts, :output, :process_id
7
-
8
- def initialize(opts = {})
9
- @opts = default_config.merge opts
10
- @output = opts[:output]
11
- @video_file = nil
12
- @process_id = nil
13
- init_logger(opts[:logging_level])
14
- end
15
-
16
- def opts=(new_opts)
17
- @opts = default_config.merge new_opts
18
- @output = opts[:output]
19
- init_logger(opts[:logging_level]) if FFMPEG.logger.level != opts[:logging_level]
20
- end
21
-
22
- def start
23
- FFMPEG.logger.debug "Starting: #{command}"
24
- @video_file = nil # New file
25
- @process_id = start_ffmpeg
26
- FFMPEG.logger.info 'Recording...'
27
- @process_id
28
- end
29
-
30
- def stop
31
- FFMPEG.logger.debug 'Stopping ffmpeg.exe...'
32
- # msg = Process.kill('INT', @process_id)
33
- # Process.detach(@process_id)
34
- msg = kill_ffmpeg
35
- FFMPEG.logger.debug msg
36
- FFMPEG.logger.debug 'Stopped ffmpeg.exe'
37
- FFMPEG.logger.info 'Recording complete.'
38
- msg
39
- end
40
-
41
- # def inputs(application)
42
- # FFMPEG.logger.debug "Retrieving available windows from: #{application}"
43
- # available_inputs_by application
44
- # end
45
-
46
- def video_file
47
- @video_file ||= Movie.new(output)
48
- end
49
-
50
- private
51
-
52
- def default_config
53
- { input: 'desktop',
54
- framerate: 15,
55
- device: 'gdigrab',
56
- log: 'ffmpeg_recorder_log.txt' }
57
- end
58
-
59
- def start_ffmpeg
60
- spawn(command)
61
- pid = `powershell (Get-Process ffmpeg).id`.to_i
62
- raise 'ffmpeg failed to start.' if pid.zero?
63
- pid
64
- end
65
-
66
- def kill_ffmpeg
67
- `TASKKILL /f /im ffmpeg.exe`
68
- end
69
-
70
- def init_logger(level)
71
- FFMPEG.logger.progname = 'FFMPEG::Recorder'
72
- FFMPEG.logger.level = level
73
- FFMPEG.logger.formatter = proc do |severity, time, progname, msg|
74
- "#{time.strftime('%F %T')} #{progname} - #{severity} - #{msg}\n"
75
- end
76
- FFMPEG.logger.debug "Logger initialized."
77
- end
78
-
79
- def command
80
- "#{FFMPEG.ffmpeg_binary} -y " \
81
- "#{extra_opts}" \
82
- "-f #{opts[:device]} " \
83
- "-framerate #{opts[:framerate]} " \
84
- "-i #{opts[:input]} " \
85
- "#{opts[:output]} " \
86
- "2> #{opts[:log]}"
87
- end
88
-
89
- def extra_opts
90
- return nil unless opts[:extra_opts]
91
- raise ':extra_opts cannot be empty.' if opts[:extra_opts].empty?
92
-
93
- arr = []
94
- opts[:extra_opts].each { |k, v|
95
- arr.push "-#{k} #{v}"
96
- }
97
- ' ' + arr.join(' ') + ' '
98
- end
99
-
100
- # def available_inputs_by(application)
101
- # `tasklist /v /fi "imagename eq #{application}.exe" /fo list | findstr Window`
102
- # .split("\n")
103
- # .reject { |title| title == 'Window Title: N/A' }
104
- # end
105
- #
106
- # def input
107
- # return opts[:input] if opts[:input] == 'desktop'
108
- # %Q(title="#{opts[:input].gsub('Window Title: ', '')}")
109
- # end
110
- end # class Recorder
111
- end # module FFMPEG
1
+ require 'streamio-ffmpeg'
2
+ require 'os'
3
+ require_relative 'recorder_options'
4
+ require_relative 'windows'
5
+
6
+ module FFMPEG
7
+ class Screenrecorder
8
+ extend Windows
9
+
10
+ attr_reader :options, :video
11
+
12
+ def initialize(options = {})
13
+ @options = RecorderOptions.new(options)
14
+ @video = nil
15
+ @process = nil
16
+ initialize_logger(@options.log_level || Logger::ERROR)
17
+ end
18
+
19
+ def start
20
+ @video = nil # New file
21
+ start_time = Time.now
22
+ @process = start_ffmpeg
23
+ elapsed = Time.now - start_time
24
+ FFMPEG.logger.debug "Process started in #{elapsed}s"
25
+ FFMPEG.logger.info 'Recording...'
26
+ end
27
+
28
+ def stop
29
+ FFMPEG.logger.debug 'Stopping ffmpeg.exe...'
30
+ elapsed = kill_ffmpeg
31
+ FFMPEG.logger.debug "Stopped ffmpeg.exe in #{elapsed}s"
32
+ FFMPEG.logger.info 'Recording complete.'
33
+ @video = Movie.new(options.output)
34
+ end
35
+
36
+ private
37
+
38
+ def start_ffmpeg
39
+ FFMPEG.logger.debug "Command: #{command}"
40
+ process = IO.popen(command, 'r+')
41
+ sleep(1.5) # Takes ~1.5s on average to initialize
42
+ process
43
+ end
44
+
45
+ def kill_ffmpeg
46
+ @process.puts 'q' # Gracefully exit ffmpeg
47
+ elapsed = wait_for_io_eof(5)
48
+ @process.close_write # Close IO
49
+ elapsed
50
+ end
51
+
52
+ def initialize_logger(level)
53
+ FFMPEG.logger.progname = 'FFMPEG'
54
+ FFMPEG.logger.level = level
55
+ FFMPEG.logger.formatter = proc do |severity, time, progname, msg|
56
+ "#{time.strftime('%F %T')} #{progname} - #{severity} - #{msg}\n"
57
+ end
58
+ FFMPEG.logger.debug 'Logger initialized.'
59
+ end
60
+
61
+ def command
62
+ cmd = "#{FFMPEG.ffmpeg_binary} -y "
63
+ cmd << @options.parsed
64
+ end
65
+
66
+ def wait_for_io_eof(timeout)
67
+ start = Time.now
68
+ Timeout.timeout(timeout) do
69
+ sleep(0.1) until @process.eof?
70
+ end
71
+ FFMPEG.logger.debug "IO#eof? #{@process.eof?}"
72
+ Time.now - start
73
+ end
74
+ end # class Recorder
75
+ end # module FFMPEG
@@ -0,0 +1,18 @@
1
+ module FFMPEG
2
+ module Windows
3
+
4
+ def window_titles(application)
5
+ FFMPEG.logger.debug "Retrieving available windows for: #{application}"
6
+ WindowGrabber.new.available_windows_for application
7
+ end
8
+
9
+ class WindowGrabber
10
+ def available_windows_for(application)
11
+ list = `tasklist /v /fi "imagename eq #{application}.exe" /fo list | findstr Window`
12
+ .split("\n")
13
+ .reject { |title| title == 'Window Title: N/A' }
14
+ list.map { |i| i.gsub('Window Title: ', '') } # Make it user friendly
15
+ end
16
+ end
17
+ end # module Windows
18
+ 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.beta
4
+ version: 1.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lakshya Kapoor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-27 00:00:00.000000000 Z
11
+ date: 2018-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,8 +122,8 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.0'
125
- description: A ruby gem based on streamio-ffmpeg gem to record your computer screen
126
- in various formats.
125
+ description: Ruby gem to record your computer screen - desktop or specific application/window
126
+ - using [FFMPEG](https://www.ffmpeg.org/).
127
127
  email:
128
128
  - kapoorlakshya@gmail.com
129
129
  executables: []
@@ -142,8 +142,10 @@ files:
142
142
  - bin/setup
143
143
  - ffmpeg-screenrecorder.gemspec
144
144
  - lib/ffmpeg.rb
145
+ - lib/ffmpeg/recorder_options.rb
145
146
  - lib/ffmpeg/screenrecorder.rb
146
- homepage: https://github.com/kapoorlakshya/ruby-ffmpeg_screenrecorder
147
+ - lib/ffmpeg/windows.rb
148
+ homepage: https://github.com/kapoorlakshya/ffmpeg-screenrecorder
147
149
  licenses:
148
150
  - MIT
149
151
  metadata: {}