Module: AnimateIt::AssetRenderer

Defined in:
lib/animate_it/asset_renderer.rb

Overview

Drives a composition through every Output it declared, writing each one to its absolute repo-relative path. Outputs covering the same frame range share one ordered browser capture; each format still gets its own encoder.

Class Method Summary collapse

Class Method Details

.capture_key_for(composition, frame_range) ⇒ Object



54
55
56
57
# File 'lib/animate_it/asset_renderer.rb', line 54

def capture_key_for(composition, frame_range)
  range = frame_range || (0...composition.duration_in_frames)
  [range.first, range.last]
end

.effective_range_for(output, frame_range) ⇒ Object

A still PNG output always renders its declared single frame; if the caller-supplied range excludes that frame, skip the output entirely. Animated outputs use the caller's range when provided, otherwise render the full composition.



71
72
73
74
75
76
77
78
79
# File 'lib/animate_it/asset_renderer.rb', line 71

def effective_range_for(output, frame_range)
  if output.still?
    return :skip if frame_range && !frame_range.cover?(output.frame)

    output.frame..output.frame
  else
    frame_range
  end
end

.frames_dir_for(composition, capture_key, primary:) ⇒ Object



59
60
61
62
63
64
65
# File 'lib/animate_it/asset_renderer.rb', line 59

def frames_dir_for(composition, capture_key, primary:)
  base = Rails.root.join("tmp/animate_it/#{composition.id}")
  return base if primary

  start_frame, end_frame = capture_key
  base.join("captures/#{start_frame}-#{end_frame}")
end

.render_composition(composition, host:, on_progress: nil, frame_range: nil) ⇒ Object

Raises:



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
# File 'lib/animate_it/asset_renderer.rb', line 8

def render_composition(composition, host:, on_progress: nil, frame_range: nil)
  raise Error, "Composition #{composition.id} has no `outputs do ... end`" if composition.outputs.empty?

  capture_dirs = {}
  composition.outputs.map do |output|
    effective_range = effective_range_for(output, frame_range)
    next if effective_range == :skip

    capture_key = capture_key_for(composition, effective_range)
    frames_dir = capture_dirs[capture_key]
    reuse_captured_frames = capture_dirs.key?(capture_key)
    frames_dir ||= frames_dir_for(composition, capture_key, primary: capture_dirs.empty?)
    capture_dirs[capture_key] = frames_dir

    render_output(
      composition,
      output,
      host:,
      on_progress:,
      frame_range: effective_range,
      frames_dir:,
      reuse_captured_frames:
    )
  end
end

.render_output(composition, output, host:, on_progress: nil, frame_range: nil, frames_dir: nil, reuse_captured_frames: false) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/animate_it/asset_renderer.rb', line 34

def render_output(composition, output, host:, on_progress: nil, frame_range: nil, frames_dir: nil,
                  reuse_captured_frames: false)
  effective_range = effective_range_for(output, frame_range)
  return nil if effective_range == :skip

  destination = output.absolute_path
  FileUtils.mkdir_p(destination.dirname)

  renderer = VideoRenderer.new(
    composition: composition,
    host: host,
    output_path: destination,
    format: output.format,
    frames_dir:
  )

  renderer.render(frame_range: effective_range, on_progress:, reuse_captured_frames:)
  destination
end