@@ -7,6 +7,7 @@ class AssetType(str, Enum):
77 image = "image"
88 audio = "audio"
99 text = "text"
10+ caption = "caption"
1011
1112
1213class Fit (str , Enum ):
@@ -62,6 +63,40 @@ class HorizontalAlignment(str, Enum):
6263 right = "right"
6364
6465
66+ class CaptionBorderStyle (int , Enum ):
67+ """Border style properties for caption assets."""
68+
69+ no_border = 1
70+ opaque_box = 3
71+ outline = 4
72+
73+
74+ class CaptionAlignment (int , Enum ):
75+ """Caption alignment properties for caption assets."""
76+
77+ bottom_left = 1
78+ bottom_center = 2
79+ bottom_right = 3
80+ middle_left = 9
81+ middle_center = 10
82+ middle_right = 11
83+ top_left = 5
84+ top_center = 6
85+ top_right = 7
86+
87+
88+ class CaptionAnimation (str , Enum ):
89+ """Caption animation properties for caption assets."""
90+
91+ float_in_bottom = "float_in_bottom"
92+ box_highlight = "box_highlight"
93+ color_highlight = "color_highlight"
94+ reveal = "reveal"
95+ karioke = "karioke"
96+ impact = "impact"
97+ supersize = "supersize"
98+
99+
65100class VerticalAlignment (str , Enum ):
66101 """Vertical text alignment options."""
67102
@@ -378,7 +413,138 @@ def to_json(self):
378413 return data
379414
380415
381- AnyAsset = Union [VideoAsset , ImageAsset , AudioAsset , TextAsset ]
416+ class FontStyling :
417+ """Font styling properties for caption assets."""
418+
419+ def __init__ (
420+ self ,
421+ name : str = "Clear Sans" ,
422+ size : int = 30 ,
423+ bold : bool = False ,
424+ italic : bool = False ,
425+ underline : bool = False ,
426+ strikeout : bool = False ,
427+ scale_x : float = 1.0 ,
428+ scale_y : float = 1.0 ,
429+ spacing : float = 0.0 ,
430+ angle : float = 0.0 ,
431+ ):
432+ self .name = name
433+ self .size = size
434+ self .bold = bold
435+ self .italic = italic
436+ self .underline = underline
437+ self .strikeout = strikeout
438+ self .scale_x = scale_x
439+ self .scale_y = scale_y
440+ self .spacing = spacing
441+ self .angle = angle
442+
443+ def to_json (self ):
444+ return {
445+ "font_name" : self .name ,
446+ "font_size" : self .size ,
447+ "bold" : self .bold ,
448+ "italic" : self .italic ,
449+ "underline" : self .underline ,
450+ "strikeout" : self .strikeout ,
451+ "scale_x" : self .scale_x ,
452+ "scale_y" : self .scale_y ,
453+ "spacing" : self .spacing ,
454+ "angle" : self .angle ,
455+ }
456+
457+
458+ class BorderAndShadow :
459+ """Border and shadow properties for caption assets."""
460+
461+ def __init__ (
462+ self ,
463+ style : CaptionBorderStyle = CaptionBorderStyle .no_border ,
464+ outline : int = 1 ,
465+ outline_color : str = "&H00000000" ,
466+ shadow : int = 0 ,
467+ ):
468+ self .style = style
469+ self .outline = outline
470+ self .outline_color = outline_color
471+ self .shadow = shadow
472+
473+ def to_json (self ):
474+ return {
475+ "style" : self .style .value ,
476+ "outline" : self .outline ,
477+ "outline_color" : self .outline_color ,
478+ "shadow" : self .shadow ,
479+ }
480+
481+
482+ class Positioning :
483+ """Positioning properties for caption assets."""
484+
485+ def __init__ (
486+ self ,
487+ alignment : CaptionAlignment = CaptionAlignment .bottom_center ,
488+ margin_l : int = 30 ,
489+ margin_r : int = 30 ,
490+ margin_v : int = 30 ,
491+ ):
492+ self .alignment = alignment
493+ self .margin_l = margin_l
494+ self .margin_r = margin_r
495+ self .margin_v = margin_v
496+
497+ def to_json (self ):
498+ return {
499+ "alignment" : self .alignment .value ,
500+ "margin_l" : self .margin_l ,
501+ "margin_r" : self .margin_r ,
502+ "margin_v" : self .margin_v ,
503+ }
504+
505+
506+ class CaptionAsset (BaseAsset ):
507+ """The CaptionAsset is used to create captions from text strings with full styling and ass support."""
508+
509+ type = AssetType .caption
510+
511+ def __init__ (
512+ self ,
513+ src : str = "auto" ,
514+ font : Optional [FontStyling ] = None ,
515+ primary_color : str = "&H00FFFFFF" ,
516+ secondary_color : str = "&H000000FF" ,
517+ back_color : str = "&H00000000" ,
518+ border : Optional [BorderAndShadow ] = None ,
519+ position : Optional [Positioning ] = None ,
520+ animation : Optional [CaptionAnimation ] = None ,
521+ ):
522+ self .src = src
523+ self .font = font if font is not None else FontStyling ()
524+ self .primary_color = primary_color
525+ self .secondary_color = secondary_color
526+ self .back_color = back_color
527+ self .border = border if border is not None else BorderAndShadow ()
528+ self .position = position if position is not None else Positioning ()
529+ self .animation = animation
530+
531+ def to_json (self ):
532+ data = {
533+ "type" : self .type ,
534+ "src" : self .src ,
535+ "font" : self .font .to_json (),
536+ "primary_color" : self .primary_color ,
537+ "secondary_color" : self .secondary_color ,
538+ "back_color" : self .back_color ,
539+ "border" : self .border .to_json (),
540+ "position" : self .position .to_json (),
541+ }
542+ if self .animation :
543+ data ["animation" ] = self .animation .value
544+ return data
545+
546+
547+ AnyAsset = Union [VideoAsset , ImageAsset , AudioAsset , TextAsset , CaptionAsset ]
382548
383549
384550class Clip :
0 commit comments