class FFMPEG::ScreenRecorder

@since 1.0.0-beta

Constants

VERSION

Attributes

options[R]
video[R]

Public Class Methods

new(options = {}) click to toggle source
# File lib/ffmpeg/screenrecorder.rb, line 12
def initialize(options = {})
  @options = RecorderOptions.new(options)
  @video   = nil
  @process = nil
  initialize_logger(@options.log_level)
end

Public Instance Methods

delete()
Alias for: discard
discard() click to toggle source

Discards the recorded file. Useful in automated testing when a test passes and the recorded file is no longer needed.

# File lib/ffmpeg/screenrecorder.rb, line 48
def discard
  FileUtils.rm options.output
end
Also aliased as: delete
start() click to toggle source

Starts the recording

# File lib/ffmpeg/screenrecorder.rb, line 22
def start
  @video     = nil # New file
  start_time = Time.now
  @process   = start_ffmpeg
  elapsed    = Time.now - start_time
  FFMPEG.logger.debug "Process started in #{elapsed}s"
  FFMPEG.logger.info 'Recording...'
  @process
end
stop() click to toggle source

Stops the recording

# File lib/ffmpeg/screenrecorder.rb, line 35
def stop
  FFMPEG.logger.debug 'Stopping ffmpeg.exe...'
  elapsed = kill_ffmpeg
  FFMPEG.logger.debug "Stopped ffmpeg.exe in #{elapsed}s"
  FFMPEG.logger.info 'Recording complete.'
  @video = Movie.new(options.output)
end

Private Instance Methods

command() click to toggle source

Generates the command line arguments based on the given options.

# File lib/ffmpeg/screenrecorder.rb, line 99
def command
  cmd = "#{FFMPEG.ffmpeg_binary} -y "
  cmd << @options.parsed
end
ffmpeg_exists?() click to toggle source

Returns true if ffmpeg binary is found.

# File lib/ffmpeg/screenrecorder.rb, line 120
def ffmpeg_exists?
  return !`which ffmpeg`.empty? if OS.linux? # "" if not found

  return !`where ffmpeg`.empty? if OS.windows?

  # If the user does not use FFMPEG#ffmpeg_binary=() to set the binary path,
  # FFMPEG#ffmpeg_binary returns 'ffmpeg' assuming it must be in ENV. However,
  # if the above two checks fail, it is not in the ENV either.
  return false if FFMPEG.ffmpeg_binary == 'ffmpeg'

  true
end
get_lines_from_log(position = :last, count = 2) click to toggle source

Returns lines from the log file

# File lib/ffmpeg/screenrecorder.rb, line 136
def get_lines_from_log(position = :last, count = 2)
  f     = File.open(options.log)
  lines = f.readlines
  lines = lines.last(count) if position == :last
  lines = lines.first(count) if position == :first
  f.close

  lines.join(' ')
end
initialize_logger(level) click to toggle source

Initializes the logger with the given log level.

# File lib/ffmpeg/screenrecorder.rb, line 86
def initialize_logger(level)
  FFMPEG.logger.progname  = 'FFmpeg'
  FFMPEG.logger.level     = level || Logger::ERROR
  FFMPEG.logger.formatter = proc do |severity, time, progname, msg|
    "#{time.strftime('%F %T')} #{progname} - #{severity} - #{msg}\n"
  end
  FFMPEG.logger.debug 'Logger initialized.'
end
kill_ffmpeg() click to toggle source

Sends 'q' to the ffmpeg binary to gracefully stop the process.

# File lib/ffmpeg/screenrecorder.rb, line 72
def kill_ffmpeg
  @process.puts 'q' # Gracefully exit ffmpeg
  elapsed = wait_for_io_eof(5)
  @process.close_write # Close IO
  elapsed
rescue Errno::EPIPE
  # Gets last line from log file
  err_line = get_lines_from_log(:last, 2)
  raise FFMPEG::Error, err_line
end
start_ffmpeg() click to toggle source

Launches the ffmpeg binary using a generated command based on the given options.

# File lib/ffmpeg/screenrecorder.rb, line 60
def start_ffmpeg
  raise RecorderErrors::DependencyNotFound, 'ffmpeg binary not found.' unless ffmpeg_exists?

  FFMPEG.logger.debug "Command: #{command}"
  process = IO.popen(command, 'r+')
  sleep(1.5) # Takes ~1.5s on average to initialize
  process
end
wait_for_io_eof(timeout) click to toggle source

Waits for IO#eof? to return true after 'q' is sent to the ffmpeg process.

# File lib/ffmpeg/screenrecorder.rb, line 108
def wait_for_io_eof(timeout)
  start = Time.now
  Timeout.timeout(timeout) do
    sleep(0.1) until @process.eof?
  end
  FFMPEG.logger.debug "IO#eof? #{@process.eof?}"
  Time.now - start
end