Class: Subconv::Scc::Transformer

Inherits:
Object
  • Object
show all
Defined in:
lib/subconv/scc/transformer.rb

Overview

Transform an array of caption grids parsed from SCC into an array of captions with the caption content converted to a tree of text and style nodes

Instance Method Summary collapse

Instance Method Details

#combine_paint_on_captions(captions) ⇒ Object

Transform paint-on captions to pop-on captions by combining successive captions that only add text. As soon as text is removed or text that is already on-screen is changed, a caption is produced.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/subconv/scc/transformer.rb', line 64

def combine_paint_on_captions(captions)
  first_paint_on_caption = nil
  last_paint_on_caption = nil
  # Insert nil pseudo-element at end for flushing
  (captions + [nil]).each_with_object([]) do |caption, result_captions|
    if caption&.paint_on_mode?
      first_paint_on_caption ||= caption
      # Detect when characters disappear/change; until then: skip all paint-on captions (that just add text).
      # At the same time, always produce a cue for empty grids so explicit display clears do not get lost.
      # Simple character replacement cues that replace standard characters with extended ones should also never trigger a new caption.
      if !last_paint_on_caption.nil? && !caption.char_replacement? && (!require_grid_object(last_paint_on_caption.grid).without_identical_characters(require_grid_object(caption.grid)).empty? || last_paint_on_caption.grid.nil?)
        # Take timecode from the first caption of the current batch, but the grid from the current caption
        result_captions << Scc::Caption.new(timecode: first_paint_on_caption.timecode, grid: last_paint_on_caption.grid, mode: :pop_on)
        # Caption produced, so this marks a new segment
        first_paint_on_caption = caption
      end
      last_paint_on_caption = caption
    else
      # Flush out last paint-on caption if necessary
      result_captions << Scc::Caption.new(timecode: first_paint_on_caption.timecode, grid: last_paint_on_caption.grid, mode: :pop_on) unless first_paint_on_caption.nil?
      first_paint_on_caption = nil
      last_paint_on_caption = nil
      result_captions << caption unless caption.nil?
    end
  end
end

#transform(captions) ⇒ Object

Perform the transformation Continuous text blocks are collected in each caption grid and merged Empty grids will end the previously displayed caption



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
# File 'lib/subconv/scc/transformer.rb', line 14

def transform(captions)
  transformed_captions = []
  return [] if captions.empty?

  # Use fps from Scc
  fps = captions.first.timecode.fps
  last_time = Timecode.new(0, fps)

  captions_open = []
  captions.each do |caption|
    if caption.grid.nil? || !captions_open.empty?
      # Close any captions that might be displayed
      captions_open.each do |caption_to_close|
        caption_to_close.timespan = Utility::Timespan.new(last_time.dup, caption.timecode.dup)
      end
      transformed_captions.concat captions_open
      # All captions are closed now
      captions_open = []
    end

    # Collect text chunks in each row and create captions out of them
    caption.grid&.each_with_index do |row, row_number|
      chunks = collect_chunks(row)
      chunks.each_pair do |start_column, chunk|
        content = transform_chunk(chunk)
        position = position_from_grid(row_number, start_column)
        captions_open.push(Subconv::Caption.new(
          align:    :start,
          position: position,
          content:  content
        ))
      end
    end

    last_time = caption.timecode
  end

  unless captions_open.empty?
    # Close any captions that are still open at the end
    captions_open.each do |caption_to_close|
      caption_to_close.timespan = Utility::Timespan.new(last_time.dup, last_time + Timecode.from_seconds(5, fps))
    end
    transformed_captions.concat captions_open
  end

  transformed_captions
end