Skip to content

Commit 465704e

Browse files
committed
Add cheap video style preset prompts based on regular expression replacements from old
1 parent 06d96a8 commit 465704e

1 file changed

Lines changed: 157 additions & 0 deletions

File tree

__init__.py

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,67 @@ def unfrakturpad(text: str) -> str:
298298
text_without_joiners = remove_joiners(text)
299299
return from_bold_fraktur(text_without_joiners)
300300

301+
302+
def to_video_prompt(text: str, is_system: bool = False) -> str:
303+
"""
304+
Transform image-based prompt presets into video-based ones by replacing
305+
static constraints with motion-focused directives.
306+
"""
307+
# 1. Replacement Map for standard patterns (ordered by specificity)
308+
replacements = [
309+
# Complex Multi-phrase constraints
310+
(r"(?i)(?:Keep|Maintain|Ensure)\s+subject\s+position\s+and\s+their\s+pose\s+the\s+same\s+as\s+the\s+reference", "Maintain character consistency with natural lifelike motion"),
311+
(r"(?i)(?:Make\s+sure|Ensure)\s+the\s+subject\s+is\s+in\s+the\s+same\s+position", "Ensure the subject moves naturally within the environment"),
312+
(r"(?i)keeping\s+the\s+composition\s+and\s+structure\s+of\s+the\s+image\s+same\s+as\s+reference", "maintaining character consistency and cinematic flow"),
313+
(r"(?i)not\s+changing\s+the\s+positioning\s+of\s+subjects\s+in\s+image", "enabling dynamic character movement and large actions"),
314+
(r"(?i)strictly\s+maintaining\s+their\s+original\s+appearance", "preserving visual identity during dynamic motion"),
315+
316+
# Simple Constraints -> Motion
317+
(r"(?i)Keep\s+pose", "Fluid movement and dynamic posing"),
318+
(r"(?i)Keep\s+angle", "Cinematic camera pans and motion"),
319+
(r"(?i)Keep\s+viewing\s+direction", "Dynamic gaze and perspective shifts"),
320+
(r"(?i)Keep\s+eyes", "Expressive eye movement and blinking"),
321+
(r"(?i)Keep\s+in\s+focus", "Maintain sharp cinematic focus"),
322+
(r"(?i)Keep\s+body\s+color", "Maintain consistent color during motion"),
323+
324+
# Verb/Directive Transformation
325+
(r"(?i)Modify\s+(?:any\s+subjects'\s+appearance|the\s+scene)\s+to\s+(?:match\s+|look\s+like\s+|show\s+)?(.*?)(?:\.(?:\s|$)|$)", r"Animate with motion and physics authentic to \1. "),
326+
(r"(?i)focuses\s+on\s+edits\s+to\s+look\s+like\s+", "focuses on generating high-quality motion authentic to "),
327+
(r"(?i)modify\s+the\s+style\s+to\s+look\s+like\s+", "animate with motion and physics authentic to "),
328+
(r"(?i)image\s+editing\s+descriptions", "cinematic motion and video generation descriptions"),
329+
(r"(?i)keeping\s+the\s+structure\s+of\s+the\s+image\s+intact", "maintaining cinematic continuity"),
330+
331+
# Nouns (Medium Swaps)
332+
(r"(?i)\bimage\b", "video"),
333+
(r"(?i)\bphotograph\b", "cinematic video"),
334+
(r"(?i)\bphotography\b", "cinematography"),
335+
(r"(?i)\bphoto\b", "video"),
336+
(r"(?i)\bstill\b", "video clip"),
337+
(r"(?i)\bscreenshot\b", "video clip"),
338+
(r"(?i)\bframe\b", "motion clip"),
339+
(r"(?i)\bcel\b", "animation frame"),
340+
(r"(?i)\bdrawing\b", "animation"),
341+
(r"(?i)\bpainting\b", "animated sequence"),
342+
(r"(?i)\billustration\b", "animated sequence"),
343+
(r"(?i)\bartwork\b", "animated sequence"),
344+
]
345+
346+
347+
result = text
348+
for pattern, replacement in replacements:
349+
result = re.sub(pattern, replacement, result)
350+
351+
# Cleanup extra whitespace and broken punctuation
352+
result = re.sub(r"\s+", " ", result)
353+
result = re.sub(r"\.\s*\.", ".", result)
354+
result = result.strip()
355+
356+
if is_system:
357+
prefix = "Analyze cinematic information and dynamic potential. Describe action as if already in motion, focusing on large motions and style-appropriate physics. "
358+
result = prefix + result
359+
360+
return result
361+
301362
def _hex_to_rgb(hex_str: str, default=(255, 255, 255)):
302363
hex_str = hex_str.lstrip('#')
303364
try:
@@ -1167,6 +1228,99 @@ def execute(cls, preset) -> io.NodeOutput:
11671228
return io.NodeOutput(bonus_prompt)
11681229

