captionbob docs

Version 1.0.0
Contents ↓

Python: captionbob.effects

captionbob.effects.ruby

The ruby effect: heavy white capitals with a thick black outline.

Each caption shows its words in heavy white capitals with no end marks, with room between the letters and a thick black outline around them. A caption holds up to three words, and it ends at each end mark, such as a comma. A caption stays on one line up to the line letters, and a longer caption is cut into two lines, the top line with the larger half of the words. A keyword has its keyword color for the whole caption, and the keywords of a video take the keyword colors in turn.

A caption pops in: it shows larger at its start and shrinks to its full size in the pop time. A caption of one line keeps its middle while it shrinks. In a caption of two lines the top line keeps its bottom and the second line keeps its top.

Each line of a caption has two events with the times of the caption. The outline event draws the letters in the outline color, with a border that reaches the outline width past the stroke. The text event draws the letters over it, with a stroke in the color of the letters that makes them heavier. Each letter of the two events gets the letter gap after it, and each space gets the word gap after it.

An emoji is not drawn by ASS. build_layers gives one emoji layer for each caption with a keyword, with the times of the caption. The emoji is above the caption in the middle of the video, at its full size at once.

The settings of the lines, the captions with their lines and keywords, the places of the lines, the edge of the emoji, the pop tags, the keyword colors in turn and the text of a line come from LineSettings, line_captions, pop_tags, keywords_in_turn and word_lines_text of effect_common. The emoji layer is PopEmojiLayer of effect_common.

Source file: captionbob/effects/ruby.py

Settings

The command line and the HTTP API call this effect the style ruby. Its settings class is RubySettings. Each setting has the default below.

Setting Type Default Description
most_words integer 3 The most words that one caption shows.
fewest_words integer 1 The fewest words that one caption shows, when its sentence is long enough for that.
font_name string "Ubuntu" Name of the font of the text.
font_size integer 95 Height of the font in pixels.
bold boolean true True for bold text.
primary_color string "#FFFFFF" Color of the text, as "#RRGGBB".
stroke_color string "#FFFFFF" Color of the outline of the text, as "#RRGGBB".
stroke_width number 3.5 Width of the outline in pixels. 0 gives no outline.
bottom_position number 0.712 Where the bottom of the caption sits, as a part of the video height from the top. 0.75 is three quarters of the way down.
side_margin integer 54 Room in pixels that stays free on the left and on the right of the caption. A caption that is too wide for the room between the margins breaks into lines.
letter_width number 0.89 The width of the letters as a part of the width that the font gives them, above 0. 1 keeps the width of the font.
line_gap number 7.5 Room in pixels between the bottom of the top line and the top of the second line. A value below 0 puts the lines closer.
capitals boolean true True to write the words in capitals.
end_at_marks boolean true True to end a caption at each end mark, such as a comma.
line_letters integer 17 The most letters, with the spaces, of a caption that stays on one line, 1 or above.
letter_gap number 7.5 Room in pixels that is added after each letter, at the letter width. The last letter of a word gets it too. A value below 0 puts the letters closer.
word_gap number -2.7 Room in pixels that is added after each space, at the letter width. A value below 0 puts the words closer.
keyword_colors list ["#E1253E", "#F2DE3E", "#3DFF62"] The colors of the letters and of the stroke of the keywords, as "#RRGGBB". The keywords of a video take them in turn.
outline_color string "#000000" The color of the outline around the letters, as "#RRGGBB".
outline_width number 10.5 How far the outline reaches past the stroke, in pixels. 0 gives no outline.
pop_scale number 1.24 The size of a caption at its start, as a part of its full size, above 0. 1 shows it at its full size at once.
pop_seconds number 0.05 The time in which a caption changes to its full size. 0 shows it at its full size at once.
emoji_size number 190.0 The side of the emoji in pixels, above 0.
emoji_gap number -5.0 Room in pixels between the bottom of the emoji and the top of the top line. A value below 0 puts the emoji lower.
hold_seconds number 0.0 The longest time that a caption stays after its last word ends. The caption goes earlier when the next caption starts.

RubyLayers

class RubyLayers(NamedTuple)

What the effect gives for the words of one video.

Args:

  • ass_text: The text of the ASS script.
  • emojis: One emoji layer for each caption with a keyword, in time order.

RubySettings

@dataclass(frozen=True)
class RubySettings(LineSettings)

The look and the timing of the ruby effect.

