分享按钮

提示词随机器

北漂劳动者 IP · 提示词随机器 v1.0

北漂劳动者 IP · 换装卡点短视频提示词随机器

竖屏 9:16 | 1080p | ≤10 秒 | 原生 BGM | 无字幕无水印 | 适配即梦 Seedance 2.0 reference_images_to_video

1. 每次开拍先填

男/女装池独立,各 32 套(每季 8 套);选「全部混抽」会出跨季节换装卡点效果,选具体季节则贴合当季发片。
写稳定不变的特征:年龄段、脸型、发型、肤色、不完美细节(胡茬 / 雀斑 / 毛孔 / 晒痕 / 笑纹)、体型。不完美细节是去 AI 感的关键;只给图不写文字,换装时脸最容易漂。切换性别会自动更新默认特征。
换模板会改变镜头数,已锁定的格子会随之重置——请先定模板,再逐格锁定微调。
给工厂客户出片选「工厂制造」,餐饮选「餐饮食品」,逐类出片更贴合行业调性;不确定就留「全部混抽」。场景库共 102 个,含大量室内场景。
提交 Seedance 时 duration_seconds 只能填整数,这里的小数用于控制节奏分配与后期裁切。
遇到满意的一条,把种子存下来,下次填回来即可复现同一套分镜。

2. 怎么用

① 放好 3–5 张同一人参考图(正脸免冠 + 3/4 侧脸 + 半身全身)
       ② 选性别、填特征、点随机
       ③ 想留住的格子点「锁定」,再随机只重抽其余
       ④ 复制提示词 + 参数提交 Seedance
       ⑤ 出片后进剪映自动踩点、关自动字幕、导出 1080×1920
Seedance 提交参数
负面提示词(已并入完整提示词)

分镜表

点左侧「一键随机」开始。锁定的格子在重新随机时会保留。

完整提示词

铁律层(画幅 / 纪实风格 / 器材三件套 / Match Cut / 结尾点赞 / 无字幕水印)已锁死在提示词里,不参与随机——这是保证「每次不一样但还是同一个 IP、同一张脸」的关键。

