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.