captionbob docs

Version 1.0.0
Contents ↓

Python: captionbob.effects

captionbob.effects.rally

The rally effect: narrow white capitals whose spoken word takes a color.

Each caption shows its words in heavy narrow capitals, white, with their end marks. A caption holds up to five words, and it ends at each end mark, such as a comma. A line holds up to three words, so the first three words are the top line and the words behind them are the second line. The line whose words are spoken is at its full size, and the other line is smaller. The word that is spoken takes the line color of the caption, and the captions take the line colors in turn. A dark border, a little blurred, lies around the letters.

The time of a caption is cut into one turn for each of its lines. The turn of a line starts with its first word and ends when the turn of the next line starts, or with the caption. Each turn has a shadow event, when the shadow can be seen, and a text event, each with all the lines of the caption. libass puts the lines one below the other, from the top of the top line, and each line takes the room of its size. The shadow event draws the letters in the shadow color, with a border that fades out. The text event draws the letters over it, with an outline in the color of the letters that makes them heavier. Each space of a line gets the word gap.

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 below the caption in the middle of the video, and it shows at its full size at once.

The caption groups that end at each end mark, the times of the captions, the spoken time of each word and its look in that time, the lines of a caption, the turns of its lines, the line colors and the check that the shadow is seen come from effect_common. The emoji layer is PopEmojiLayer of effect_common.

Source file: captionbob/effects/rally.py

Settings

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

Setting Type Default Description
most_words integer 5 The most words that one caption shows.
fewest_words integer 2 The fewest words that one caption shows, when its sentence is long enough for that.
font_name string "Ubuntu Condensed" Name of the font of the text.
font_size integer 98 Height of the font in pixels.
bold boolean false 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.25 Width of the outline in pixels. 0 gives no outline.
bottom_position number 0.68 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.83 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.
word_gap number 6.0 Room in pixels that is added to each space between two words, at the letter width. A value below 0 puts the words closer. 0 keeps the space of the font.
words_per_line integer 3 The most words of one line, 1 or above. Each line from the top holds this many words, and the last line holds the words that are left.
small_line_scale number 0.85 The size of a line whose words are not spoken, as a part of the size of the line that is spoken, above 0.
line_colors list ["#F8FF20", "#3DFF33", "#D9021D"] The colors of the word that is spoken, as "#RRGGBB". The captions take them in turn.
shadow_color string "#000000" The color of the shadow, as "#RRGGBB".
shadow_spread number 11.5 How far the shadow reaches past the outline, in pixels.
shadow_blur number 4.0 How far the edge of the shadow fades out, in pixels.
shadow_opacity number 1.0 The strength of the shadow, from 0 for no shadow to 1.
shadow_drop number -1.0 How far the shadow is below the letters, in pixels. A value below 0 puts the shadow above them.
emoji_size number 114.0 The side of the emoji in pixels, above 0.
emoji_gap number 12.0 Room in pixels between the bottom of the lines of a caption and the top of the emoji.
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.

RallyLayers

class RallyLayers(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.

RallyCaption

class RallyCaption(NamedTuple)

One caption of the rally effect.

Args:

  • caption: The caption with the times of its events and its words as spoken.
  • lines: The lines of the caption from the top, with the words in capitals.
  • keywords: The places of the keywords in the words of the caption.
  • line_color: The line color of the caption.

RallySettings

@dataclass(frozen=True)
class RallySettings(CaptionSettings)

The look and the timing of the rally effect.

The settings of CaptionSettings come first: the word counts, the font, the colors, the stroke, the bottom position and the side margin. Then come the letter width, the word gap, the words per line, the small line scale, the line colors, the settings of the shadow 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, which makes them heavier. The bottom position is the bottom of the top line at its full size.

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.
  • word_gap: Room in pixels that is added to each space between two words, at the letter width. A value below 0 puts the words closer. 0 keeps the space of the font.
  • words_per_line: The most words of one line, 1 or above. Each line from the top holds this many words, and the last line holds the words that are left.
  • small_line_scale: The size of a line whose words are not spoken, as a part of the size of the line that is spoken, above 0.
  • line_colors: The colors of the word that is spoken, as "#RRGGBB". The captions take them in turn.
  • shadow_color: The color of the shadow, as "#RRGGBB".
  • shadow_spread: How far the shadow reaches past the outline, in pixels.
  • shadow_blur: How far the edge of the shadow fades out, in pixels.
  • shadow_opacity: The strength of the shadow, from 0 for no shadow to 1.
  • shadow_drop: How far the shadow is below the letters, in pixels. A value below 0 puts the shadow above them.
  • emoji_size: The side of the emoji in pixels, above 0.
  • emoji_gap: Room in pixels between the bottom of the lines of a caption and the top of the emoji.
  • 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 words per line is not a whole number.
  • ValueError: When a value is outside its range, or when a color is not in the form "#RRGGBB".

RallySettings.has_shadow

def has_shadow(self) -> bool

True when the shadow has strength and reaches past the letters: it spreads, it is blurred or it is below or above them.

RallySettings.line_scales

def line_scales(self, line_count: int, spoken_line: int) -> list[float]

Give the size of each line of a caption in the turn of a line.

Args:

  • line_count: The number of lines of the caption.
  • spoken_line: The line whose words are spoken, 0 for the top line.

Returns:

WHOLE for the spoken line and the small line scale for each other line, from the top line.

RallyEffect

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

Builds the ASS script and the emoji layers of narrow white capitals with a dark border, whose spoken word takes the color of its caption and whose spoken line is larger, with an emoji below 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.

RallyEffect.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 turn of each caption has a shadow event, when the shadow can be seen, and a text event. The first turn starts with the first word of its caption. The last turn ends when the next caption starts, and at the latest the hold time after the last word of its caption 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.

RallyEffect.build_layers

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

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.