class TeslaCam::Model

Constants

CAMS

list of camera symbols

TIME_FORMAT

Format string for ISO-8601 timestamps.

VIDEO_PATH_RE

Regular expression to extract relevant data from video file names.

Attributes

config[RW]

Public Class Methods

new(config, log) click to toggle source
# File lib/teslacam/model.rb, line 28
def initialize(config, log)
  # cache config
  @config = config
  @log = log

  # extract video sets from input file names
  @videos = parse_inputs(config.inputs)
  @times = @videos.keys.sort
  @paths = get_paths(@times, @videos)
  @filter = TeslaCam::Filter.new(self)
  @command = get_command(config, @paths, @filter)
end

Public Instance Methods

multiple_video_sets?() click to toggle source

Are there multiple video sets?

# File lib/teslacam/model.rb, line 44
def multiple_video_sets?
  @videos.keys.size > 1
end

Private Instance Methods

get_command(config, paths, filter) click to toggle source

build ffmpeg command

# File lib/teslacam/model.rb, line 100
def get_command(config, paths, filter)
  [
    config.ffmpeg,

    # hide ffmpeg banner
    '-hide_banner',

    # set ffmpeg log level
    '-loglevel', (config.quiet ? 'fatal' : 'info'),

    # sorted list of videos (in order of CAMS, see above)
    *(paths.map { |path| ['-i', path] }.flatten),

    # filter command
    '-filter_complex', filter.to_s,
    '-c:v', 'libx264',

    # output path
    config.output,
  ]
end
get_paths(times, videos) click to toggle source

Build ordered list of video input paths.

# File lib/teslacam/model.rb, line 87
def get_paths(times, videos)
  times.reduce([]) do |r, time|
    CAMS.select { |cam|
      videos[time].key?(cam)
    }.reduce(r) do |r, cam|
      r << videos[time][cam][:path]
    end
  end
end
parse_inputs(inputs) click to toggle source

extract video sets from input file names

# File lib/teslacam/model.rb, line 53
def parse_inputs(inputs)
  # extract video sets from input file names
  videos = inputs.each.with_object(Hash.new { |h, k| h[k] = {} }) do |path, r|
    if md = ::File.basename(path).match(VIDEO_PATH_RE)
      # build data
      data = (md.names.each.with_object({}) { |s, mr|
        i = s.intern
        mr[i] = md[i]
      }).merge({
        path: path,
      })

      # build key
      key = TIME_FORMAT % data
      r[key][md[:name].intern] = data
    end
  end

  # check for missing videos in each set
  videos.each do |time, videos|
    missing = CAMS - videos.keys
    if missing.size > 0
      # some videos missing, raise warning
      @log.warn { "missing videos in #{time}: #{missing * ', '}" }
    end
  end

  # return videos
  videos
end