summaryrefslogtreecommitdiff
path: root/lib/booru/image_processing/video_processor.rb
blob: c947a1f55f47d146d6544ebc8c5bb91b4dd73845 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# frozen_string_literal: true
require_relative 'shell_helper'

module Booru
  module ImageProcessing
    class VideoProcessor < Processor
      include ShellHelper

      def initialize(original_path, directory, metadata)
        super(original_path, directory, metadata)
        # We keep around a reference to the Tempfile object so that it doesn't get GC'd (and deleted) too early.
        @rasterized_tempfile = Tempfile.new(%w[still .png]).tap(&:close)
        @rasterized = @rasterized_tempfile.path
      end

      def is_video?
        true
      end

      def pre_process
        write_log 'pre_process'
        generate_rasterized
      end

      def generate_rasterized
        median_time = @metadata[:duration] / 2.0
        generate_thumb @original_path, median_time, @rasterized
      end

      def generate_version(dimensions, destination_path)
        write_log "generate_version #{dimensions} #{destination_path}"

        width, height = dimensions
        width &= 4_294_967_294
        height &= 4_294_967_294

        ffmpeg '-i', @original_path,
               '-c:v', 'libvpx',
               '-deadline', 'good',
               '-cpu-used', '5',
               '-auto-alt-ref', '0',
               '-qmin', '15',
               '-qmax', '35',
               '-crf', '31',
               '-vf', "scale=w=#{width}:h=#{height}:force_original_aspect_ratio=decrease",
               '-max_muxing_queue_size', '4096',
               '-slices', '8',
               destination_path
      end

      def additional_process
        write_log 'additional_process'

        # generate gifs from mp4s/webms; no idea why this is special-cased.
        duration = @metadata[:duration] / 10.0
        duration = 1 if duration == 0

        [[250, :thumb], [150, :thumb_small], [50, :thumb_tiny]].each do |w, n|
          # FIXME: Why is this so EXTREME?
          exec "ffmpeg -loglevel warning -i #{@original_path.shellescape} -vf \"fps=1/#{duration},scale=w=#{w}:h=#{w}:force_original_aspect_ratio=decrease\" -vframes 10 -qscale:v 2 -f image2pipe -vcodec ppm - | convert -delay 50 -loop 0 - gif:- | gifsicle --no-warnings -O2 -o #{@directory}/#{n}.gif"
        end
      end
    end
  end
end