captionbob docs

Version 1.0.0
Contents ↓

Python: captionbob.effects

captionbob.effects.blitz

Blitz effect: heavy slanted capitals with one line in a strong color.

Each caption shows its words in heavy capitals that lean to the right, with no end marks, and with a wide black outline that fades out at its edge. A short caption stays on one line. A longer caption is cut into two lines, and the top line takes the larger half of the words. One line of each caption has a strong color and the other line is white. The line of the first keyword of the caption has the color, and a caption with no keyword gives the color to its top line. The captions take the line colors in turn.

The captions take their turns from an order of turns, which starts again when it ends. A caption that floats moves to and fro on the line from the top left to the bottom right, on a cosine curve around its place. A caption that floats down starts at the top left end of its way, and a caption that floats up starts at the bottom right end. A still caption stays at its place. Each caption appears at once and hides at once.

ASS moves a text only in a straight line at one speed. The time of a caption that floats is cut into events of about FLOAT_PIECE_CENTISECONDS, and each event is one straight move from one place of the curve to the next.

The letters are drawn on two layers. The bottom layer draws them in the stroke color, with an outline as wide as the spread of the letters and the stroke together, and it blurs the outline. The top layer draws them in the color of their line, with an outline of that color as wide as the spread. The spread makes the letters as heavy as the letters of the source video.

A caption with a keyword has an emoji above it, below it, or below it and to the right. The emoji captions of a video take the emoji places in turn. The emoji floats with its caption. The ffmpeg filters scale and overlay draw the emoji under the ASS script. The effect gives the place of the emoji as ffmpeg expressions on an emoji layer, and it reads no image. The float turns, the events of a caption that floats and the emoji layer that floats are in effect_common.py.

libass breaks a line that is too wide for the room between the side margins into more rows. An emoji below such a caption can then cover its last row.

The effect draws nothing itself. It builds the text of an ASS script and the emoji layers, and ffmpeg draws them on the video. The common part of the effects is in effect_common.py.

The defaults are the look of the source video of the effect, measured on its frames and scaled to a video of 1080x1920.

Source file: captionbob/effects/blitz.py

Settings

The command line and the HTTP API call this effect the style blitz. Its settings class is BlitzSettings. 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 108 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 "#000000" Color of the outline of the text, as "#RRGGBB".
stroke_width number 12.0 Width of the outline in pixels. 0 gives no outline.
bottom_position number 0.716 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.
capitals boolean true True to write the words in capitals.
letter_width number 0.86 The width of the letters as a part of the width that the font gives them, above 0.
slant number 0.15 How far the top of a letter is to the right of its bottom, as a part of the height of the letter. 0 gives upright letters.
letter_spread number 4.5 How far the letters spread past the shapes of the font, in pixels. Each letter has an outline of its own color this wide, which makes it heavier. 0 gives the letters of the font.
outline_blur number 5.0 How far the edge of the stroke fades out, in pixels. 0 gives a sharp edge.
line_letters integer 11 The most letters, with the spaces, of a caption that stays on one line, 1 or above.
line_colors list ["#DE1C32", "#4AFF41", "#F9FF31"] The colors that the captions give to one of their lines, in turn, each as "#RRGGBB".
turns list ["float down", "still", "still", "still", "float down", "float up", "still", "still", "still", "float up"] The turn of each caption in order, each FLOAT_DOWN_TURN, FLOAT_UP_TURN or STILL_TURN. The order starts again when it ends.
float_reach number 14.0 How far a caption that floats goes from its place to each side, to the right and down, in pixels. 0 keeps each caption still.
float_seconds number 1.4 The time of one swing of the float, there and back, above 0.
emoji_size number 192.0 The side of the emoji in pixels, above 0.
emoji_gap number -6.0 Room in pixels between the emoji and the rows of the caption. A gap below 0 lets the emoji reach into the rows.
emoji_shift number 196.0 How far the middle of an emoji below the caption and to the right is to the right of the middle of the caption, in pixels.
emoji_places list ["below", "below right", "above"] The places of the emojis, one or more of "above", "below" and "below right". The captions with a keyword take them in turn.
hold_seconds number 0.3 The longest time that a caption stays after its last word ends. The caption goes earlier when the next caption starts.

BlitzLayers

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

BlitzSettings

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

The look and the timing of the blitz effect.

The settings of CaptionSettings come first: the word counts, the font, the colors, the stroke, the bottom position and the side margin. The primary color is the color of the white lines. The stroke is the black outline past the spread of the letters. The bottom position is the bottom of the first row of a caption. These settings follow them.

Args:

  • capitals: True to write the words in capitals.
  • letter_width: The width of the letters as a part of the width that the font gives them, above 0.
  • slant: How far the top of a letter is to the right of its bottom, as a part of the height of the letter. 0 gives upright letters.
  • letter_spread: How far the letters spread past the shapes of the font, in pixels. Each letter has an outline of its own color this wide, which makes it heavier. 0 gives the letters of the font.
  • outline_blur: How far the edge of the stroke fades out, in pixels. 0 gives a sharp edge.
  • line_letters: The most letters, with the spaces, of a caption that stays on one line, 1 or above.
  • line_colors: The colors that the captions give to one of their lines, in turn, each as "#RRGGBB".
  • turns: The turn of each caption in order, each FLOAT_DOWN_TURN, FLOAT_UP_TURN or STILL_TURN. The order starts again when it ends.
  • float_reach: How far a caption that floats goes from its place to each side, to the right and down, in pixels. 0 keeps each caption still.
  • float_seconds: The time of one swing of the float, there and back, above 0.
  • emoji_size: The side of the emoji in pixels, above 0.
  • emoji_gap: Room in pixels between the emoji and the rows of the caption. A gap below 0 lets the emoji reach into the rows.
  • emoji_shift: How far the middle of an emoji below the caption and to the right is to the right of the middle of the caption, in pixels.
  • emoji_places: The places of the emojis, one or more of "above", "below" and "below right". 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 is not a whole number.
  • ValueError: When a value is outside its range, when a color is not in the form "#RRGGBB", when the font name is empty or holds a comma, or when the line colors, the turns or the emoji places are not a tuple of one known value or more.

BlitzEffect

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

Builds the ASS script and the emoji layers of the blitz effect.

Args:

  • settings: The look and the timing of the effect.
  • keyword_picker: Gives the places of the keywords of a caption. The line of the first keyword has the color, and a caption with a keyword has an emoji. The default picks the longest word of a caption when it has seven letters or more.

BlitzEffect.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 caption starts with its first word. It ends 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.

BlitzEffect.build_layers

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

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.