auto-save 2026-05-14 13:21 (~3)

This commit is contained in:
2026-05-14 13:21:46 +08:00
parent 22f8885b97
commit 4e4e5395bc
3 changed files with 101 additions and 27 deletions

View File

@@ -194,39 +194,107 @@ const PRODUCT_FUSION_DESCRIPTION_PRESETS = [
"备用30舒适微表情佩戴稳定后透明骨架人眼神变柔和、嘴角轻扬肩颈线条放松镜头从产品细节回到脸部保持广告级质感。",
]
const CHARACTER_PROMPT_PROFILES: Record<string, { name: string; subject: string; scenes: string; usage: string; enjoyment: string }> = {
const FUSION_STAGE_PLANS = [
{
refs: "正面 + 半身近景",
product: "产品先在桌面、床头或手边出现,人物尚未佩戴,负责建立角色和场景",
result: "角色成立、场景成立、观众看到 SKG 产品即将被使用",
},
{
refs: "正面 + 左45度 + 产品正面/侧面",
product: "手把 SKG 从桌面或包中拿起带入画面,产品沿手部运动靠近后颈",
result: "产品进入画面自然,不悬浮,尺寸开始和人物肩颈建立关系",
},
{
refs: "侧面 + 背部特写 + 产品侧面/背面",
product: "SKG 准确落到脖子、后颈、颈肩交界处,双手扶两端微调贴合",
result: "重点解决佩戴位置、产品尺寸、透视和后颈贴合真实性",
},
{
refs: "半身近景 + 侧面",
product: "产品已经稳定佩戴,人物轻按控制区或保持佩戴状态",
result: "表现闭眼、肩部下沉、呼吸放慢、舒适享受,但不做医疗疗效承诺",
},
{
refs: "正面 + 左45度/右45度",
product: "人物在生活场景中继续佩戴 SKG产品位置稳定不漂移不变形",
result: "展示真实使用中的生活方式,人物、场景和产品统一",
},
{
refs: "半身近景 + 背部特写 + 产品主视角",
product: "收尾停在肩颈和产品清楚可辨的位置,手不遮挡产品关键轮廓",
result: "形成广告记忆点:角色舒适、产品清楚、画面干净高级",
},
]
const CHARACTER_PROMPT_PROFILES: Record<string, { name: string; subject: string; stageScenes: string[]; usage: string; enjoyment: string }> = {
"character-01": {
name: "运动阳光男",
subject: "清爽运动阳光男透明骨架人,身形挺拔、年轻有活力,整体气质健康明亮",
scenes: "晨练后卧室、阳台休息区、明亮健身房休息长椅或运动后居家放松场景",
stageScenes: [
"晨练后的明亮卧室阳光从窗边进入SKG 放在床头或运动包旁",
"健身房休息长椅旁,人物从运动包中拿起 SKG",
"阳台休息区侧面近景,阳光照到后颈和白色骨架",
"运动后客厅或卧室半身近景,背景清爽明亮",
"窗边拉伸区或瑜伽垫旁,人物轻松活动肩颈",
"干净白色广告背景或明亮卧室收尾特写",
],
usage: "运动后双手拿起 SKG准确戴到后颈和颈肩交界处轻按侧边控制区并微调贴合",
enjoyment: "从运动后的颈肩紧绷变成轻松舒展,闭眼深呼吸、肩部下沉、露出阳光放松微笑",
},
"character-02": {
name: "都市型男",
subject: "都市通勤型男透明骨架人,穿搭利落,高层公寓和商务感更强",
scenes: "高层公寓客厅、办公桌、商务休息区、夜晚城市窗边或会议间隙",
stageScenes: [
"高层公寓客厅或落地窗前,桌面上摆着 SKG",
"办公桌前或商务休息区,人物从桌面拿起 SKG",
"办公椅侧面近景,后颈和颈肩区域清楚可见",
"夜晚城市窗边半身近景,灯光克制高级",
"会议间隙的安静休息区,人物靠回椅背继续佩戴",
"高层公寓半身收尾,产品在后颈位置清楚可辨",
],
usage: "久坐办公后从桌面拿起 SKG戴到后颈手指轻按按键让产品稳定贴合颈肩",
enjoyment: "从低头疲惫、揉脖子变为靠回椅背放松,眼神平静、嘴角微扬,呈现高效恢复感",
},
"character-03": {
name: "优雅白领女",
subject: "优雅白领女透明骨架人,姿态端正、干净精致,商业广告感更高级",
scenes: "办公室午休区、极简卧室、化妆镜前、柔和落地窗旁或精致公寓客厅",
stageScenes: [
"精致公寓客厅或柔和落地窗旁SKG 放在小桌上",
"办公室午休区或化妆镜前,人物优雅拿起 SKG",
"镜前或窗边侧面近景,后颈线条和白色骨架清楚",
"极简卧室半身近景,柔和光线突出放松表情",
"办公室休息区继续佩戴,动作克制自然",
"高级广告式半身收尾,产品轮廓和人物微笑都清楚",
],
usage: "工作间隙优雅拿起 SKG轻放到后颈双手细致调整两端贴合动作慢而自然",
enjoyment: "从肩颈紧绷转为安静舒缓,闭眼微笑、呼吸放慢,呈现精致、自洽、舒服的状态",
},
"character-04": {
name: "运动辣妹",
subject: "运动辣妹透明骨架人,线条利落、活力强,适合健身后和生活方式广告",
scenes: "健身房更衣区、瑜伽垫旁、阳光客厅、运动后休息区或浴室镜前",
stageScenes: [
"健身房更衣区或瑜伽垫旁SKG 放在水杯和毛巾旁",
"运动后休息区,人物从健身包或桌面拿起 SKG",
"浴室镜前或瑜伽垫旁侧面近景,后颈和肩线清楚",
"阳光客厅半身近景,人物闭眼放松",
"运动后休息区继续佩戴,轻轻侧头伸展",
"健身生活方式广告收尾,产品贴合后颈且轮廓清晰",
],
usage: "训练后拿起 SKG 戴到后颈,侧头伸展时保持产品稳定贴合,手部不遮挡产品轮廓",
enjoyment: "从训练后的酸胀紧绷变为轻松舒展,闭眼享受、肩颈打开,表情自信舒服",
},
"character-05": {
name: "绅士大叔",
subject: "成熟绅士大叔透明骨架人,气质稳重高级,适合书房、客厅和商务休息场景",
scenes: "木质书房、皮质休闲椅、安静客厅、窗边阅读角或商务酒店房间",
stageScenes: [
"木质书房或皮质休闲椅旁SKG 放在书桌边",
"窗边阅读角,人物从桌边稳稳拿起 SKG",
"书房侧后方近景,后颈、颈椎和背部特写参考清楚",
"安静客厅半身近景,灯光温暖克制",
"商务酒店房间或书房里继续佩戴阅读休息",
"成熟高级的半身收尾,产品清楚、人物从容微笑",
],
usage: "阅读或工作后从桌边拿起 SKG稳稳戴到后颈轻扶两端调整到颈肩正确位置",
enjoyment: "从沉稳疲惫变为从容舒适,缓慢闭眼、肩部放松、轻轻微笑,表达成熟克制的享受",
},
@@ -235,10 +303,15 @@ const CHARACTER_PROMPT_PROFILES: Record<string, { name: string; subject: string;
const fusionDescriptionForCharacter = (characterId: string, presetIndex: number) => {
const base = PRODUCT_FUSION_DESCRIPTION_PRESETS[presetIndex % PRODUCT_FUSION_DESCRIPTION_PRESETS.length]
const profile = CHARACTER_PROMPT_PROFILES[characterId] ?? CHARACTER_PROMPT_PROFILES[DEFAULT_CHARACTER_ID]
const stage = presetIndex % FUSION_SHOT_COUNT
const stagePlan = FUSION_STAGE_PLANS[stage]
const scene = profile.stageScenes[stage] || profile.stageScenes[0]
return [
base,
`角色设定:${profile.subject}`,
`场景倾向:${profile.scenes}`,
`自主图像编排:本镜头主要参考角色图【${stagePlan.refs}】,场景生成【${scene}`,
`产品调度:${stagePlan.product}`,
`镜头目标:${stagePlan.result}`,
`产品使用:${profile.usage};产品只能在脖子、后颈、颈肩交界处使用,尺寸必须符合真实颈部按摩仪比例。`,
`享受状态:${profile.enjoyment};不要医疗治疗承诺,不要恐怖解剖感。`,
].join("\n")
@@ -264,7 +337,7 @@ const createFusionShots = (): ProductFusionShot[] =>
person_image: null,
product_region: null,
scene_image: null,
action_text: PRODUCT_FUSION_DESCRIPTION_PRESETS[i % PRODUCT_FUSION_DESCRIPTION_PRESETS.length],
action_text: fusionDescriptionForCharacter(DEFAULT_CHARACTER_ID, i),
duration: 5,
image_model: "gpt-image-2",
video_model: "seedance",
@@ -544,7 +617,7 @@ export function FrameLightbox({ jobId, frames, generatedVideos = [], activeIndex
const start = (page * FUSION_SHOT_COUNT) % PRODUCT_FUSION_DESCRIPTION_PRESETS.length
const next = fusionShots.map((shot, i) => ({
...shot,
action_text: PRODUCT_FUSION_DESCRIPTION_PRESETS[(start + i) % PRODUCT_FUSION_DESCRIPTION_PRESETS.length] || shot.action_text,
action_text: fusionDescriptionForCharacter(selectedCharacterId, start + i),
}))
setFusionPresetPage(page)
setFusionShots(next)
@@ -554,10 +627,12 @@ export function FrameLightbox({ jobId, frames, generatedVideos = [], activeIndex
const selectFusionCharacter = (characterId: string) => {
const character = characterLibrary.find((item) => item.id === characterId)
const next = fusionShots.map((shot) => ({
const start = (fusionPresetPage * FUSION_SHOT_COUNT) % PRODUCT_FUSION_DESCRIPTION_PRESETS.length
const next = fusionShots.map((shot, i) => ({
...shot,
character_id: characterId,
character_name: character?.name || shot.character_name || DEFAULT_CHARACTER_NAME,
action_text: fusionDescriptionForCharacter(characterId, start + i),
subject_image: null,
subject_images: [],
}))
@@ -1274,7 +1349,7 @@ export function FrameLightbox({ jobId, frames, generatedVideos = [], activeIndex
void persistFusionShots(next)
}}
placeholder="写清场景、产品如何佩戴到脖子/后颈,以及人物舒适享受状态。"
className="h-[92px] w-full resize-none rounded-md border border-white/10 bg-black/35 px-2 py-1.5 text-[10px] leading-relaxed text-white/75 outline-none placeholder:text-white/25 focus:border-amber-300/45"
className="h-[148px] w-full resize-none rounded-md border border-white/10 bg-black/35 px-2 py-1.5 text-[10px] leading-relaxed text-white/75 outline-none placeholder:text-white/25 focus:border-amber-300/45"
/>
</label>