require 'fileutils' require 'RMagick' require 'streamio-ffmpeg' class Turmeric DEFAULT_OPTIONS = { tmp_dir: "./tmp/", resolution: "200x100", duration: ->(movie){ movie.duration.to_i.times } }.freeze attr_accessor :tmp_dir, :resolution, :duration attr_reader :frames def initialize(filename, **options) @movie = FFMPEG::Movie.new(filename) reset(**options) end def reset(**options) @frames = [] @tmp_dir = options[:tmp_dir] || DEFAULT_OPTIONS[:tmp_dir] @resolution = options[:resolution] || DEFAULT_OPTIONS[:resolution] @duration = options[:duration] || DEFAULT_OPTIONS[:duration] end def logger FFMPEG.logger end def logger=(logger) FFMPEG.logger = logger end def screenshot(path, **options) @movie.screenshot(path, resolution: resolution, **options) end def ensure_output_directory FileUtils.mkdir_p(tmp_dir) end def to_animation(output_file = "result.gif") ensure_output_directory unless File.exist?(tmp_dir) each_duration do |second| path = "#{tmp_dir}#{second}.png" begin screenshot(path, seek_time: second) ensure frames << path end end Magick::ImageList.new(*frames).coalesce.write(output_file) ensure FileUtils.rm(Dir.glob(File.join(tmp_dir, "*"))) end alias to_anime to_animation def each_duration(&block) if @duration.respond_to?(:call) @duration.call @movie else @duration.instance_of?(Range) ? @duration : @duration.times end.each(&block) end end