from __future__ import annotations from copy import deepcopy from dataclasses import dataclass, field from typing import Any @dataclass(frozen=True) class CreativeStyle: key: str label: str description: str platform: str template: str scene_duration: float transition_sequence: tuple[str, ...] scene_effect_sequence: tuple[str, ...] render_defaults: dict[str, Any] = field(default_factory=dict) metadata: dict[str, Any] = field(default_factory=dict) def metadata_payload(self) -> dict[str, Any]: return { "key": self.key, "label": self.label, "description": self.description, "platform": self.platform, "template": self.template, "scene_duration": self.scene_duration, "transition_sequence": list(self.transition_sequence), "scene_effect_sequence": list(self.scene_effect_sequence), "render_defaults": deepcopy(self.render_defaults), "metadata": deepcopy(self.metadata), } SCENE_EFFECTS: dict[str, dict[str, str]] = { "none": {"label": "None", "filter": ""}, "sharp_pop": { "label": "Sharp Pop", "filter": "eq=contrast=1.08:saturation=1.20:brightness=0.01,unsharp=5:5:0.8:3:3:0.4", }, "clean_beauty": { "label": "Clean Beauty", "filter": "hqdn3d=1.5:1.5:6:6,eq=saturation=1.08:contrast=1.03", }, "warm_glow": { "label": "Warm Glow", "filter": "eq=contrast=1.04:saturation=1.18:gamma_r=1.04:gamma_b=0.96,gblur=sigma=0.25", }, "cinematic": { "label": "Cinematic", "filter": "eq=contrast=1.14:saturation=0.95:brightness=-0.015,vignette=PI/6", }, "dreamy": { "label": "Dreamy", "filter": "gblur=sigma=0.6,eq=contrast=1.04:saturation=1.18:brightness=0.02", }, "flash_pop": { "label": "Flash Pop", "filter": "eq=contrast=1.16:saturation=1.25:brightness=0.035", }, "grain": { "label": "Fine Grain", "filter": "noise=alls=8:allf=t+u,eq=contrast=1.07:saturation=1.02", }, "motion_blur": { "label": "Motion Blur", "filter": "tmix=frames=3:weights='1 2 1',eq=contrast=1.05:saturation=1.08", }, "noir": { "label": "Noir", "filter": "hue=s=0,eq=contrast=1.18:brightness=-0.02", }, "glitch": { "label": "Glitch", "filter": "rgbashift=rh=4:bh=-4,eq=contrast=1.12:saturation=1.18", }, "rgb_split": { "label": "RGB Split", "filter": "rgbashift=rh=3:gv=1:bh=-3", }, "vhs": { "label": "VHS", "filter": "noise=alls=18:allf=t+u,eq=saturation=0.82:contrast=1.08", }, "crt": { "label": "CRT", "filter": "vignette=PI/4,noise=alls=10:allf=t+u,eq=contrast=1.15:saturation=0.9", }, "bloom": { "label": "Bloom", "filter": "gblur=sigma=0.35,eq=brightness=0.025:saturation=1.14", }, "glow": { "label": "Glow", "filter": "gblur=sigma=0.45,eq=contrast=1.05:brightness=0.03", }, "chromatic_aberration": { "label": "Chromatic Aberration", "filter": "rgbashift=rh=2:rv=1:bh=-2:bv=-1", }, "neon": { "label": "Neon", "filter": "eq=contrast=1.2:saturation=1.55:brightness=0.02", }, "cyberpunk": { "label": "Cyberpunk", "filter": "eq=contrast=1.18:saturation=1.45:gamma_r=1.08:gamma_b=1.18", }, "comic": { "label": "Comic", "filter": "edgedetect=low=0.08:high=0.25,eq=contrast=1.2:saturation=1.35", }, "cartoon": { "label": "Cartoon", "filter": "edgedetect=low=0.05:high=0.2,eq=saturation=1.45:contrast=1.15", }, "anime": { "label": "Anime", "filter": "eq=saturation=1.35:contrast=1.12:brightness=0.02,unsharp=5:5:0.6", }, "sketch": { "label": "Sketch", "filter": "edgedetect=low=0.03:high=0.18,hue=s=0", }, "oil_painting": { "label": "Oil Painting", "filter": "gblur=sigma=0.7,eq=saturation=1.25:contrast=1.1", }, "pixel_art": { "label": "Pixel Art", "filter": "scale=iw/8:ih/8,scale=iw*8:ih*8:flags=neighbor", }, } CREATIVE_STYLES: dict[str, CreativeStyle] = { "viral_shorts": CreativeStyle( key="viral_shorts", label="Viral Shorts", description="Fast vertical pacing, punchy captions, bright contrast, and whip-style movement.", platform="tiktok", template="tiktok_zoom", scene_duration=2.4, transition_sequence=("whip", "flash", "zoom", "glitch"), scene_effect_sequence=("sharp_pop", "flash_pop", "clean_beauty"), render_defaults={ "subtitle_format": "ass", "auto_subtitles": True, "audio_normalize": True, "music_volume": 0.24, "music_fade_in": 0.25, "music_fade_out": 0.8, "music_ducking": True, "normalize": True, }, metadata={"energy": "high", "best_for": "hooks, offers, memes, short promos"}, ), "product_demo": CreativeStyle( key="product_demo", label="Product Demo", description="Clean cuts, readable captions, and polished color for launches and tutorials.", platform="instagram_reels", template="modern_minimal", scene_duration=3.2, transition_sequence=("slide", "wipe_left", "push", "dissolve"), scene_effect_sequence=("clean_beauty", "sharp_pop"), render_defaults={ "subtitle_format": "ass", "auto_subtitles": True, "audio_normalize": True, "music_volume": 0.18, "music_fade_in": 0.3, "music_fade_out": 0.7, "music_ducking": True, "normalize": True, }, metadata={"energy": "medium", "best_for": "software demos, ecommerce, tutorials"}, ), "story_vlog": CreativeStyle( key="story_vlog", label="Story Vlog", description="Warm color, softer movement, and natural pacing for personality-led edits.", platform="instagram_reels", template="tiktok_classic", scene_duration=3.8, transition_sequence=("fade", "smooth_right", "dissolve"), scene_effect_sequence=("warm_glow", "dreamy", "clean_beauty"), render_defaults={ "subtitle_format": "ass", "auto_subtitles": True, "audio_normalize": True, "music_volume": 0.22, "music_fade_in": 0.5, "music_fade_out": 1.0, "music_ducking": True, "normalize": True, }, metadata={"energy": "medium", "best_for": "founder updates, day-in-life edits, testimonials"}, ), "podcast_clip": CreativeStyle( key="podcast_clip", label="Podcast Clip", description="Square-safe framing, calmer captions, and narration-first audio treatment.", platform="instagram_feed_square", template="podcast_style", scene_duration=5.0, transition_sequence=("fade", "dissolve"), scene_effect_sequence=("clean_beauty", "sharp_pop"), render_defaults={ "subtitle_format": "ass", "auto_subtitles": True, "audio_normalize": True, "music_volume": 0.12, "music_fade_in": 0.6, "music_fade_out": 1.2, "music_ducking": True, "normalize": True, }, metadata={"energy": "low", "best_for": "interviews, audiograms, education"}, ), "cinematic_story": CreativeStyle( key="cinematic_story", label="Cinematic Story", description="Deeper contrast, film grain, and slower transitions for mini-documentary edits.", platform="youtube_shorts", template="modern_minimal", scene_duration=4.2, transition_sequence=("dissolve", "fadeblack", "smooth_left"), scene_effect_sequence=("cinematic", "grain"), render_defaults={ "subtitle_format": "ass", "auto_subtitles": True, "audio_normalize": True, "music_volume": 0.26, "music_fade_in": 0.8, "music_fade_out": 1.4, "music_ducking": True, "normalize": True, }, metadata={"energy": "low", "best_for": "brand films, travel, documentary shorts"}, ), "news_explainer": CreativeStyle( key="news_explainer", label="News Explainer", description="Readable lower-third style captions with stable landscape or vertical exports.", platform="youtube_1080p", template="news_style", scene_duration=4.0, transition_sequence=("wipe_left", "slide", "fade"), scene_effect_sequence=("sharp_pop", "clean_beauty"), render_defaults={ "subtitle_format": "ass", "auto_subtitles": False, "audio_normalize": True, "music_volume": 0.1, "music_fade_in": 0.5, "music_fade_out": 1.0, "music_ducking": True, "normalize": True, }, metadata={"energy": "medium", "best_for": "explainers, news, thought leadership"}, ), } def apply_creative_style(payload: dict[str, Any]) -> dict[str, Any]: style_key = payload.get("creative_style") or payload.get("metadata", {}).get("creative_style") if not style_key: return payload style = get_creative_style(str(style_key)) output = deepcopy(payload) output["creative_style"] = style.key _set_default(output, "platform", style.platform) _set_default(output, "template", style.template) for key, value in style.render_defaults.items(): _set_default(output, key, deepcopy(value)) metadata = deepcopy(style.metadata) metadata.update(output.get("metadata", {})) metadata["creative_style"] = style.key metadata["creative_style_label"] = style.label output["metadata"] = metadata scenes = output.get("scenes") if isinstance(scenes, list): output["scenes"] = [_style_scene(scene, style, index) for index, scene in enumerate(scenes)] return output def get_creative_style(key: str | None) -> CreativeStyle: if not key: return CREATIVE_STYLES["viral_shorts"] return CREATIVE_STYLES.get(key, CREATIVE_STYLES["viral_shorts"]) def list_creative_styles() -> list[str]: return list(CREATIVE_STYLES.keys()) def creative_style_metadata() -> dict[str, dict[str, Any]]: return {key: style.metadata_payload() for key, style in CREATIVE_STYLES.items()} def list_scene_effects() -> list[str]: return list(SCENE_EFFECTS.keys()) def scene_effect_metadata() -> dict[str, dict[str, str]]: return {key: {"label": value["label"]} for key, value in SCENE_EFFECTS.items()} def scene_effect_filter(key: str | None) -> str: if not key: return "" return SCENE_EFFECTS.get(key, SCENE_EFFECTS["none"])["filter"] def _set_default(payload: dict[str, Any], key: str, value: Any) -> None: if key not in payload or payload[key] in (None, ""): payload[key] = value def _style_scene(scene: Any, style: CreativeStyle, index: int) -> Any: if not isinstance(scene, dict): return scene styled = deepcopy(scene) transition = styled.get("transition") if transition in (None, "", "fade"): styled["transition"] = style.transition_sequence[index % len(style.transition_sequence)] if styled.get("effect") in (None, ""): styled["effect"] = style.scene_effect_sequence[index % len(style.scene_effect_sequence)] _set_default(styled, "background", "blur") _set_default(styled, "layout", "fill") return styled