captionbob docs

Version 1.0.0
Contents ↓

Python: captionbob.effects

captionbob.effects.apex

The apex effect: bold white capitals whose keyword grows when spoken.

Each caption shows its words in bold white capitals, with no end marks. A caption ends at each end mark, such as a comma. A short caption stays on one line, and a longer caption is cut into two lines, and the top line takes the larger half of the words. The keywords of the captions take the keyword colors red, yellow and green in turn. A keyword has the size of the other words until it is spoken, and then it grows to the keyword scale.

Each letter has a black outline and a soft dark halo around it. Each line of a caption has three events: the halo, the outline and the letters. The top line stands on the caption bottom, and the second line hangs from the line gap below it.

Each caption zooms in: it starts at the zoom scale of its size and grows to its full size in the zoom time, fast at the start and slow at the end. The captions take the tilts in turn, and a tilted caption turns around the middle of its lines as one piece.

A caption with a keyword has an emoji below it or above it, in the middle of the video. The captions with a keyword take the emoji places in turn. The emoji grows with its caption. ASS cannot draw an image, so build_layers gives the emoji layers for the ffmpeg overlay filter next to the script.

Source file: captionbob/effects/apex.py

Settings

The command line and the HTTP API call this effect the style apex. Its settings class is ApexSettings. 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 72 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 2.0 Width of the outline in pixels. 0 gives no outline.
bottom_position number 0.677 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 1.1 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 4.4 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 13 The most letters, with the spaces, of a caption that stays on one line, 1 or above.
keyword_colors list ["#DE1B2F", "#FAFF31", "#DE1B2F", "#4AFF41", "#4AFF41", "#DE1B2F", "#FAFF31"] The colors of the keywords, as "#RRGGBB". The keywords take them in turn.
keyword_scale number 1.1 The size of a keyword from the time at which it is spoken, as a part of the size of the other words, above 0.
outline_color string "#000000" The color of the outline and of the halo, as "#RRGGBB".
outline_spread number 5.0 How far the outline reaches past the stroke, in pixels.
outline_blur number 2.0 How far the edge of the outline fades out, in pixels.
outline_opacity number 0.9 The strength of the outline, from 0 to 1.
halo_spread number 9.0 How far the halo reaches past the outline, in pixels.
halo_blur number 7.0 How far the edge of the halo fades out, in pixels.
halo_opacity number 0.8 The strength of the halo, from 0 to 1.
tilts list [-2.0, 0.0, 3.0, -1.5, 0.0, 2.5, -3.5, -2.5, 2.0, -2.0, 0.0, 3.0, -3.0, 0.5, 3.0, -1.5, 0.0, 3.5, -3.0, 0.0, 5.0, -3.5, -1.0] The tilts of the captions in degrees clockwise, one or more. The captions take them in turn.
zoom_scale number 0.8 The size of a caption and of its emoji at the start of the caption, as a part of the full size, above 0.
zoom_seconds number 0.6 The time in which a caption grows to its full size. 0 shows it at its full size at once.
zoom_ease number 0.6 The ease of the zoom of the tag \t, above 0. 1 grows at one speed, and a value below 1 is fast at the start and slow at the end.
emoji_size number 116.0 The side of the emoji in pixels, above 0.
emoji_gap number 12.0 Room in pixels between the lines of a caption and its emoji.
emoji_places list ["below", "below", "above", "above", "above", "below", "below"] EMOJI_BELOW or EMOJI_ABOVE for each emoji, one or more. The captions with a keyword take them in turn.
hold_seconds number 0.2 The longest time that a caption stays after its last word ends. The caption goes earlier when the next caption starts.

ApexSettings

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

The look and the timing of the apex 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 settings of the effect and the hold time. The effect changes the defaults of some of them. The primary color is the color of the words that are not keywords. The stroke is the outline of the letters, which makes them heavier in the color of their word. The outline of the settings of the effect is the black outline past it. The bottom position is the bottom of the top line.

