guanghulab/video-ai-system/tools/sidechars_gen.py
bingshuo fe449f4f73
Some checks failed
自动更新代码和重启 / update-and-restart (push) Has been cancelled
CI检查 + 自动部署 / check (push) Has been cancelled
CI检查 + 自动部署 / deploy (push) Has been cancelled
ICE-GL-ZY001 · CHAR-006中年男子+CHAR-007欧阳员外·8候选·对齐苏白风格 · D169
2026-07-06 15:31:32 +08:00

118 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""CHAR-006 + CHAR-007 配角批量生成 · 对齐苏白V3-R4风格"""
import os, sys, json, time, subprocess
from pathlib import Path
ROOT = Path('D:/WorkBuddy/guanghulab/video-ai-system')
env = {}
for line in open(ROOT/".env"):
line = line.strip()
if not line or line.startswith("#"): continue
if "=" in line:
k, v = line.split("=", 1)
env[k.strip()] = v.strip()
AK = env["JIMENG_API_KEY"]
URL = env["JIMENG_BASE_URL"]
MODEL = "doubao-seedream-4-0-250828"
CHARS = {
"CHAR-006": {
"name": "中年男子·送土特产",
"prompt": """中国古代修仙世界普通中年男子,单人全身立绘,纯白背景。
40岁左右亚洲男性普通面孔略带谄媚笑容小眼睛微眯讨好神情骨相清晰但面相圆滑市侩。
身着朴素灰色长袍,布料普通缺乏灵气纹饰,腰间系旧布带无配饰。
双手捧一个粗布包袱/布袋,袋子略鼓装有土特产。
姿态微躬身略弯腰,一副讨好看人脸色的模样,仙侠世界观里的普通凡人送礼者。
真人向3D写实渲染光影自然不良人硬核写实风格。
与CHAR-003苏白V3-R4同一风格体系画面有电影级质感。""",
"neg": """现代服装西装T恤短发染发现代发型。
年轻面孔20岁以下少年偶像英俊帅气小生精致美男奶油小生。
华丽服饰,丝绸锦衣,富贵打扮,金线刺绣,玉佩,官服,执事服,宗门装饰。
表情凶狠,阴险,愤怒,悲伤,哭泣,严肃,冷漠,高傲。
迪士尼皮克斯日系动漫Q版卡通赛璐璐塑料感页游风。
水印,模糊,畸形的肢体。
苏白脸,诸葛风脸,王执事脸。""",
"variants": [
"正面微躬身,捧布包袱讨好看人,小眼睛眯笑圆滑市侩,灰色素袍,不良人写实",
"半侧身弯腰捧布袋,普通中年男子谄媚表情,朴素长袍旧布带,电影级质感",
"微躬身正面,脸上堆笑讨好神情,粗布袍布包袱,修仙世界凡人送礼者",
"侧面微躬身,双手捧布袋略鼓,谄媚而不猥琐,素灰袍凡人,硬核写实"
]
},
"CHAR-007": {
"name": "欧阳员外·闪切",
"prompt": """中国古代修仙世界富家员外,单人全身立绘,纯白背景。
50岁左右亚洲男性华贵暗紫色锦缎长袍金丝绣边精致纹样腰间系镶金玉佩腰带。
面容阴沉冷漠,嘴角下撇,眼神高高在上俯视鄙夷,富贵傲慢之气逼人。
身材微微发福,下巴略圆润,保养得当的脸上没有修炼痕迹——不是修仙者而是有钱有势的俗世权贵。
一手抚腰间玉佩,姿态居高临下,有压迫感。
真人向3D写实渲染光影清冷有重量不良人硬核写实风格。
与CHAR-003苏白V3-R4同一风格体系。""",
"neg": """现代服装,西装,现代服饰,现代发型,短发。
年轻20岁以下少年英俊小生笑容慈祥和善友好善良。
朴素服饰,粗布衣,破旧衣服,乞丐,贫穷感。
卡通渲染赛璐璐塑料感页游风日系动漫Q版。
水印,模糊不清,畸形肢体。
过于苍老70岁以上白发苍苍驼背佝偻。
苏白脸,诸葛风脸,王执事脸。
肌肉发达,壮汉。""",
"variants": [
"正面直立,一手抚腰间玉佩,面容阴沉高傲,暗紫锦缎长袍金丝绣边,富贵傲慢员外",
"半侧身俯视姿态,眼神高高在上,华贵紫袍金绣精致,中年富态权势感,硬核写实",
"正面微仰角,双手叠放身前玉佩腰带,脸上写满鄙夷不屑,锦缎华丽面料质感可见",
"半侧身冷淡表情,嘴角下撇,暗紫长袍金丝纹样,腰间玉佩,修仙世界权贵员外"
]
}
}
SEEDS = [100, 200, 300, 400]
def gen(prompt, neg, seed):
body = json.dumps({"model": MODEL, "prompt": prompt, "negative_prompt": neg, "size": "1440x2560", "n": 1, "seed": seed})
r = subprocess.run(["curl", "-s", "-m", "120", "--noproxy", "*", "-X", "POST", f"{URL}/images/generations",
"-H", f"Authorization: Bearer {AK}", "-H", "Content-Type: application/json", "-d", body],
capture_output=True, text=True, timeout=130)
try:
return json.loads(r.stdout)["data"][0].get("url")
except:
print(f" API err: {r.stdout[:200]}")
return None
def dl(url, dst):
Path(dst).parent.mkdir(parents=True, exist_ok=True)
subprocess.run(["curl", "-s", "-m", "120", "-L", "--noproxy", "*", "-o", dst, url], capture_output=True, timeout=130)
return os.path.exists(dst) and os.path.getsize(dst) > 1024
ts = time.strftime("%Y%m%d-%H%M%S")
all_meta = {}
for char_id, cfg in CHARS.items():
print(f"\n{'='*40}\n{char_id} · {cfg['name']}\n{'='*40}")
OUT = ROOT / f"assets/candidates/D169-VA-05-001/{char_id}"
OUT.mkdir(parents=True, exist_ok=True)
results = []
for i, seed in enumerate(SEEDS):
var = cfg["variants"][i]
full = f"{cfg['prompt']} {var}"
print(f" [{i+1}/4] seed={seed}", flush=True)
url = gen(full, cfg["neg"], seed)
if not url:
results.append({"c": i+1, "ok": False, "err": "api"})
continue
dst = OUT / f"{char_id}-V1-candidate-{i+1:02d}-1440x2560.png"
if not dl(url, str(dst)):
results.append({"c": i+1, "ok": False, "err": "dl"})
continue
results.append({"c": i+1, "ok": True, "raw": str(dst), "seed": seed})
print(f" -> {dst.name}")
time.sleep(3)
ok = sum(1 for r in results if r["ok"])
print(f" {char_id} 完成: {ok}/4")
all_meta[char_id] = {"name": cfg["name"], "ok": ok, "results": results}
json.dump({"spec": f"VA-05-001-{char_id}-V1", "ts": ts, **all_meta[char_id], "model": MODEL, "engine": "Seedream"},
open(OUT/"generation-meta.json","w",encoding="utf-8"), ensure_ascii=False, indent=2)
for char_id, m in all_meta.items():
print(f" {char_id} · {m['name']}: {m['ok']}/4")