class VideoSprites::Processor

Public Class Methods

new(input_file, output_directory, options=nil) click to toggle source
# File lib/video_sprites/processor.rb, line 3
def initialize(input_file, output_directory, options=nil)
  @input_file = input_file
  @output_directory = output_directory
  FileUtils.mkdir_p @output_directory unless File.exist? @output_directory
  @options = options || default_options
end

Public Instance Methods

all_images() click to toggle source
# File lib/video_sprites/processor.rb, line 113
def all_images
  if @all_images
    @all_images
  else
    images = Dir[all_images_glob]
    images.pop
    @all_images = images
  end
end
all_images_glob() click to toggle source
# File lib/video_sprites/processor.rb, line 123
def all_images_glob
  File.join @temporary_directory, '*'
end
basename() click to toggle source

TODO: make basename configurable

# File lib/video_sprites/processor.rb, line 140
def basename
  "sprites"
end
clean_temporary_directory() click to toggle source
# File lib/video_sprites/processor.rb, line 178
def clean_temporary_directory
  FileUtils.rm_rf @temporary_directory
end
create_gif() click to toggle source
# File lib/video_sprites/processor.rb, line 70
def create_gif
  `convert -geometry #{@options[:width]}x -delay 20 -loop 0 #{all_images.join(' ')} #{gif_output_filename}`
end
create_images() click to toggle source
# File lib/video_sprites/processor.rb, line 27
def create_images
  # run ffmpeg command
  `#{ffmpeg_cmd}`
end
create_sprites() click to toggle source
# File lib/video_sprites/processor.rb, line 32
def create_sprites
  # determine how many images go in each sprite
  all_images.each_slice(images_per_sprite).with_index do |(*sprite_slice), index|
    cmd = montage_cmd(sprite_slice, index)
    # puts cmd
    `#{cmd}`
  end
end
create_temporary_directory() click to toggle source
# File lib/video_sprites/processor.rb, line 22
def create_temporary_directory
  @temporary_directory = Dir.mktmpdir
  puts @temporary_directory
end
create_webvtt() click to toggle source
# File lib/video_sprites/processor.rb, line 41
def create_webvtt
  @webvtt = "WEBVTT\n\nNOTE This file was automatically generated by https://github.com/jronallo/video_sprites\n\n"
  start = 0
  total = 0
  sprite_count.times do |sprite_index|
    sprite_filename_base = File.basename sprite_filename(sprite_index)
    puts sprite_filename_base
    @options[:group].times do |group_index|
      next if total >= all_images.length
      cue_start = start
      cue_end = start + @options[:seconds]
      x = ((group_index % @options[:columns]) * @options[:width])
      y = (group_index.to_f / @options[:columns].to_f).floor * processed_height

      fractional_start = start == 0 ? "000" : "001"
      cue_times = "#{formatted_time(cue_start)}.#{fractional_start} --> #{formatted_time(cue_end)}.000\n"
      puts cue_times
      cue_text = "#{sprite_filename_base}#xywh=#{x},#{y},#{@options[:width]},#{processed_height}\n\n"
      @webvtt += cue_times
      @webvtt += cue_text
      start = cue_end
      total += 1
    end
  end
  File.open(webvtt_output_filename, 'w') do |fh|
    fh.puts @webvtt
  end
end
default_options() click to toggle source
# File lib/video_sprites/processor.rb, line 103
def default_options
  {
    seconds: 10,
    width:   200,
    columns: 5,
    group:   20,
    gif:     false
  }
end
ffmpeg_cmd() click to toggle source
# File lib/video_sprites/processor.rb, line 74
def ffmpeg_cmd
  %Q|ffmpeg -i "#{@input_file}" -vf fps=1/#{@options[:seconds]} #{thumbnail_image_path} |
end
first_jpeg() click to toggle source
# File lib/video_sprites/processor.rb, line 127
def first_jpeg
  all_images.first
end
formatted_time(total_seconds) click to toggle source
# File lib/video_sprites/processor.rb, line 156
def formatted_time(total_seconds)
  seconds = total_seconds % 60
  minutes = (total_seconds / 60) % 60
  hours = total_seconds / (60 * 60)

  # TODO: format start times to start at .0001
  format("%02d:%02d:%02d", hours, minutes, seconds)
end
gif_output_filename() click to toggle source
# File lib/video_sprites/processor.rb, line 95
def gif_output_filename
  File.join @output_directory, "#{basename}.gif"
end
images_per_sprite() click to toggle source
# File lib/video_sprites/processor.rb, line 135
def images_per_sprite
  @options[:group]
end
keep_images_directory() click to toggle source
# File lib/video_sprites/processor.rb, line 170
def keep_images_directory
  File.join @output_directory, 'images'
end
montage_cmd(sprite_slice, index) click to toggle source
# File lib/video_sprites/processor.rb, line 78
def montage_cmd(sprite_slice, index)
  image_files = sprite_slice.join(' ')
  %Q|montage #{image_files} -tile #{@options[:columns]}x -geometry #{@options[:width]}x #{sprite_filename(index)}|
end
move_images() click to toggle source
# File lib/video_sprites/processor.rb, line 165
def move_images
  FileUtils.mkdir keep_images_directory unless File.exist? keep_images_directory
  FileUtils.mv Dir.glob(temporary_directory_glob), keep_images_directory
end
original_height() click to toggle source
# File lib/video_sprites/processor.rb, line 144
def original_height
  `identify -format "%h" -ping "#{first_jpeg}"`.to_f
end
original_width() click to toggle source
# File lib/video_sprites/processor.rb, line 148
def original_width
  `identify -format "%w" -ping "#{first_jpeg}"`.to_f
end
padded_index(index) click to toggle source
# File lib/video_sprites/processor.rb, line 99
def padded_index(index)
  (index + 1).to_s.rjust(5, "0")
end
process() click to toggle source
# File lib/video_sprites/processor.rb, line 10
def process
  create_temporary_directory
  create_images
  create_sprites
  create_webvtt
  create_gif if @options[:gif]
  if @options[:keep_images]
    move_images
  end
  clean_temporary_directory
end
processed_height() click to toggle source
# File lib/video_sprites/processor.rb, line 152
def processed_height
  (original_height.to_f / original_width.to_f * @options[:width]).to_i
end
sprite_count() click to toggle source
# File lib/video_sprites/processor.rb, line 131
def sprite_count
  (all_images.length.to_f / @options[:group]).ceil
end
sprite_filename(index) click to toggle source
# File lib/video_sprites/processor.rb, line 87
def sprite_filename(index)
  File.join @output_directory, "#{basename}-sprite-#{padded_index(index)}.jpg"
end
temporary_directory_glob() click to toggle source
# File lib/video_sprites/processor.rb, line 174
def temporary_directory_glob
  File.join @temporary_directory, '*.jpg'
end
thumbnail_image_path() click to toggle source
# File lib/video_sprites/processor.rb, line 83
def thumbnail_image_path
  File.join @temporary_directory, 'img-%05d.jpg'
end
webvtt_output_filename() click to toggle source
# File lib/video_sprites/processor.rb, line 91
def webvtt_output_filename
  File.join @output_directory, "#{basename}.vtt"
end