Args:

  • keyword_colors: The colors of the keywords, as "#RRGGBB". The keywords take them in turn.
  • keyword_scale: The size of a keyword from the time at which it is spoken, as a part of the size of the other words, above 0.
  • outline_color: The color of the outline and of the halo, as "#RRGGBB".
  • outline_spread: How far the outline reaches past the stroke, in pixels.
  • outline_blur: How far the edge of the outline fades out, in pixels.
  • outline_opacity: The strength of the outline, from 0 to 1.
  • halo_spread: How far the halo reaches past the outline, in pixels.
  • halo_blur: How far the edge of the halo fades out, in pixels.
  • halo_opacity: The strength of the halo, from 0 to 1.
  • tilts: The tilts of the captions in degrees clockwise, one or more. The captions take them in turn.
  • zoom_scale: The size of a caption and of its emoji at the start of the caption, as a part of the full size, above 0.
  • zoom_seconds: The time in which a caption grows to its full size. 0 shows it at its full size at once.
  • zoom_ease: The ease of the zoom of the tag \t, above 0. 1 grows at one speed, and a value below 1 is fast at the start and slow at the end.
  • emoji_size: The side of the emoji in pixels, above 0.
  • emoji_gap: Room in pixels between the lines of a caption and its emoji.
  • emoji_places: EMOJI_BELOW or EMOJI_ABOVE for each emoji, one or more. The captions with a keyword take them in turn.
  • 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, when a color is not in the form "#RRGGBB", when an emoji place is not known, or when the font name is empty or holds a comma.

ApexSettings.outline_width

def outline_width(self) -> float

Give the width of the border of the outline: the stroke and the outline spread, in pixels.

ApexSettings.halo_width

def halo_width(self) -> float

Give the width of the border of the halo: the stroke, the outline spread and the halo spread, in pixels.

zoom_tags

def zoom_tags(settings: ApexSettings, border_width: float) -> str

Write the tags of a text that zooms in with its border.

The text starts at the zoom scale of its size, with the letter width, and grows to its full size in the zoom time, with the zoom ease of the tag \t. libass does not scale a border with the text, so the border grows with it.

Args:

  • settings: The settings of the effect.
  • border_width: The width of the border at the full size, in pixels.

Returns:

The tags with no curly brackets. With no zoom time, or with the zoom scale 1, the text has its full size at once.

keyword_size_tags

def keyword_size_tags(
        font_size: int, keyword_scale: float, spoken_milliseconds: int) -> str

Write the tags of a keyword that grows when it is spoken.

Args:

  • font_size: The font size of the other words.
  • keyword_scale: The size of the keyword when it is spoken, as a part of the size of the other words.
  • spoken_milliseconds: The tag time at which the keyword is spoken, 0 for a keyword that is spoken from the start of the event.

Returns:

The tags with no curly brackets. The keyword has the font size of the other words until it is spoken. libass reads the time 0 in the tag \t as the whole length of the event, so a keyword that is spoken from the start has its grown size with no timed tag.

keyword_own_tags

def keyword_own_tags(tags: str) -> str

Give the tags of a keyword whose choice is its tags.

Args:

  • tags: The tags of the keyword, with no curly brackets.

Returns:

The same tags.

ApexLayers

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

ApexCaption

class ApexCaption(NamedTuple)

One caption of the apex effect.

Args:

  • caption: The caption with the times of its events and its words as spoken.
  • group: The words of the caption as the effect shows them.
  • lines: The lines of the caption from the top, with the words as the effect shows them.
  • keyword_colors: The color of each keyword, by its place in the words of the caption.
  • tilt: The tilt of the caption in degrees clockwise.
  • emoji_place: EMOJI_BELOW or EMOJI_ABOVE for a caption with a keyword, or None for a caption with no keyword.

ApexEffect

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

Builds the ASS script and the emoji layers of bold white capitals with a black outline and a dark halo, whose keyword is red, yellow or green and grows when it is spoken, that zoom in and tilt, with an emoji below or above.

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.

ApexEffect.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 a halo, an outline and a text event. The events of a caption start with its first word. 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.

ApexEffect.build_layers

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

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.