326 lines
30 KiB
Python
Executable File
326 lines
30 KiB
Python
Executable File
from __future__ import annotations
|
||
|
||
from pathlib import Path
|
||
|
||
from docx import Document
|
||
from docx.enum.text import WD_ALIGN_PARAGRAPH
|
||
from docx.shared import Inches, Pt
|
||
|
||
import build_woyanmo_docx as b
|
||
|
||
|
||
OUT = Path(r"D:\workspace\digital_me\artifacts\《我为你研墨》完整歌词脚本与20镜分镜提示词(每镜10秒).docx")
|
||
|
||
|
||
SHOTS = [
|
||
dict(n=1, section="Intro", title="不会写字的孤女", lyric="(研墨声)你杀了我祖父的那一年 / 我还不会写字",
|
||
beats=[("0–2秒", "黑场中先出现研墨声,烛火从暗处显出。"), ("2–6秒", "俯视缓推,幼年婉儿在掖庭矮桌前歪斜描红。"), ("6–10秒", "镜头停在握笔的小手与高墙长影,红簪成为唯一亮色。")],
|
||
subtitles="1.0–6.0秒「你杀了我祖父的那一年」;6.0–9.8秒「我还不会写字」",
|
||
prompt="开场黑场约1秒,只有细微研墨声。烛火渐亮,俯视机位从高耸暗红宫墙缓慢下推,揭示幼年上官婉儿穿暗蓝粗布囚衣、背对镜头伏在窄矮木桌前描红。她握笔生涩,纸上笔画歪斜;发髻一支朱砂红簪为唯一鲜明色。宫墙占画面七成以上,长影压住弱小人物。最后四秒镜头近乎静止,仅烛焰、衣袖和笔尖微动。",
|
||
transition="0.8秒叠化,歪斜墨迹溶入成年婉儿笔下端正诏书。"),
|
||
dict(n=2, section="Verse 1", title="替她写漂亮的诏书", lyric="如今我替你 把诏书写得漂亮",
|
||
beats=[("0–3秒", "成年婉儿伏案,镜头从诏书卷首缓慢推向执笔手。"), ("3–7秒", "笔锋稳定行进,字迹端整,武则天身影在后景虚化。"), ("7–10秒", "婉儿停笔半拍,烛光将她的脸切成明暗两半。")],
|
||
subtitles="1.0–9.5秒「如今我替你 把诏书写得漂亮」",
|
||
prompt="成年上官婉儿身着玄红唐代女官服,夜间宫室内伏案书写明黄诏书。镜头从诏书卷首极缓推向执笔右手,毛笔写出端整有力的墨字;画面后景仅保留晚年武则天模糊侧影与明黄衣色,不抢主体。右上烛光照亮婉儿半张脸,另一半隐入墨影。第七秒后停笔半拍,目光仍落在诏书上,情绪克制、专业、不可揣测。",
|
||
transition="笔尖悬停处硬切至下一镜的锋利落笔。"),
|
||
dict(n=3, section="Verse 1", title="每一笔都是锋芒", lyric="一笔一划 都是你要的锋芒",
|
||
beats=[("0–3秒", "微距笔尖悬于纸面,朱砂与墨色并置。"), ("3–7秒", "笔锋快速但稳定地压、行、提,形成一道锐利转折。"), ("7–10秒", "镜头沿笔画末端滑动,墨迹边缘缓慢渗入宣纸。")],
|
||
subtitles="1.0–9.5秒「一笔一划 都是你要的锋芒」",
|
||
prompt="微距特写毛笔、手指与宣纸,成年婉儿的手腕佩细银镯。笔尖先悬停,随后以清晰的压笔、行笔、提锋完成一道锐利而端正的墨色笔画,笔锋末端带少量朱砂红高光,象征权力锋芒。镜头沿新写成的笔画缓慢横移,展示墨色在纸纤维中细微晕开;手指结构稳定,笔杆与笔毫不变形。",
|
||
transition="墨迹晕染扩满画面,叠化成掖庭冷灰墙面。"),
|
||
dict(n=4, section="Verse 1", title="掖庭长大的罪臣之孙", lyric="掖庭里长大 罪臣的孙女",
|
||
beats=[("0–3秒", "远景展示门字形高墙与极小人物。"), ("3–7秒", "少女提灯穿过狭长廊道,步伐安静。"), ("7–10秒", "她停在门洞中央,灯火变弱,墙体继续压迫。")],
|
||
subtitles="1.0–5.0秒「掖庭里长大」;5.0–9.5秒「罪臣的孙女」",
|
||
prompt="高耸暗红宫墙围出狭窄门字形通道,冷灰空气中,少年上官婉儿穿素色旧衣,手提一盏小灯缓慢穿过。人物只占画面约8%,巨大墙体形成强烈压迫。镜头固定,仅做极轻缓推;她走至门洞中央停下,灯焰渐弱,烛泪沿灯烛下滑。无人出现,无夸张表演,以空间体量表现“罪臣孙女”的身份烙印。",
|
||
transition="灯焰焦外光斑溶成砚池中的暖金倒影。"),
|
||
dict(n=5, section="Verse 1", title="把恨磨成墨", lyric="我把恨 磨成了墨 / 一滴 不许它响",
|
||
beats=[("0–3秒", "俯拍砚台,墨锭缓慢画圆,水滴在上方凝结。"), ("3–6秒", "水滴无声落入墨池,扩散三圈涟漪。"), ("6–10秒", "墨气升起又散去,砚面恢复黑镜般平静。")],
|
||
subtitles="0.8–5.0秒「我把恨 磨成了墨」;5.0–9.8秒「一滴 不许它响」",
|
||
prompt="微距俯拍黑色砚台占画面九成,女子手持墨锭缓慢画圆研磨。一滴清水在画面上方凝结,第三秒无声落入墨池中央,扩散三圈细密涟漪;落墨瞬间只有极轻视觉震颤,不出现剧烈水花。水雾化成细长墨气升至画面三分之一,再缓缓散去。砚面映着虚化暖金烛斑,最后恢复黑镜般平静。",
|
||
transition="黑色墨面中央裂开一道竖痕,进入火宅与递笔的对照画面。"),
|
||
dict(n=6, section="Pre 1", title="恨与谢的分屏", lyric="该恨你 还是该谢你 / 你毁了我的家 又给了我笔",
|
||
beats=[("0–3秒", "左侧祖宅燃烧,右侧一支毛笔悬在少女面前。"), ("3–7秒", "少女左手握紧、右手接笔,中央墨痕向下滴落。"), ("7–10秒", "火焰爆裂与接笔动作同拍,画面轻震后定住。")],
|
||
subtitles="0.5–4.5秒「该恨你 还是该谢你」;4.5–9.8秒「你毁了我的家 又给了我笔」",
|
||
prompt="左右对称分屏构图。左屏为唐代上官府宅在夜色中燃烧,火焰舔过屋檐,少女剪影站在火前不动;右屏为宫室烛光下一支毛笔从画外递到少女面前,她迟疑后伸手接住。中央分隔线是一道竖直墨痕,第三秒开始向下滴墨。第七秒火焰轻微爆裂与指尖握住笔杆同步,双屏极轻震动后稳定。建议左右画面分别生成10秒,再后期合成。",
|
||
transition="中央墨痕向两侧晕开,覆盖火焰并化作宫城夜色。"),
|
||
dict(n=7, section="Chorus 1", title="为她研墨,也为自己活", lyric="我为你研墨 也为自己活 / 仇人的江山 我替她说",
|
||
beats=[("0–3秒", "砚面与研墨手势近景,婉儿倒影浮现。"), ("3–7秒", "镜头升起后拉,砚面转化为水墨宫城。"), ("7–10秒", "婉儿立于城楼俯瞰灯火,身影虽小却居于制高点。")],
|
||
subtitles="0.5–4.8秒「我为你研墨 也为自己活」;4.8–9.8秒「仇人的江山 我替她说」",
|
||
prompt="从俯拍砚面和研墨手势开始,黑色墨面映出成年婉儿克制的半脸倒影。镜头缓慢升起并后拉,砚池边缘自然转化为水墨大明宫城墙与宫阙,近景烛火连续变成万家灯火。后段婉儿背影立于最高城楼,玄红衣摆被风轻动,人物虽小却位于画面上三分之一制高点,俯瞰仇人的江山,表达她在权力中争取生存。",
|
||
transition="宫城灯火排列成棋盘格,俯视进入黑白棋局。"),
|
||
dict(n=8, section="Chorus 1", title="看不透的棋局", lyric="你看不透我 我也看不透我 / 这盘棋里 谁是谁的 因果",
|
||
beats=[("0–4秒", "墨镜中婉儿的脸一半清晰、一半被墨纹遮住。"), ("4–8秒", "画面叠化为棋盘,两双手分别落黑白子。"), ("8–10秒", "棋子落点泛起墨晕,两只手同时退出画面。")],
|
||
subtitles="0.5–4.5秒「你看不透我 我也看不透我」;4.5–9.8秒「这盘棋里 谁是谁的 因果」",
|
||
prompt="前四秒中近景:成年婉儿凝视砚中自己,现实半脸清晰,倒影半脸被流动墨纹遮住,目光冷静而困惑。随后以墨纹叠化成青玉棋盘俯拍,左侧婉儿纤白手戴银镯落白子,右侧年老帝王枯瘦手戴玉扳指落黑子。两枚棋子先后落盘,落点各泛一圈淡墨晕;最后两只手同时缓慢退出,只留下未完棋局。",
|
||
transition="棋盘墨晕旋转上升,变成掌心的墨色风旋。"),
|
||
dict(n=9, section="Chorus 1|间奏", title="掌上起风,婉儿落笔", lyric="(掌上起风 婉儿落笔)",
|
||
beats=[("0–3秒", "女子摊开手掌,掌心墨气聚拢。"), ("3–7秒", "墨气旋转三圈上升,另一只手在焦外蘸墨。"), ("7–10秒", "墨风散开,毛笔从上方落向宣纸,停在触纸一刻。")],
|
||
subtitles="1.0–9.0秒「(掌上起风 婉儿落笔)」;使用28pt淡灰括号体",
|
||
prompt="女子摊开的手掌占画面六成,掌心黑色墨气聚拢并形成缓慢旋转的风涡,连续旋转三圈后上升。另一只手在左侧焦外区域执笔蘸墨,右下烛光勾亮指尖边缘。第七秒墨风向两侧散开,画面上方一支毛笔缓慢落向宣纸;第十秒停在笔毫刚触纸的瞬间。手指自然稳定,无多余手指和肢体。",
|
||
transition="笔毫触纸硬切到帝王凝视婉儿书写的宫室。"),
|
||
dict(n=10, section="Verse 2", title="她只看字写得好不好", lyric="你不问我恨不恨 你只看我写得好不好",
|
||
beats=[("0–3秒", "婉儿书写近景,帝王在后景审视。"), ("3–7秒", "镜头横移至诏书,展示整齐字列与朱砂批记。"), ("7–10秒", "帝王手指轻点纸面,婉儿没有抬头。")],
|
||
subtitles="0.8–9.7秒「你不问我恨不恨 你只看我写得好不好」",
|
||
prompt="宫室夜景,中近景拍成年婉儿伏案书写,晚年武则天在后景虚化端坐,只露明黄衣袖和审视的侧影。镜头缓慢横移到诏书,展示端整墨字与少量朱砂批记。第七秒帝王枯瘦手指从画外伸入,轻点纸面某一行;婉儿笔尖停顿半拍但不抬头,继续书写。情绪是无声考核,不做争吵或夸张对峙。",
|
||
transition="镜头沿帝王指尖下移,进入纸边极小批注的微距。"),
|
||
dict(n=11, section="Verse 2", title="把心藏进小字号", lyric="我也学会了 把心 藏进批注的小字号",
|
||
beats=[("0–3秒", "极小字号批注在宣纸边缘逐行出现。"), ("3–7秒", "笔尖写到一个字时微停,墨迹化成短暂心形涟漪。"), ("7–10秒", "婉儿袖口遮住批注,诏书正文保持端正。")],
|
||
subtitles="0.8–9.7秒「我也学会了 把心 藏进批注的小字号」",
|
||
prompt="超近景拍宣纸边缘与纤细笔尖,诏书正文大字端正,边缘批注字号极小、密而整齐,不要求文字可辨读。婉儿写到一处时笔尖微停,墨面反光短暂形成近似心形的细小涟漪,随即恢复普通墨迹。后段她轻移玄色衣袖遮住批注区域,只留下公开正文。避免真实可读文字,强调“隐藏”而非魔幻发光。",
|
||
transition="玄色袖口掠过画面,叠化成长廊中搀扶帝王的玄衣背影。"),
|
||
dict(n=12, section="Verse 2", title="扶老帝王上朝", lyric="你老了 手也抖了 我扶你上朝",
|
||
beats=[("0–3秒", "幽深宫廊中,两人背影缓慢前行。"), ("3–7秒", "帝王袖口颤动、步履迟缓,婉儿手臂稳定。"), ("7–10秒", "前方朝堂暖光增强,帝王加重搭臂力道。")],
|
||
subtitles="0.8–5.0秒「你老了 手也抖了」;5.0–9.8秒「我扶你上朝」",
|
||
prompt="幽深唐代宫廊纵深透视,固定跟随镜头缓慢前推。左侧玄衣上官婉儿背影挺拔,右侧身着明黄龙袍的晚年武则天略显佝偻,婉儿搀扶她向朝堂走去。帝王袖口和手指细微颤动,步伐迟缓;婉儿步伐稳定。两侧红柱与灯火缓慢后退,前方暖金朝堂光晕渐亮。第八秒帝王在婉儿手臂上加重力道,全程不露正脸。",
|
||
transition="二人长影拉长,地面影子逐渐变成一卷血红诏书。"),
|
||
dict(n=13, section="Verse 2", title="谁也没提过那道诏", lyric="这一路 我们谁也没提过 那道诏",
|
||
beats=[("0–3秒", "延续宫廊跟随,青砖地面开始浮出红色卷轴虚影。"), ("3–7秒", "诏书虚影展开,两人脚步从其上踏过。"), ("7–10秒", "诏影散为红墨气,婉儿停半拍又继续走。")],
|
||
subtitles="0.8–6.0秒「这一路 我们谁也没提过」;6.0–9.8秒「那道诏」",
|
||
prompt="延续上一镜同一宫廊、同一背影与光位。两人缓步前行时,青砖地面从脚下浮现一卷血红诏书虚影,卷轴缓慢展开,朱砂字迹模糊不可辨读。二人脚步踏过虚影,没有低头。第七秒诏书散成红色墨气,被步风卷走;婉儿脚步停顿半拍,随后继续搀扶帝王前行。红色只用于诏影,不污染整体暗调。",
|
||
transition="红墨气上升并遮满画面,化成第二次Pre的火光与笔影。"),
|
||
dict(n=14, section="Pre 2", title="第二次选择", lyric="该恨你 还是该谢你 / 你毁了我的家 又给了我笔",
|
||
beats=[("0–3秒", "婉儿眼中闪回焚宅与祖父剪影。"), ("3–7秒", "现实中她握紧毛笔,火光倒影与烛光重合。"), ("7–10秒", "她松开紧绷手指,重新落笔,完成主动选择。")],
|
||
subtitles="0.5–4.5秒「该恨你 还是该谢你」;4.5–9.8秒「你毁了我的家 又给了我笔」",
|
||
prompt="成年婉儿中近景,先凝视手中毛笔。她瞳孔中短暂闪回燃烧的祖宅与白发祖父剪影,火光倒影和现实烛光在眼中重叠。第三秒手指用力握紧笔杆,指节泛白;第七秒她缓慢放松手指,深吸气但不流泪、不哭喊,随后把笔落向诏书。与第一次Pre相比,这一镜不是被动接笔,而是她清醒地再次选择使用这支笔。",
|
||
transition="笔尖落下的一滴墨扩散,进入第二次更明亮、更主动的宫城全景。"),
|
||
dict(n=15, section="Chorus 2", title="第二次为自己活", lyric="我为你研墨 也为自己活 / 仇人的江山 我替她说",
|
||
beats=[("0–3秒", "婉儿研墨并抬眼,目光从砚面转向宫城。"), ("3–7秒", "墨迹化为朝堂奏章与宫阙,镜头升高。"), ("7–10秒", "她立于朝堂与宫城之间,主动向前一步。")],
|
||
subtitles="0.5–4.8秒「我为你研墨 也为自己活」;4.8–9.8秒「仇人的江山 我替她说」",
|
||
prompt="第二次副歌采用更坚定的视觉。成年婉儿研墨后缓慢抬眼,目光从砚面转向前方。黑色墨迹从砚边流出,连续化为摊开的奏章、朝堂台阶与远处宫阙,镜头缓慢升高。婉儿从暗处向暖金光区迈出一步,玄红女官服衣摆轻动;她不再只是城楼上的孤小棋子,而是站在文字与江山之间的执笔者。",
|
||
transition="朝堂地砖转化为棋盘,婉儿迈出的一步对应白子落盘。"),
|
||
dict(n=16, section="Chorus 2", title="第二盘棋的答案", lyric="你看不透我 我也看不透我 / 这盘棋里 谁是谁的 因果",
|
||
beats=[("0–3秒", "铜镜中出现婉儿、祖父与帝王三重淡影。"), ("3–7秒", "镜面裂成棋盘格,白子落在关键位置。"), ("7–10秒", "黑子周围墨色退开,棋局仍未结束。")],
|
||
subtitles="0.5–4.5秒「你看不透我 我也看不透我」;4.5–9.8秒「这盘棋里 谁是谁的 因果」",
|
||
prompt="铜镜与砚面融合的黑镜中,成年婉儿自己的脸最清晰,白发祖父和晚年帝王只以淡淡轮廓在两侧重叠,三者随墨纹轻微错位。第三秒镜面逐格转化为青玉棋盘,婉儿戴银镯的手把白子落在关键位置,周围黑子不消失但墨色阴影逐渐退开。最后棋局仍未终结,镜头停在白子与婉儿手指离开的空隙。",
|
||
transition="白子落点泛出的墨晕旋成更大的掌上风。"),
|
||
dict(n=17, section="Chorus 2|间奏", title="风从掌上吹向江山", lyric="(掌上起风 婉儿落笔)",
|
||
beats=[("0–3秒", "掌心墨风比第一次更强,卷起细小纸页。"), ("3–7秒", "墨风沿手臂流向笔尖,婉儿落笔。"), ("7–10秒", "笔画化作宫阙轮廓,风越过城楼吹向远方。")],
|
||
subtitles="1.0–9.0秒「(掌上起风 婉儿落笔)」;使用28pt淡灰括号体",
|
||
prompt="呼应镜9但规模升级。婉儿摊开手掌,墨色风涡从掌心升起,卷动几张轻薄奏章纸页,但不形成暴风。墨风沿手腕和毛笔方向流动,第三秒另一只手稳稳落笔;新写出的墨色笔画从纸面升起,连续化成微缩宫阙与城墙轮廓。后段镜头随墨风越过城楼,吹向远处夜色,表达她的笔已经进入江山叙事。",
|
||
transition="远处墨云缓慢聚拢成祖父的白发面容,进入Bridge。"),
|
||
dict(n=18, section="Bridge", title="比报仇更长的一句咒", lyric="(古琴独白)祖父啊 我没替你报仇 / 我活成了 比报仇 更长的一句咒",
|
||
beats=[("0–3秒", "古琴独白中,祖父面容从砚中缓慢浮现。"), ("3–7秒", "婉儿凝视祖父,宫城与诏书片段在墨面掠过。"), ("7–10秒", "祖父面容与婉儿倒影重合,烛泪落入砚池。")],
|
||
subtitles="0.5–4.5秒「祖父啊 我没替你报仇」;4.5–9.8秒「我活成了 比报仇 更长的一句咒」",
|
||
prompt="古琴独白氛围,中近景缓推。成年婉儿俯身凝视砚中墨面,白发祖父上官仪的清瘦威严面容从涟漪中缓慢浮现。墨面边缘掠过焚宅、诏书、宫城和搀扶帝王的淡淡片段,如漫长人生回声。第七秒祖父面容与婉儿自己的倒影短暂重合,一滴烛泪落入砚池,重合影像被涟漪打散。婉儿唇角微颤但不落泪。",
|
||
transition="涟漪散尽后只留下婉儿自己的倒影,进入自我回答。"),
|
||
dict(n=19, section="Bridge", title="只是想活下去的人", lyric="或者 只是一个 想活下去的人",
|
||
beats=[("0–3秒", "黑镜只映出婉儿自己,她第一次正视倒影。"), ("3–7秒", "她直起身,身后宫门缓慢打开,冷夜转为黎明。"), ("7–10秒", "她走向门口但停在光影交界,留下选择余地。")],
|
||
subtitles="0.8–9.5秒「或者 只是一个 想活下去的人」;30pt淡灰,像低声自语",
|
||
prompt="砚面恢复平静,只映出成年婉儿自己的脸,不再出现祖父或帝王。她与倒影对视约三秒,随后缓慢直起身。身后半闭宫门逐渐打开,门外不是炫目强光,而是冷灰黎明与淡金天色。婉儿向门口走两步,停在阴影与晨光交界处,侧脸安静、疲惫但仍有生命力。镜头不煽情,表达她也可能只是一个努力活下来的人。",
|
||
transition="门外淡金天色叠化为明黄诏书纸面。"),
|
||
dict(n=20, section="Outro", title="墨干诏成,风仍在掌上", lyric="(研墨声渐远)墨干了 诏成了 / 风 还在掌上",
|
||
beats=[("0–3秒", "俯拍诏书,墨迹由湿转干,研墨声渐远。"), ("3–7秒", "墨字离纸化成宫阙,镜头升起俯瞰灯火。"), ("7–10秒", "婉儿在城楼摊开手掌,灯火逐盏熄灭,最终全黑。")],
|
||
subtitles="0.5–5.0秒「墨干了 诏成了」;5.0–9.1秒「风 还在掌上」;9.1秒后全黑",
|
||
prompt="俯拍明黄诏书,湿润墨迹在前三秒内缓慢失去反光并变干,研墨声逐渐远去。随后墨色笔画从纸面升起,化为微缩宫阙与大明宫夜景,镜头随之上升后拉。婉儿背影立在最高城楼,轻轻摊开一只手掌,掌心只剩一缕很淡的墨风。第七秒起万家灯火逐盏熄灭,最后仅剩她身旁一盏灯,约第九秒熄灭并归于全黑。生成完整10秒;合成199.152秒音频时裁掉末尾约0.85秒黑场。",
|
||
transition="全黑结束,不加片尾文字或Logo。"),
|
||
]
|
||
|
||
|
||
def tc_for(n):
|
||
start = (n - 1) * 10
|
||
end = n * 10
|
||
return f"{start // 60:02d}:{start % 60:02d}–{end // 60:02d}:{end % 60:02d}"
|
||
|
||
|
||
def add_cover(doc):
|
||
p = doc.add_paragraph()
|
||
p.paragraph_format.space_before = Pt(62)
|
||
p.paragraph_format.space_after = Pt(16)
|
||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||
b.set_run_font(p.add_run("上官婉儿主题音乐视频"), size=11, bold=True, color=b.GOLD)
|
||
|
||
p = doc.add_paragraph()
|
||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||
p.paragraph_format.space_after = Pt(8)
|
||
b.set_run_font(p.add_run("《我为你研墨》"), size=30, bold=True, color=b.INK, name=b.SERIF)
|
||
|
||
p = doc.add_paragraph()
|
||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||
p.paragraph_format.space_after = Pt(10)
|
||
b.set_run_font(p.add_run("完整歌词脚本与分镜头提示词"), size=17, color=b.CINNABAR)
|
||
|
||
p = doc.add_paragraph()
|
||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||
p.paragraph_format.space_after = Pt(30)
|
||
b.set_run_font(p.add_run("20 个分镜 × 每镜严格 10 秒|不生成图片"), size=11, bold=True, color=b.GOLD)
|
||
|
||
table = doc.add_table(rows=6, cols=2)
|
||
b.set_table_geometry(table, [1900, 7460])
|
||
b.set_repeat_table_header(table.rows[0])
|
||
for j, text in enumerate(("项目", "制作参数")):
|
||
b.set_cell_shading(table.cell(0, j), b.INK)
|
||
p = table.cell(0, j).paragraphs[0]
|
||
p.paragraph_format.space_after = Pt(0)
|
||
b.set_run_font(p.add_run(text), size=9.2, bold=True, color=b.WHITE)
|
||
rows = [
|
||
("歌词结构", "Intro → Verse → Pre → Chorus → Verse → Pre → Chorus → Bridge → Outro"),
|
||
("分镜", "20镜;每条图生视频提示词生成时长固定为10秒"),
|
||
("素材总长", "200秒;与199.152秒音频合成时,裁掉最后约0.85秒黑场"),
|
||
("画幅", "9:16竖屏,1080×1920,H.264,30fps"),
|
||
("说明", "本文件只提供脚本、字幕与提示词,不生成任何图片或视频素材"),
|
||
]
|
||
for i, (label, value) in enumerate(rows, start=1):
|
||
b.set_cell_shading(table.cell(i, 0), b.PALE)
|
||
for j, text in enumerate((label, value)):
|
||
p = table.cell(i, j).paragraphs[0]
|
||
p.paragraph_format.space_after = Pt(0)
|
||
b.set_run_font(p.add_run(text), size=9.4, bold=(j == 0), color=b.CINNABAR if j == 0 else b.INK)
|
||
doc.add_page_break()
|
||
|
||
|
||
def add_front(doc):
|
||
b.add_heading(doc, "1. 创作说明", 1)
|
||
b.add_label_para(doc, "核心叙事|", "不会写字的罪臣孤女,在仇人的宫廷中学会用笔;她替武则天书写江山,也借文字延长自己的生命,最终承认自己或许不是复仇者,只是一个想活下去的人。")
|
||
b.add_label_para(doc, "歌词原则|", "所有歌词严格按照用户提供的顺序出现;重复的Pre与Chorus采用不同情绪层级,第一次偏被动与撕裂,第二次偏清醒与主动。")
|
||
b.add_label_para(doc, "10秒规则|", "每个分镜提示词都明确要求生成10秒,不拆成5秒或8秒。20条素材合计200秒;最后一镜的末尾是黑场,可安全裁掉约0.85秒以匹配199.152秒音频。")
|
||
b.add_label_para(doc, "字幕规则|", "文档给出的是镜内建议区间。正式剪辑时,歌词字幕应以实际演唱咬字和音频波形为准,在相邻10秒镜头内前后微调,不需要改变画面提示词。")
|
||
|
||
b.add_heading(doc, "2. 统一视觉风格", 1)
|
||
b.add_prompt(doc, b.STYLE_PREFIX + "人物以成年上官婉儿为主,幼年与少年阶段只在明确镜头出现;武则天采用晚年帝王形象;全片不生成可辨读文字,字幕统一后期添加。")
|
||
b.add_heading(doc, "2.1 统一负面提示词", 2)
|
||
b.add_label_para(doc, "负面提示|", b.NEGATIVE, after=8, shade="F4EEEE")
|
||
|
||
b.add_heading(doc, "3. 20镜歌词分配总表", 1)
|
||
table = doc.add_table(rows=1, cols=5)
|
||
widths = [540, 1320, 930, 3710, 2860]
|
||
b.set_table_geometry(table, widths)
|
||
b.set_repeat_table_header(table.rows[0])
|
||
for j, text in enumerate(("镜", "时间", "段落", "歌词", "画面主题")):
|
||
b.set_cell_shading(table.cell(0, j), b.INK)
|
||
p = table.cell(0, j).paragraphs[0]
|
||
p.paragraph_format.space_after = Pt(0)
|
||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
|
||
b.set_run_font(p.add_run(text), size=8.8, bold=True, color=b.WHITE)
|
||
for s in SHOTS:
|
||
cells = table.add_row().cells
|
||
values = (str(s["n"]), tc_for(s["n"]), s["section"], s["lyric"].replace(" / ", "\n"), s["title"])
|
||
for j, text in enumerate(values):
|
||
p = cells[j].paragraphs[0]
|
||
p.paragraph_format.space_after = Pt(0)
|
||
p.paragraph_format.line_spacing = 1.05
|
||
p.alignment = WD_ALIGN_PARAGRAPH.CENTER if j < 3 else WD_ALIGN_PARAGRAPH.LEFT
|
||
for k, line in enumerate(text.split("\n")):
|
||
if k:
|
||
p.add_run().add_break()
|
||
b.set_run_font(p.add_run(line), size=8.2, bold=(j == 0), color=b.INK)
|
||
if s["n"] % 2 == 0:
|
||
b.set_cell_shading(cells[j], "FBF8F4")
|
||
b.set_table_geometry(table, widths)
|
||
b.add_label_para(doc, "音频收尾|", "第20镜生成00:10完整黑场尾帧;成片在03:19.152结束,裁掉最后约0.848秒黑场即可,不影响歌词和画面动作。", shade=b.PAPER)
|
||
doc.add_page_break()
|
||
|
||
|
||
def add_shot(doc, s):
|
||
h = doc.add_paragraph(style="Heading 1")
|
||
h.paragraph_format.page_break_before = True
|
||
h.paragraph_format.keep_with_next = True
|
||
b.set_run_font(h.add_run(f"分镜 {s['n']:02d}|{s['title']}"), size=16, bold=True, color=b.CINNABAR)
|
||
|
||
p = doc.add_paragraph()
|
||
p.paragraph_format.space_after = Pt(8)
|
||
b.shade_paragraph(p, b.PALE, b.GOLD)
|
||
for idx, (label, value) in enumerate((("时间", tc_for(s["n"])), ("生成", "严格10.00秒"), ("段落", s["section"]))):
|
||
if idx:
|
||
b.set_run_font(p.add_run(" | "), size=8.8, color=b.GOLD)
|
||
b.set_run_font(p.add_run(label + " "), size=8.8, bold=True, color=b.CINNABAR)
|
||
b.set_run_font(p.add_run(value), size=8.8, color=b.INK)
|
||
|
||
b.add_label_para(doc, "对应歌词|", s["lyric"], after=9, shade=b.PAPER)
|
||
b.add_heading(doc, "10秒导演脚本", 2)
|
||
for timing, action in s["beats"]:
|
||
b.add_label_para(doc, timing + "|", action, after=4)
|
||
b.add_heading(doc, "字幕建议", 2)
|
||
b.add_label_para(doc, "镜内字幕|", s["subtitles"], after=5)
|
||
b.add_label_para(doc, "转场|", s["transition"], after=7)
|
||
|
||
b.add_heading(doc, "10秒分镜提示词(可直接复制)", 2)
|
||
full_prompt = (
|
||
b.STYLE_PREFIX
|
||
+ "生成时长严格10秒,整个动作必须在0–10秒内完成;首帧和尾帧稳定可剪辑;不生成字幕、歌词、Logo或水印。"
|
||
+ s["prompt"]
|
||
+ "镜内节拍:"
|
||
+ ";".join(f"{timing}{action}" for timing, action in s["beats"])
|
||
+ "。"
|
||
)
|
||
b.add_prompt(doc, full_prompt)
|
||
b.add_label_para(doc, "统一负面提示|", b.NEGATIVE, after=7, shade="F4EEEE")
|
||
|
||
|
||
def add_end(doc):
|
||
h = doc.add_paragraph(style="Heading 1")
|
||
h.paragraph_format.page_break_before = True
|
||
b.set_run_font(h.add_run("4. 剪辑与验收"), size=16, bold=True, color=b.CINNABAR)
|
||
b.add_heading(doc, "4.1 剪辑执行", 2)
|
||
steps = [
|
||
("01|生成", "按分镜01至20顺序生成,每条时长选10秒;镜6左右分屏建议分别生成10秒再合成。"),
|
||
("02|铺音频", "先锁定《我为你研墨》原音频,再将20条素材按每10秒排列。"),
|
||
("03|字幕", "字幕不写入生成画面;以本文歌词顺序为准,以实际演唱波形微调入出点。"),
|
||
("04|收尾", "第20镜在03:19.152结束,裁掉素材末尾约0.848秒黑场。"),
|
||
("05|导出", "1080×1920,H.264,30fps,8–12Mbps;不添加未要求的片头、片尾或Logo。"),
|
||
]
|
||
for label, text in steps:
|
||
b.add_label_para(doc, label + " ", text, after=6)
|
||
b.add_heading(doc, "4.2 验收标准", 2)
|
||
table = doc.add_table(rows=1, cols=2)
|
||
b.set_table_geometry(table, [1800, 7560])
|
||
b.set_repeat_table_header(table.rows[0])
|
||
for j, text in enumerate(("验收项", "通过标准")):
|
||
b.set_cell_shading(table.cell(0, j), b.INK)
|
||
p = table.cell(0, j).paragraphs[0]
|
||
p.paragraph_format.space_after = Pt(0)
|
||
b.set_run_font(p.add_run(text), size=9.2, bold=True, color=b.WHITE)
|
||
rows = [
|
||
("提示词时长", "20条提示词均明确标注10.00秒,无5秒、7秒或16秒生成要求。"),
|
||
("歌词完整", "用户提供的全部歌词按原顺序出现,两次Pre和两次Chorus均完整保留。"),
|
||
("人物连续", "幼年、少年与成年婉儿阶段清晰;成年服装、红簪、银镯和右上烛光方向保持统一。"),
|
||
("画面安全", "无现代元素、可辨读文字、字幕、水印、Logo、畸形手指、穿模或面部突变。"),
|
||
("音频结尾", "最终成片在03:19.152结束,最后一句和研墨声尾音完整保留。"),
|
||
]
|
||
for label, value in rows:
|
||
cells = table.add_row().cells
|
||
b.set_cell_shading(cells[0], b.PALE)
|
||
for j, text in enumerate((label, value)):
|
||
p = cells[j].paragraphs[0]
|
||
p.paragraph_format.space_after = Pt(0)
|
||
b.set_run_font(p.add_run(text), size=9.2, bold=(j == 0), color=b.CINNABAR if j == 0 else b.INK)
|
||
b.set_table_geometry(table, [1800, 7560])
|
||
|
||
|
||
def build():
|
||
OUT.parent.mkdir(parents=True, exist_ok=True)
|
||
doc = Document()
|
||
sec = doc.sections[0]
|
||
sec.page_width = Inches(8.5)
|
||
sec.page_height = Inches(11)
|
||
sec.top_margin = Inches(1)
|
||
sec.bottom_margin = Inches(1)
|
||
sec.left_margin = Inches(1)
|
||
sec.right_margin = Inches(1)
|
||
sec.header_distance = Inches(0.492)
|
||
sec.footer_distance = Inches(0.492)
|
||
sec.different_first_page_header_footer = True
|
||
b.configure_styles(doc)
|
||
|
||
hp = sec.header.paragraphs[0]
|
||
b.set_run_font(hp.add_run("《我为你研墨》|完整歌词20镜执行稿"), size=8.5, color=b.MUTED)
|
||
b.add_page_field(sec.footer.paragraphs[0])
|
||
|
||
core = doc.core_properties
|
||
core.title = "《我为你研墨》完整歌词脚本与20镜分镜提示词(每镜10秒)"
|
||
core.subject = "上官婉儿主题音乐视频制作执行稿"
|
||
core.author = ""
|
||
core.keywords = "我为你研墨, 上官婉儿, 完整歌词, 20镜, 10秒, 分镜提示词"
|
||
core.comments = "根据用户提供完整歌词顺序创作,不生成图片。"
|
||
|
||
add_cover(doc)
|
||
add_front(doc)
|
||
for shot in SHOTS:
|
||
add_shot(doc, shot)
|
||
add_end(doc)
|
||
doc.save(OUT)
|
||
print(OUT)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
build()
|