The settings of CaptionSettings come first: the word counts, the font, the colors, the stroke, the bottom position and the side margin. The settings of LineSettings follow them, from the letter width to the line letters, and then the letter gap, the word gap, the keyword colors, the settings of the outline, of the pop and of the emoji, and the hold time. The effect changes the defaults of some of them. The stroke is the outline of the letters in their own color, which makes them heavier. The bottom position is the bottom of the top line.

Args:

  • letter_width: The width of the letters as a part of the width that the font gives them, above 0. 1 keeps the width of the font.
  • line_gap: Room in pixels between the bottom of the top line and the top of the second line. A value below 0 puts the lines closer.
  • capitals: True to write the words in capitals.
  • end_at_marks: True to end a caption at each end mark, such as a comma.
  • line_letters: The most letters, with the spaces, of a caption that stays on one line, 1 or above.
  • letter_gap: Room in pixels that is added after each letter, at the letter width. The last letter of a word gets it too. A value below 0 puts the letters closer.
  • word_gap: Room in pixels that is added after each space, at the letter width. A value below 0 puts the words closer.
  • keyword_colors: The colors of the letters and of the stroke of the keywords, as "#RRGGBB". The keywords of a video take them in turn.
  • outline_color: The color of the outline around the letters, as "#RRGGBB".
  • outline_width: How far the outline reaches past the stroke, in pixels. 0 gives no outline.
  • pop_scale: The size of a caption at its start, as a part of its full size, above 0. 1 shows it at its full size at once.
  • pop_seconds: The time in which a caption changes to its full size. 0 shows it at its full size at once.
  • emoji_size: The side of the emoji in pixels, above 0.
  • emoji_gap: Room in pixels between the bottom of the emoji and the top of the top line. A value below 0 puts the emoji lower.
  • hold_seconds: The longest time that a caption stays after its last word ends. The caption goes earlier when the next caption starts.

Raises:

  • TypeError: When a word count or the line letters is not a whole number.
  • ValueError: When a value is outside its range, or when a color is not in the form "#RRGGBB".

RubySettings.has_outline

def has_outline(self) -> bool

True when the outline reaches past the stroke.

RubySettings.letter_tags

def letter_tags(self) -> str

Write the tag of the letter gap of a word.

Returns:

The tag with no curly brackets, or no tags when the letter gap and the word gap are both 0. libass adds the room of the tag at the letter width, so the tag holds the room at the full width of the font.

RubySettings.space_tags

def space_tags(self) -> str

Write the tag of the word gap of a space.

Returns:

The tag with no curly brackets, or no tags when the letter gap and the word gap are both 0. A space gets the tag also when the word gap alone is 0, so that it does not keep the letter gap of the word in front of it.

RubyEffect

class RubyEffect
    def __init__(
            self, settings: RubySettings,
            keyword_picker: KeywordPicker = DEFAULT_KEYWORD_PICKER) -> None

Builds the ASS script and the emoji layers of heavy white capitals with a thick black outline and keywords in color, which pop in, with an emoji above a caption with a keyword.

Args:

  • settings: The look and the timing of the effect.
  • keyword_picker: Names the keywords of each caption. A caption with a keyword has an emoji. With no value, the keyword of a caption is its longest word when that word has seven letters or more.

RubyEffect.build_ass_text

def build_ass_text(self, words: Sequence[Word], video: VideoInfo) -> str

Build the ASS script of the effect for the words of one video.

Each line of each caption has an outline event, when the outline reaches past the stroke, and a text event. The events start with the first word of their caption. They end when the next caption starts, and at the latest the hold time after its last word and at the end of the video.

Args:

  • words: The words of the video in time order, each with its times.
  • video: The frame size and the duration of the video.

Returns:

The text of the ASS script. It has no event when there are no words.

Raises:

  • ValueError: When the side margins leave no room for the caption in the width of the video, or when the keyword picker gives a place that is not a word of its caption.

RubyEffect.build_layers

def build_layers(
        self, words: Sequence[Word], video: VideoInfo,
        emoji_path: Path) -> RubyLayers

Build the ASS script and the emoji layers for one video.

The script is the script of build_ass_text. Each caption with a keyword has one emoji layer with the times of the caption.

Args:

  • words: The words of the video in time order, each with its times.
  • video: The frame size and the duration of the video.
  • emoji_path: The emoji image, such as an animated GIF or a PNG with a see-through background. The effect does not read the image. ffmpeg reads it when it draws the layers.

Returns:

The script and the emoji layers.

Raises:

  • TypeError: When the emoji path is not a Path.
  • FileNotFoundError: When the emoji image is not a file.
  • ValueError: When the side margins leave no room for the caption in the width of the video, or when the keyword picker gives a place that is not a word of its caption.