<script>/* ================= 变量池 ================= */ /* 人物特征词库:性别联动,全部带「不完美真实细节」——去 AI 感的核心 */ const FACE_LIB={ "女":{age:["20 岁出头","25 岁上下","28 岁左右","30 岁上下","32 岁左右"], face:["鹅蛋脸","小方脸","圆脸","心形脸","颧骨略高的长脸","下颌线柔和"], hair:["黑色高马尾,鬓角有碎发","低马尾配空气刘海","齐肩碎短发","自然披发被风吹得有些乱","丸子头配碎发","黑发扎起,额前有绒毛碎发"], skin:["皮肤白皙,鼻翼微微泛红","小麦色肤色,晒痕明显","自然肤色带淡淡雀斑","肤色偏黄真实通透","两颊有日晒后的微红"], detail:["单眼皮,眼尾微微下垂","内双,睫毛自然不浓密","未经修剪的野生眉","鼻梁有晒红脱皮的痕迹","唇色偏淡,嘴角有自然干纹","浅浅的法令纹","耳后碎发翘出","皮肤能看到毛孔和细小绒毛","眼底有轻微倦色","手背有晒斑与小划痕"], body:["身形娇小但挺拔","中等身材,肩背舒展","纤细但有力","骨架偏小,动作利落"]}, "男":{age:["24 岁上下","28 岁左右","30 岁上下","35 岁左右","40 岁上下"], face:["方脸","长脸","国字脸","下颌线清晰","颧骨略高","脸形偏圆"], hair:["短寸黑发","两侧推短的碎盖短发","自然微卷短发","额前碎发略长","头发被风吹得有些乱","寸头带枕部扁平"], skin:["肤色偏黑粗糙","小麦色古铜肤色","晒痕明显,脖子和脸有色差","皮肤毛孔粗,有旧痘印","两颊泛红","额头有油光与自然反光"], detail:["下颌一层青色胡茬","眼角有笑纹","浓眉单眼皮","鼻梁有晒脱皮的痕迹","法令纹明显","鬓角有几根白发","手背粗糙有晒斑与小伤口","嘴唇干裂","鼻翼有黑头","眉骨投下的阴影明显"], body:["体格结实","偏瘦但挺拔","中等身材,肩膀宽厚","微壮,动作沉稳","手臂青筋明显"]} }; const FACE_DEFAULT={ "女":"25 岁上下,鹅蛋脸,黑色高马尾鬓角有碎发,皮肤白皙鼻翼微泛红,单眼皮,皮肤能看到毛孔和细小绒毛,身形娇小但挺拔", "男":"30 岁左右,方脸,短寸黑发,肤色偏黑粗糙有晒痕,下颌青色胡茬,眼角有笑纹,体格结实" }; function buildFaceAnchor(sex){ const L=FACE_LIB[sex]; const p=a=>a[Math.floor(Math.random()*a.length)]; const two=a=>{const c=a.slice();for(let i=c.length-1;i>0;i--){const j=Math.floor(Math.random()*(i+1));[c[i],c[j]]=[c[j],c[i]];}return c.slice(0,2);}; return [p(L.age),p(L.face),p(L.hair),p(L.skin),two(L.detail).join(","),p(L.body)].join(","); } /* 场景库:按行业分组,覆盖短视频运营常见客户行业;描述均为人物居中构图友好、避开文字直面的视角 */ const SCENE_GROUPS={ street:{name:"街头市井",list:[ "城中村窄巷,墙面贴满小广告","斑驳旧砖墙配枯黄爬山虎","工业区铁丝网围栏与厂房", "在建工地围挡,角落堆着安全帽","城乡结合部的黄土路","立交桥墩下的阴影里", "铁路涵洞,远处有列车虚影","地下车库出入口坡道","收摊后的早市街面","河堤水泥护坡", "老居民楼楼道口","出租屋天台,背后是密集楼房","建材市场门口","物流园装卸平台", "空旷停车场,远处塔吊剪影","拆迁废墟前扬起的灰尘","菜地埂边,下乡拍摄收工", "高铁高架桥墩下","街角早餐摊蒸笼白雾前","傍晚下班人流的工厂大门前", "公交总站候车亭","大桥人行道上,栏杆延伸成引导线"]}, factory:{name:"工厂制造",list:[ "现代化工厂车间,流水线在身后延伸","仓库货架通道,高耸货架形成纵深","厂区大门口,门禁与厂牌虚化", "数控机床旁,金属零件泛着冷光","装配工位前,工具墙整齐排列","质检台前,台灯下零件细节虚化", "原料堆场,编织袋与托盘码放","叉车通道,黄色警示线延伸向远方","厂房屋顶,通风管道与远处烟囱", "配电房外,管线成排平行延伸","无尘车间走廊,玻璃隔断映出反光","工业风设备间,管道阀门密布"]}, food:{name:"餐饮食品",list:[ "后厨灶台前,火光与蒸汽升腾","备菜间,不锈钢台面与满筐蔬菜","餐厅大堂,餐桌椅虚化成光斑", "咖啡店吧台后,咖啡机冒着蒸汽","面点间,案板与蒸笼热气","面包房烤箱前,暖光与烤盘", "烧烤摊炭火前,夜色里烟气缭绕","火锅店门口,红灯笼暖光,灯箱虚化","外卖打包区,保温袋与订单架", "火锅后厨冷柜旁,冷气白雾","夜市小吃车旁,暖黄串灯连成线","食材仓库,米面粮油货架"]}, edu:{name:"教育培训",list:[ "明亮教室,课桌椅整齐,黑板虚化","学校走廊,储物柜向纵深延伸","图书馆书架间,暖光台灯", "操场跑道,绿茵场与看台","琴房,钢琴与隔音墙","舞蹈教室,整面镜墙与把杆", "学校实验室,试管架与显微镜","美术教室,画架与颜料架","机房,电脑桌整齐排列", "培训机构前台,楼梯口暖光","教研办公室,白板内容虚化","宿舍楼下,晾衣杆与绿树"]}, medical:{name:"医疗健康",list:[ "医院走廊,导视灯箱虚化","药房取药窗口前","护士站,绿植与电脑屏幕", "康复训练室,器械整齐排列","诊所前台,叫号屏虚化","检验科外走廊,玻璃隔断反光", "中医馆,木质药柜抽屉成排","医院天台,晾晒的白大褂随风轻摆"]}, logistics:{name:"物流仓储",list:[ "快递分拣中心,传送带与包裹流动","快递驿站货架间,取件码墙虚化","仓库通道,托盘码到高处", "货车旁,车门半开","装卸月台,卷帘门与叉车","集装箱堆场,彩色箱体形成纵深", "快递三轮车旁,清晨街边微光","冷链仓库门口,呼出白气"]}, retail:{name:"美业零售",list:[ "理发店镜前,理发椅与吹风机","美甲台前,色卡与台灯","服装店衣架间,射灯打光", "超市货架通道,商品排列整齐","便利店收银台后,冷柜泛光","商场中庭,玻璃扶梯延伸", "化妆品柜台前,灯箱虚化","花店,花桶与包装纸","水果店,果堆色彩鲜艳", "烘焙店橱窗前,玻璃反光虚化"]}, office:{name:"写字楼办公",list:[ "写字楼工位区,显示器连成一片","会议室,长桌与白板内容虚化","茶水间,咖啡机与马克杯", "写字楼电梯口,大理石地面反光","落地窗前,城市天际线","公司前台,背景墙虚化", "写字楼天台,空调机组与城市剪影","地下车库,车道灯带延伸","办公楼梯间,安全出口灯微光", "打印区,纸张与绿植"]}, estate:{name:"房产建筑",list:[ "新房样板间,落地窗与软装","毛坯房,水泥墙面与窗洞透光","装修现场,梯子与涂料桶", "售楼处沙盘前,模型灯带发光","新楼盘小区步道,绿化与楼宇","建筑工地楼层边缘,安全网", "建材市场石材区,石板排列","阳台,绿植与晾晒衣物"]} }; /* 服装库:性别 × 四季,每人每季 8 套;全部为写实摄影师风格(马甲/工装/功能性外套/相机背带), 颜色不夸张(米/卡其/军绿/藏青/黑/灰/酒红/燕麦/驼色),符合专业摄影师的日常与工作着装 */ const OUTFIT={ F:{ spring:{n:"女·春",list:[ "米色长风衣内搭白T恤,直筒牛仔裤,斜挎相机背带","卡其色薄款多口袋摄影马甲配浅灰长袖衬衫,黑色长裤", "浅蓝牛仔外套内搭白T恤,黑色工装裤","军绿色工装衬衫束腰穿,黑色修身长裤,胸前挂相机背带", "灰蓝色针织开衫内搭白T恤,卡其色长裤","藏青色轻便风衣配灰T恤,黑色长裤,戴渔夫帽", "浅卡其色短夹克配条纹T恤,直筒牛仔裤","燕麦色薄呢短外套内搭黑色高领,深灰色长裤"]}, summer:{n:"女·夏",list:[ "白色速干短袖配卡其色多口袋摄影马甲,黑色速干长裤","藏青色短袖Polo衫,黑色速干工装裤,斜挎器材包", "浅灰色薄款防晒衣内搭白T恤,浅色长裤","白衬衫敞开穿,内搭灰色背心,卡其色短裤", "黑色速干T恤,军绿色工装半身裙,斜挎相机包","浅蓝棉麻衬衫卷起衣袖,黑色长裤", "灰色T恤配卡其色摄影马甲,手臂戴黑色防晒袖套","白色T恤配浅色直筒牛仔裤,戴帆布渔夫帽"]}, autumn:{n:"女·秋",list:[ "军绿色工装夹克内搭白T恤,黑色长裤","卡其色摄影马甲配灰色连帽卫衣,黑色长裤", "酒红色卫衣,直筒牛仔裤,斜挎相机背带","藏青色棒球夹克内搭白T恤,卡其色工装裤", "灰蓝色摇粒绒外套配黑色棉马甲,深色长裤","深灰色连帽卫衣,军绿色工装裤,胸前挂相机背带", "砖红色针织衫,卡其色长裤,戴针织帽","黑色教练夹克内搭灰T恤,黑色长裤"]}, winter:{n:"女·冬",list:[ "黑色长款羽绒服内搭灰毛衣,燕麦色针织围巾","奶白色短款羽绒服内搭黑色高领,深色长裤", "军绿色派克大衣带毛领,内搭黑色高领,戴针织冷帽","深灰色三合一冲锋衣配抓绒内胆,黑色长裤", "燕麦色羊毛大衣内搭黑色高领,斜挎相机背带","藏青色棉服内搭灰色卫衣,戴针织帽", "黑色短款羽绒马甲配酒红色卫衣,深色长裤","驼色羊羔绒外套内搭黑色高领,深灰色长裤"]} }, M:{ spring:{n:"男·春",list:[ "卡其色多口袋摄影马甲配灰色长袖衬衫,黑色长裤","军绿色工装夹克内搭白T恤,黑色长裤", "浅蓝牛仔外套内搭灰T恤,卡其色长裤","藏青色轻便风衣内搭白T恤,黑色长裤", "灰色针织开衫内搭白T恤,深灰色长裤","黑色教练夹克内搭灰T恤,军绿色工装裤", "米色薄夹克配条纹T恤,直筒牛仔裤","灰绿色工装衬衫,黑色长裤,胸前挂相机背带"]}, summer:{n:"男·夏",list:[ "灰色速干T恤配卡其色多口袋摄影马甲,黑色速干长裤","藏青色短袖Polo衫,黑色长裤,斜挎器材包", "白色速干短袖,军绿色工装短裤,戴棒球帽","浅灰色薄款防晒衣内搭白T恤,深色长裤", "黑色速干T恤,卡其色多口袋工装裤","浅蓝棉麻衬衫卷起衣袖,深灰色长裤", "军绿色T恤配黑色轻便摄影马甲,深色长裤","白色T恤配直筒牛仔裤,戴帆布渔夫帽"]}, autumn:{n:"男·秋",list:[ "军绿色工装夹克内搭灰T恤,黑色长裤","卡其色摄影马甲配灰色连帽卫衣,黑色长裤", "藏青色棒球夹克内搭白T恤,黑色长裤","黑色飞行员夹克内搭灰T恤,卡其色工装裤", "米白色摇粒绒外套配深灰色马甲,黑色长裤","酒红色卫衣,直筒牛仔裤,斜挎相机背带", "灰蓝色防风衣内搭黑T恤,卡其色长裤","深灰色教练夹克内搭白T恤,黑色长裤"]}, winter:{n:"男·冬",list:[ "黑色长款羽绒服内搭灰毛衣,深色针织围巾","军绿色派克大衣带毛领,内搭黑色高领", "藏青色棉服内搭灰色连帽卫衣,戴针织冷帽","深灰色三合一冲锋衣配抓绒内胆,黑色长裤", "黑色短款羽绒服,卡其色长裤,戴针织冷帽","驼色羊羔绒夹克内搭黑色高领,深色长裤", "黑色羽绒马甲配灰色卫衣,深色长裤","藏青色呢大衣内搭灰高领毛衣,黑色长裤"]} } }; OUTFIT.F.all=[].concat(OUTFIT.F.spring.list,OUTFIT.F.summer.list,OUTFIT.F.autumn.list,OUTFIT.F.winter.list); OUTFIT.M.all=[].concat(OUTFIT.M.spring.list,OUTFIT.M.summer.list,OUTFIT.M.autumn.list,OUTFIT.M.winter.list); const POOL = { outfitF:OUTFIT.F.all, outfitM:OUTFIT.M.all, gear:[ "肩扛金属三脚架、单肩背黑色重型器材包、胸前挂着单反","怀抱大型器材包,包里露出长焦镜头单反和三脚架,相机背带挂在脖子", "三脚架扛右肩、左手提黑色器材包,单反斜挎在身侧","单反相机挂脖、肩扛三脚架、背黑色双肩器材包", "单肩斜挎黑色灯架包、手提三脚架、相机挂在手腕上","肩扛三脚架、手拎器材箱,相机斜挎胸前", "胸前挂着微单、背上压着巨大的黑色器材包,三脚架横担在包顶","手持稳定器云台,肩上挎器材包,三脚架绑在包两侧", "用肩带把三脚架背在身后,双手拎着器材包,相机挂脖","推着器材拉杆箱,三脚架绑在箱侧,相机斜挎在身", "一手扶肩上的三脚架,一手拎器材包,嘴里咬着镜头盖","三脚架顶在肩上,手里转着一颗镜头,器材包放在脚边", "双肩大摄影包上绑着三脚架,腰挂快扣上挂着相机","单肩背器材包、手提三脚架,另一只手翻看手机里的样片"], scene:[].concat(SCENE_GROUPS.street.list,SCENE_GROUPS.factory.list,SCENE_GROUPS.food.list, SCENE_GROUPS.edu.list,SCENE_GROUPS.medical.list,SCENE_GROUPS.logistics.list, SCENE_GROUPS.retail.list,SCENE_GROUPS.office.list,SCENE_GROUPS.estate.list), move:[ "固定机位","缓慢推镜(dolly in)","缓慢拉镜,揭示器材的重量", "人物迎面走来、镜头匀速后退跟拍","侧向平行跟拍,背景掠过","手持轻微呼吸感晃动", "环绕 15° 微移","低角度微微上摇,从器材包摇到脸","前景遮挡后穿过","肩部高度跟随机位,背景高速虚化流动", "腰平视角跟随,贴近人物重心","从脚部缓摇到脸的升镜","稳定器环绕半圈并缓慢推近", "缓慢横摇,揭示整条街的环境","俯拍降镜,从高处降到平视","跟手部动作的小幅跟随移镜"], shot:[ "远景/平视,交代环境","全景/平视","中全景/平视","中景/平视","中景/低角度仰拍显挺拔", "中近景/平视","近景/微仰 5°","近景/平视","胸上景/平视","过肩中景/平视", "中近景/微俯 5°","全景/低角度仰拍","近景/侧脸 45° 视角","中景/荷兰角微斜 8°"], action:[ "边走边啃大白馒头","仰头灌一口矿泉水","用手背擦掉额头的汗","蹲在地上整理散开的器材", "拧开保温杯吹着热气","把器材包从左肩换到右肩,显出承重感","拍打身上的灰", "咬住口罩带子腾出双手","数手里一把零钱后咧嘴笑","低下头用取景器取景再抬眼", "用气吹清洁镜头","低头给相机换电池","单手转动镜头变焦环","摘下帽子扇风", "拉上外套拉链","把三脚架在肩上转了个方向","双手搓一搓取暖,呼出一口白气", "蹲下来系紧鞋带","单手拎起器材箱颠了颠重量","对着镜头展示手里的镜头,像在介绍老伙计", "甩了甩相机背带重新背上","卷起袖子看了一眼手表","咬开矿泉水瓶盖","把镜头盖抛起又接住"], light:[ "正午顶光带轻微硬阴影","黄金时刻侧逆光勾出轮廓","蓝调时刻的冷调环境光", "阴天柔散光,肤色通透","清晨冷蓝调,空气湿润通透","傍晚暖橙调,长阴影拉出纵深感", "逆光下扬尘可见光柱,丁达尔光效","单侧窗光 45° 侧打,室内柔光", "顶灯加面部补光,专业布光的干净感","灯箱霓虹的冷调轮廓光","暖色灯笼光加面部柔光", "厂房高窗斜射的光柱","手机屏幕冷光映在脸上","傍晚街头混合光,暖灯与冷天光交融", "半剪影逆光,人物边缘一圈轮廓光","模拟柔光箱的均匀无影光"], trans:[ "硬切卡点落在重音上","闪白一帧","匹配剪辑,手与器材停在同一画面位置", "甩镜过渡(whip pan)","前景物体遮挡擦除","器材包掠过镜头转场", "动作衔接转场,上一镜的动作下一镜接续","同色块对齐过渡","快速变焦推近转场", "两帧黑闪过渡","漏光光晕闪烁过渡","手掌呼脸遮挡转场"], hook:[ "对着镜头灿烂大笑,眼神直勾勾抓住观众","右手竖起大拇指怼近镜头", "把大白馒头举到镜头前","三脚架横扛在肩挡住半个画面","迎面走来并朝镜头挥手", "擦汗的瞬间抬眼看向镜头","从画面侧方大步走进中央","转身回头,背影转成正脸", "单手把器材包甩上肩的同时看向镜头","蹲着系鞋带时抬头看向镜头", "举着相机对镜头按下快门再笑","从三脚架后探身出来打招呼"], ending:[ "右手竖起大拇指加露齿大笑后定格","双手抱拳拱手作谢后定格", "举起馒头向镜头致意后定格","眨眼 wink 配一个大拇指后定格", "拍拍肩上的器材包挑眉一笑后定格","张开双臂展示整条街后定格", "单手把三脚架立在地上轻点一下后定格","对镜头比出 OK 手势后定格", "扛着器材背对镜头,回头一笑后定格","举起相机对镜头咔嚓一声后定格", "双手比耶再指一下镜头后定格","把帽子摘下按在胸前微微鞠躬后定格"], expr:[ "笑容明媚有感染力","露齿大笑","自信而充满活力的微笑","眼神坚定嘴角上扬", "质朴满足的咧嘴笑","带着一点疲惫却不服输的笑","挑眉一笑,干劲十足", "微微眯眼看向远处的光,像在测光","眼神发亮,像刚发现一个好画面","抿嘴浅笑,眼神温柔坚定", "仰头大笑,爽朗有感染力","嘴角上扬的浅笑,眼神笃定"], extra:[ "35mm 焦段环境人像感,人与环境有呼吸感","50mm 标准镜头视角,接近人眼自然透视", "85mm 人像焦段,面部立体,背景奶油般虚化","背景大光圈虚化,浅景深", "皮肤有真实毛孔与细纹,汗珠可见","高帧率捕捉生动的面部微表情", "构图保持人物绝对居中,留出抖音竖屏安全区","低饱和青橙调,电影感调色", "暖色调 HDR,高动态范围","逆光空气感与镜头光斑", "服装面料纹理清晰,工装与针织质感分明","金属器材有真实反光与使用磨损痕迹", "主体锐利,背景柔化过渡","甩镜瞬间的轻微动态模糊,其余帧保持清晰"], imperf:[ "衣领有汗渍,袖口磨白","鞋面沾着泥点与灰尘","头发被风吹乱了几缕","器材包边角磨破露出内衬", "帽檐压得有些变形","衣服上有明显的褶皱和起球","手指有倒刺,指甲缝带着灰","脸上有晒红脱皮的痕迹", "围巾起球","手套指尖磨破","三脚架腿上有磕碰划痕","相机背带被汗浸出深色一块", "裤脚蹭了灰,蹲坐的褶皱没拍平","外套拉链坏了半截,用绳子系着","镜片上有指纹和灰","额头一层薄汗的自然反光"] }; const BGM = { A:{n:"民谣叙事",instr:"木吉他 + 口琴 + 低声人声哼鸣",bpm:"92–100",curve:"平缓起 → 副歌推进,苦涩后的释然",d:[2.6,2.2,2.4,2.8]}, B:{n:"励志鼓点",instr:"军鼓 + 弦乐铺底 + 拍手",bpm:"108–118",curve:"情绪逐级加码,苦尽甘来的推进感",d:[1.8,2.0,2.0,2.0,2.2]}, C:{n:"国潮电子",instr:"古筝采样 + 侧链合成器贝斯 + 四踩",bpm:"124–128",curve:"全程高密度,鼓点极硬",d:[1.5,1.6,1.7,1.6,1.7,1.8]}, D:{n:"钢琴递进",instr:"独奏钢琴 → 全编制进入",bpm:"72–80",curve:"一慢三快,末镜爆发",d:[3.0,2.0,2.2,2.6]}, E:{n:"抖音热歌卡点",instr:"流行电子鼓组 + 明亮合成器 + 洗脑人声哼鸣 hook",bpm:"126–132",curve:"全程密集重音,钩子旋律循环上头",d:[1.6,1.9,2.0,2.1,2.4]}, F:{n:"治愈慢歌",instr:"钢琴 + 弦乐 + 气声人声哼鸣",bpm:"75–85",curve:"前静后动,末镜收暖",d:[2.8,2.2,2.2,2.8]}, G:{n:"热歌高潮切片",instr:"副歌 drop 型编曲:前奏蓄力 → 全编制爆发",bpm:"120–128",curve:"前两镜蓄力,drop 后三镜爆发",d:[2.2,2.0,1.6,1.8,2.4]}, H:{n:"无BGM·原声实况",instr:"(无配乐)",bpm:"—",curve:"—",d:[1.9,2.0,2.0,2.0,2.1],silent:true} }; const ROLE = i=> i===0?"Hook 亮相": i===2?"真实感落点":"换装推进"; const NEG = "字幕, 文字, 标题, 水印, logo, 台标, 二维码, UI界面, 人脸改变, 换脸, 不同的人物, 多人合影, 镜面或橱窗中出现多余人影, 手指畸形, 六指, 多余肢体, 器材消失, 三脚架变形, 低分辨率, 模糊, 卡通, 动漫, 3D渲染感, CG感, 游戏画面感, AI生成痕迹, 网红脸, 模板脸, 过度美颜, 磨皮, 美白滤镜, 皮肤过于光滑无毛孔, 影楼修图感, 过度锐化, 假笑, 眼神空洞, 动作僵硬无重量感, 服装过于崭新挺括, 棚拍布景感, 广告摆拍感, 慢动作, 黑边, 横屏, 画面静止, 招牌乱码文字"; const REAL = "画面必须像单反相机手持实拍:皮肤保留真实毛孔、细纹与自然油光变化,禁止磨皮美颜与网红脸;衣物有褶皱、起球、褪色与灰尘,头发有飞丝;器材有磕碰磨损与使用痕迹;环境是真实的生活与工作现场,有杂物与岁月痕迹,不是棚拍布景;光影方向统一、符合物理规律,阴影边缘真实;保留轻微数码噪点与胶片颗粒感;人物表情自然不做作,扛器材的动作有惯性和重量感,走路有重心起伏。"; const IRON = "主体居中,人物占画面高度 65%–75%。纪实摄影风格,高动态范围 HDR,色彩饱和而温暖,肤色自然真实不磨皮。电影感自然光照明,柔和浅景深,高帧率捕捉生动面部表情。人物全程肩扛或怀抱专业摄像器材三件套:金属三脚架、黑色重型器材包、单反/电影机。快节奏卡点换装剪辑(Match Cut),每镜更换一套服装但器材与人物保持不变,同一动作位置精准对齐切换。情绪基调:勤奋、乐观、坚韧、朴实的北漂劳动者,画面充满正能量与生活气息。整条视频从头到尾严格保持同一个人、同一张脸、同一身形。"; const COLORS = ["#d1682b","#b95a24","#a04f22","#8a5a3b","#6f6a5f","#2f6b4f"]; /* ================= 可复现随机 ================= */ function hash(s){let h=2166136261>>>0;for(let i=0;i>>0} function mulberry32(a){return function(){a|=0;a=a+0x6D2B79F5|0;let t=Math.imul(a^a>>>15,1|a);t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296}} let rnd=Math.random; const pick=a=>a[Math.floor(rnd()*a.length)]; function pickN(a,n){const c=a.slice();for(let i=c.length-1;i>0;i--){const j=Math.floor(rnd()*(i+1));[c[i],c[j]]=[c[j],c[i]]}return c.slice(0,Math.min(n,c.length))} const newSeed=()=>Math.random().toString(36).slice(2,8).toUpperCase(); /* ================= 状态 ================= */ const S={sex:"女",bgmKey:"A",sceneCat:"all",season:"all",shots:[]}; const outfitPool=()=>{const g=S.sex==="女"?"F":"M";return (S.season&&S.season!=="all")?OUTFIT[g][S.season].list:OUTFIT[g].all;}; const scenePool=()=> S.sceneCat==="all" ? POOL.scene : (SCENE_GROUPS[S.sceneCat]||SCENE_GROUPS.street).list; const WALK=["稳步朝镜头走来","把器材往上颠了颠","抬头看了眼天色继续走","呼出一口白气","避开地上的水洼继续赶"]; function buildShots(){ const key=S.bgmKey==="R"?pick(["A","B","C","D","E","F","G"]):S.bgmKey; const T=BGM[key]; S.bgmKey=key; const n=T.d.length, total=parseFloat(el("total").value); let d=T.d.slice(), sum=d.reduce((a,b)=>a+b,0); if(sum>total){ // 超目标则等比缩放,末镜吸收舍入误差,保证合计精确不超限 d=d.map(x=>+(x*total/sum).toFixed(2)); sum=d.reduce((a,b)=>a+b,0); d[n-1]=+(d[n-1]+(total-sum)).toFixed(2); } const prev=S.shots; const actIdx=n>=3?2:n-2; const SRC={outfit:()=>outfitPool(),scene:()=>scenePool(),gear:()=>POOL.gear, move:POOL.move,shot:POOL.shot,light:POOL.light,expr:POOL.expr, extra:POOL.extra,trans:POOL.trans,action:POOL.action,imperf:POOL.imperf}; /* 无重复分配:锁定槽位保留原值并从池中剔除,避免「换装卡点」里出现两套相同服装 */ function alloc(field){ const pool=(typeof SRC[field]==="function"?SRC[field]():SRC[field]); const locked=[]; for(let i=0;i!used.has(x)), n-locked.length); let j=0; const out=[]; for(let i=0;iV[f]=alloc(f)); V.trans[0]={value:"开场,无转场",locked:false}; V.action.forEach((v,i)=>{ // 非落点镜换成轻动作,降低手部畸形与穿模风险 if(v.locked) return; if(i===actIdx||(i===n-1&&n<3)) return; if(rnd()>0.35) v.value=pick(WALK); }); if(n>1&&rnd()<0.5&&!V.scene[n-1].locked) // 末镜回环复用首镜场景,形成闭环结构 V.scene[n-1]={value:V.scene[0].value,locked:false}; let t=0; S.shots=d.map((dur,i)=>{ const isAct=(i===actIdx)||(i===n-1&&n<3); const row={dur,start:+t.toFixed(2), role:i===0?"Hook 亮相":i===n-1?"收尾定格":isAct?"真实感落点":"换装推进"}; Object.keys(V).forEach(f=>row[f]=V[f][i]); t+=dur; return row; }); const hp0=prev[0]&&prev[0].hook&&prev[0].hook.locked?prev[0].hook.value:null; const hpN=prev[n-1]&&prev[n-1].hook&&prev[n-1].hook.locked?prev[n-1].hook.value:null; S.shots[0].hook ={value:hp0||pick(POOL.hook), locked:!!hp0}; S.shots[n-1].hook={value:hpN||pick(POOL.ending), locked:!!hpN}; } /* ================= 文案组装 ================= */ function shotText(r,i,n){ const parts=[`${r.shot.value},${r.move.value}:`,`${r.outfit.value},${r.gear.value},`, `${r.scene.value},${r.light.value}。`,`${r.hook?r.hook.value+",":r.action.value+","}${r.expr.value}。`, `${r.extra.value}。`,r.imperf?r.imperf.value+"。":""]; return parts.join(""); } function buildPrompt(){ const face=el("face").value.trim()||FACE_DEFAULT[S.sex]; const T=BGM[S.bgmKey], n=S.shots.length; let p=""; p+=`【规格】竖屏 9:16,1080p 高清,总时长 ${S.shots.reduce((a,b)=>a+b.dur,0).toFixed(1)} 秒,${T.silent?"仅真实环境音":"含器乐 BGM"},无字幕、无水印、无文字。nn`; p+=`【全局风格】${IRON}nn`; p+=`【真实感要求】${REAL}nn`; p+=`【人物锚】一位中国${S.sex}性,${face}。五官、发型与身形在所有镜头中严格保持一致,面部零漂移;不改变性别特征,不换人。nn`; p+=`【分镜 · 共 ${n} 镜,${T.silent?"硬切转场节奏均匀,保持纪实呼吸感":"切换点严格对齐音乐重音"}】n`; S.shots.forEach((r,i)=>{ const s=r.start.toFixed(1), e=(r.start+r.dur).toFixed(1); p+=`镜头 ${i+1}|${s}–${e}s|${r.trans.value} → ${shotText(r,i,n)}n`; }); p += T.silent ? `n【音频】无任何配乐。仅收录真实环境音:脚步声、远处模糊的街道市井人声、风声、器材金属轻碰声。无旁白、无人声演唱、无歌词、无配乐、无字幕。发布后将使用平台站内曲库配乐,请保持节奏干净。nn` : `n【音频】仅一条器乐 BGM:${T.instr},节奏 ${T.bpm} BPM,情绪曲线:${T.curve}。每一次镜头切换都必须落在鼓点/重音上,卡点干脆。人声仅作哼鸣衬底,绝无歌词。无旁白、无人声解说、无对白、无字幕。nn`; p+=`【负面提示】${NEG}`; el("out").value=p; } function buildTable(){ let m="| 镜号 | 时间 | 角色 | 景别/角度 | 运动 | 转场 | 服装 | 器材 | 场景 | 动作/表情 | 光线 | 质感 | 真实痕迹 |n|---|---|---|---|---|---|---|---|---|---|---|---|---|n"; S.shots.forEach((r,i)=>{ m+=`| ${i+1} | ${r.start.toFixed(1)}–${(r.start+r.dur).toFixed(1)}s | ${r.role} | ${r.shot.value} | ${r.move.value} | ${r.trans.value} | ${r.outfit.value} | ${r.gear.value} | ${r.scene.value} | ${r.hook?r.hook.value:r.action.value},${r.expr.value} | ${r.light.value} | ${r.extra.value} | ${r.imperf.value} |n`; }); return m; } function buildJson(){ const dur=Math.round(S.shots.reduce((a,b)=>a+b.dur,0)); const Tj=BGM[S.bgmKey]; const note=Tj&&Tj.silent ? "无BGM模板:generate_audio 保持 true 用于生成环境音;发布时用平台站内曲库选热歌高潮版。duration_seconds 仅接受 4–15 整数,小数时长出片后裁切" : "duration_seconds 仅接受 4–15 整数;小数时长需出片后裁切"; return JSON.stringify({mode:"reference_images_to_video",model:"seedance-2.0", reference_images:["/绝对路径/正脸.jpg","/绝对路径/侧脸3-4.jpg","/绝对路径/半身.jpg"], duration_seconds:Math.max(4,Math.min(15,dur||10)),resolution:"1080p",aspect_ratio:"9:16", generate_audio:true,note},null,2); } /* ================= 渲染 ================= */ const el=id=>document.getElementById(id); function render(){ const box=el("shots"); box.innerHTML=""; el("emptyHint").style.display="none"; const n=S.shots.length; const fields=[["shot","景别"],["move","运动"],["trans","转场"],["outfit","服装"],["gear","器材"], ["scene","场景"],["action","动作"],["expr","表情"],["light","光线"],["extra","质感"],["imperf","真实痕迹"]]; const tl=el("timeline"); tl.innerHTML=""; const total=S.shots.reduce((a,b)=>a+b.dur,0); S.shots.forEach((r,i)=>{ const seg=document.createElement("div"); seg.style.flex=r.dur; seg.style.background=COLORS[i%COLORS.length]; seg.textContent=`${i+1}·${r.dur.toFixed(1)}s`; tl.appendChild(seg); const c=document.createElement("div"); c.className="shot"; let rows=""; if(r.hook) rows+=rowHtml(i,"hook",i===0?"开场钩子":"收尾定格",r.hook,true); fields.forEach(([k,lab])=>{ if(!r[k])return; if(k==="action"&&r.hook)return; rows+=rowHtml(i,k,lab,r[k],false) }); c.innerHTML=`
镜头 ${i+1} ${r.start.toFixed(1)}–${(r.start+r.dur).toFixed(1)}s | ${r.dur.toFixed(1)}s ${r.role}
${rows}
${shotText(r,i,n)}
`; box.appendChild(c); }); const tb=el("totalBox"); const limit=parseFloat(el("total").value); const T0=BGM[S.bgmKey]; tb.className="total"+(total>limit+0.01?" warn":""); tb.innerHTML=`${total.toFixed(1)}s / 目标 ${limit}s | ${n} 镜 | BGM ${S.bgmKey} ${T0.n}`+(T0.silent?"":" · "+T0.bpm+"BPM"); el("bgmNote").textContent=T0.silent ? "无配乐成片。发布时在抖音/视频号站内曲库选「热歌高潮版」再配乐——真热歌才有音乐流量池,剪映自动踩点对齐。" : `${T0.instr} | ${T0.bpm} BPM | ${T0.curve}`; el("negBox").textContent=NEG; el("paramBox").textContent=buildJson(); buildPrompt(); } function rowHtml(i,k,lab,v,forceLock,role){ if(!v) return `
${lab||"角色"}${role}
`; return `
${lab}${v.value}
`; } /* ================= 事件 ================= */ function roll(autoSeed){ if(autoSeed){ el("seed").value=newSeed(); } rnd=mulberry32(hash(el("seed").value||newSeed())); const sel=el("bgm").value; S.bgmKey=sel; if(el("sceneCat")) S.sceneCat=el("sceneCat").value; if(el("season")) S.season=el("season").value; buildShots(); render(); } el("roll").onclick=()=>roll(true); el("applySeed").onclick=()=>roll(false); const FACE_PH={ "女":"例:25 岁上下,鹅蛋脸,黑色高马尾鬓角碎发,鼻翼微泛红,皮肤能看到毛孔", "男":"例:30 岁左右,方脸,短寸黑发,肤色偏黑粗糙有晒痕,下颌青色胡茬" }; let faceDirty=false; function syncSexFace(){ if(!faceDirty) el("face").value=FACE_DEFAULT[S.sex]; el("face").placeholder=FACE_PH[S.sex]; } el("segSex").querySelectorAll("button").forEach(b=>b.onclick=()=>{ el("segSex").querySelectorAll("button").forEach(x=>x.classList.remove("on")); b.classList.add("on"); S.sex=b.dataset.v; syncSexFace(); roll(false); }); el("faceRoll").onclick=()=>{ el("face").value=buildFaceAnchor(S.sex); faceDirty=true; if(S.shots.length) buildPrompt(); toast("已生成"+S.sex+"性真实感特征锚(含不完美细节)"); }; ["bgm","total","sceneCat","season"].forEach(id=>el(id).onchange=()=>roll(false)); el("face").oninput=()=>{ faceDirty=true; if(S.shots.length) buildPrompt(); }; el("shots").addEventListener("click",e=>{ const b=e.target.closest(".lockbtn"); if(!b) return; const r=S.shots[+b.dataset.i]; const v=r[b.dataset.k]; v.locked=!v.locked; render(); }); function copy(txt,msg){ if(navigator.clipboard&&window.isSecureContext){navigator.clipboard.writeText(txt).then(()=>toast(msg)).catch(()=>fb());} else fb(); function fb(){const t=document.createElement("textarea");t.value=txt;document.body.appendChild(t);t.select(); try{document.execCommand("copy");toast(msg)}catch(e){toast("复制失败,请手动选中")}document.body.removeChild(t);} } let tt; function toast(m){const t=el("toast");t.textContent=m;t.classList.add("show");clearTimeout(tt);tt=setTimeout(()=>t.classList.remove("show"),1800)} el("cpPrompt").onclick=()=>copy(el("out").value,"已复制完整提示词("+el("out").value.length+" 字)"); el("cpTable").onclick=()=>{if(S.shots.length)copy(buildTable(),"已复制分镜表 Markdown")}; el("cpJson").onclick=()=>copy(buildJson(),"已复制 Seedance JSON 参数"); /* 首屏预置一套,便于直接看到效果 */ S.sex="女"; syncSexFace(); el("seed").value=newSeed(); S.bgmKey="B"; el("bgm").value="B"; roll(false);