11691230

1231+
class SystemMessageVideoPresets(io.ComfyNode):
1232+
@classmethod
1233+
def get_presets(cls):
1234+
return SystemMessagePresets.get_presets()
1235+
1236+
@classmethod
1237+
def define_schema(cls):
1238+
presets = cls.get_presets()
1239+
return io.Schema(
1240+
node_id="SystemMessageVideoPresets",
1241+
category="advanced/text",
1242+
display_name="System Message Video Presets",
1243+
inputs=[
1244+
io.Combo.Input(
1245+
"preset",
1246+
options=sorted(list(presets.keys())),
1247+
default="F2_SYSTEM_MESSAGE" if "F2_SYSTEM_MESSAGE" in presets else sorted(list(presets.keys()))[0],
1248+
),
1249+
],
1250+
outputs=[
1251+
io.String.Output(display_name="system_prompt"),
1252+
],
1253+
)
1254+
1255+
@classmethod
1256+
def execute(cls, preset) -> io.NodeOutput:
1257+
presets_dict = cls.get_presets()
1258+
system_prompt = presets_dict.get(preset, "")
1259+
return io.NodeOutput(to_video_prompt(system_prompt, is_system=True))
1260+
1261+
1262+
class InstructPromptVideoPresets(io.ComfyNode):
1263+
@classmethod
1264+
def get_presets(cls):
1265+
return InstructPromptPresets.get_presets()
1266+
1267+
@classmethod
1268+
def define_schema(cls):
1269+
presets = cls.get_presets()
1270+
return io.Schema(
1271+
node_id="InstructPromptVideoPresets",
1272+
category="advanced/text",
1273+
display_name="Instruct Prompt Video Presets",
1274+
inputs=[
1275+
io.Combo.Input(
1276+
"preset",
1277+
options=sorted(list(presets.keys())),
1278+
default=sorted(list(presets.keys()))[0] if presets else "",
1279+
),
1280+
],
1281+
outputs=[
1282+
io.String.Output(display_name="instruct_prompt"),
1283+
],
1284+
)
1285+
1286+
@classmethod
1287+
def execute(cls, preset) -> io.NodeOutput:
1288+
presets_dict = cls.get_presets()
1289+
instruct_prompt = presets_dict.get(preset, "")
1290+
return io.NodeOutput(to_video_prompt(instruct_prompt))
1291+
1292+
1293+
class BonusPromptVideoPresets(io.ComfyNode):
1294+
@classmethod
1295+
def get_presets(cls):
1296+
return BonusPromptPresets.get_presets()
1297+
1298+
@classmethod
1299+
def define_schema(cls):
1300+
presets = cls.get_presets()
1301+
return io.Schema(
1302+
node_id="BonusPromptVideoPresets",
1303+
category="advanced/text",
1304+
display_name="Bonus Prompt Video Presets",
1305+
inputs=[
1306+
io.Combo.Input(
1307+
"preset",
1308+
options=sorted(list(presets.keys())),
1309+
default=sorted(list(presets.keys()))[0] if presets else "",
1310+
),
1311+
],
1312+
outputs=[
1313+
io.String.Output(display_name="bonus_prompt"),
1314+
],
1315+
)
1316+
1317+
@classmethod
1318+
def execute(cls, preset) -> io.NodeOutput:
1319+
presets_dict = cls.get_presets()
1320+
bonus_prompt = presets_dict.get(preset, "")
1321+
return io.NodeOutput(to_video_prompt(bonus_prompt))
1322+
1323+
11701324
class EditTargetPresets(io.ComfyNode):
11711325
@classmethod
11721326
def get_presets(cls):
@@ -3598,8 +3752,11 @@ async def get_node_list(self) -> list[type[io.ComfyNode]]:
35983752
ImageBlendByMask,
35993753
SU_InjectNoiseToLatent,
36003754
SystemMessagePresets,
3755+
SystemMessageVideoPresets,
36013756
InstructPromptPresets,
3757+
InstructPromptVideoPresets,
36023758
BonusPromptPresets,
3759+
BonusPromptVideoPresets,
36033760
EditTargetPresets,
36043761
EditOpPresets,
36053762
CameraShotPresets,

0 commit comments

Comments
 (0)