优化多个视频带字幕问题
This commit is contained in:
@@ -32,7 +32,7 @@ PROMPT_PLACEHOLDERS = {
|
||||
"person_triview": [],
|
||||
"product_triview": ["商品", "补充"],
|
||||
"scene": ["场景描述"],
|
||||
"video_segment": ["设定", "风格", "脚本", "时长"],
|
||||
"video_segment": ["开场", "设定", "风格", "脚本", "时长"],
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
|
||||
@@ -489,6 +489,8 @@ _CREATIVE_DIRECTION = """
|
||||
全片只围绕这一个情境推进。不要在一条短视频里罗列所有卖点。
|
||||
|
||||
### 每一镜都必须有推进,禁止平铺直叙
|
||||
- 钩子镜的**画面**必须从一个正在进行的动作或一个可见状态开场,第一条秒级分镜不能是
|
||||
「对着镜头说话」这种静态口播开场(观众先看到事,再听到话;静态对镜口播也是成片被自动加大字的高发语境)。
|
||||
- 钩子镜:前 15 个字就抛出反常、尴尬、选择或结果;禁止「大家好」「今天分享」
|
||||
「给你们推荐」「这款很好用」「值得买」等任何寒暄或泛推荐开场。
|
||||
- 痛点镜:拍得到的细节,而非抽象感受。例如「开会前刘海粘成一绺」而不是「头发很油」。
|
||||
|
||||
@@ -891,6 +891,17 @@ NO_EMBEDDED_CAPTIONS_REQUIREMENT = (
|
||||
# 结尾再补一句极短的正面复述:末位权重高,但只用「叠加」这类中性词,不再重复负面名词。
|
||||
NO_EMBEDDED_CAPTIONS_TAIL = "画面全程保持纯实拍,无任何叠加层。"
|
||||
|
||||
# ★ 实测:同一条片子出四段,只有**开场那一段**带字幕,后三段干净。
|
||||
# 原因不在我们的提示词结构(四段模板完全一致),而在模型的先验:在「电商口播开场」这个语境下,
|
||||
# 它学到的强关联是「钩子 = 屏幕上打一行大字」;使用过程 / 特写 / CTA 段几乎不触发这个先验。
|
||||
# 所以给开场段单独一句**正面**指令,把这个先验掰到「钩子靠画面和表演」上 ——
|
||||
# 注意全句不含任何负面名词(字幕/花字…),否则又会掉进「越说越画」的坑。
|
||||
OPENING_SHOT_DIRECTIVE = (
|
||||
"【开场】这是全片的第一段:第一帧就是实拍画面本身,人物已经在做第一条秒级分镜里的那件事,"
|
||||
"镜头直接开拍,像从一段连续素材里截出来的。开场的吸引力全部来自人物的表情、动作和环境,"
|
||||
"屏幕保持干净。"
|
||||
)
|
||||
|
||||
# 提示词正文里残留的「字幕:…」「花字:…」会和上面的禁令打架 —— 模型看到具体字幕内容就会画出来。
|
||||
# 来源:脚本【声音】栏、视频提炼稿逐字照抄的画面花字、用户自己写的提示词。这里在送出前统一抹掉。
|
||||
_CAPTION_WORDS = r"(?:字幕|花字|艺术字|贴片|水印|角标|标题栏|弹幕)"
|
||||
@@ -2718,10 +2729,11 @@ def build_video_segment_prompt(project, video_segment, scene, refs, user_prompt:
|
||||
extra = (user_prompt or "").strip()
|
||||
if extra:
|
||||
script_text = (script_text + "\n" + extra).strip() if script_text else extra
|
||||
# 正文可在 admin「提示词·视频」页改。占位符:{设定}=@图N点名、{风格}=全片风格锚点、{脚本}=本段脚本、{时长}。
|
||||
# 正文可在 admin「提示词·视频」页改。占位符:{开场}=仅第一段有的开场指令、{设定}=@图N点名、
|
||||
# {风格}=全片风格锚点、{脚本}=本段脚本、{时长}。
|
||||
# 时长/比例靠 API 参数传(duration/ratio),不写进正文;尾句给风格 + 音效/字幕要求。
|
||||
default = (
|
||||
"{设定}{风格}【脚本】{脚本}\n"
|
||||
"{开场}{设定}{风格}【脚本】{脚本}\n"
|
||||
"【执行纪律】严格按脚本里的秒级分镜拍:每一个时间段都要拍到,景别、机位、运镜、动作按写的来;"
|
||||
"不要把整段并成一个静止长镜头,也不要加脚本里没有的转场、人物或道具。"
|
||||
"\n【一致性】参考图是本片唯一的视觉依据:角色保持同一张脸、同一发型、同一套服装;"
|
||||
@@ -2733,8 +2745,11 @@ def build_video_segment_prompt(project, video_segment, scene, refs, user_prompt:
|
||||
"\n【画质】真人实拍质感,自然光影,肤色与材质真实,焦点始终落在脚本指定的主体上,画面稳定不糊。"
|
||||
"\n电商带货短视频,商品露出清晰,节奏有转化感。不要背景音乐,但是要有音效,逼真的音效。"
|
||||
)
|
||||
# 开场段(全片第一段)额外挂一条正面开场指令 —— 字幕基本只在这一段冒出来
|
||||
opening = OPENING_SHOT_DIRECTIVE + "\n" if video_segment.sort_order == 0 else ""
|
||||
rendered = render_prompt(
|
||||
"video_segment", default,
|
||||
开场=opening,
|
||||
设定=("【设定】" + ",".join(setup_parts) + "。\n" if setup_parts else ""),
|
||||
风格=(f"【风格】{_scene_context(project)}。\n" if _scene_context(project) else ""),
|
||||
分镜="", # 兼容:旧模板行里可能还留着 {分镜}(故事板时代的占位符),渲染成空串而不是原样漏出
|
||||
|
||||
@@ -3,6 +3,7 @@ from django.test import SimpleTestCase
|
||||
from apps.ai.services import (
|
||||
NO_EMBEDDED_CAPTIONS_REQUIREMENT,
|
||||
NO_EMBEDDED_CAPTIONS_TAIL,
|
||||
OPENING_SHOT_DIRECTIVE,
|
||||
enforce_no_embedded_captions,
|
||||
strip_caption_directives,
|
||||
)
|
||||
@@ -87,3 +88,15 @@ class VideoCaptionPolicyTests(SimpleTestCase):
|
||||
self.assertNotIn("手慢无", prompt)
|
||||
self.assertIn("0-3s:特写;推近;倒入", prompt)
|
||||
self.assertTrue(prompt.startswith(NO_EMBEDDED_CAPTIONS_REQUIREMENT))
|
||||
|
||||
|
||||
class OpeningShotDirectiveTests(SimpleTestCase):
|
||||
"""实测:一条片子出四段,只有开场那段带字幕,后三段干净 —— 模型在「电商口播开场」语境下
|
||||
有「钩子 = 打一行大字」的强先验。开场段单独给一条正面指令把它掰回来。"""
|
||||
|
||||
def test_directive_is_purely_positive(self):
|
||||
"""★ 关键约束:这句里不能出现任何负面名词,否则又回到「越说越画」的老路。"""
|
||||
for word in ("字幕", "花字", "标题", "贴片", "水印", "文字"):
|
||||
self.assertNotIn(word, OPENING_SHOT_DIRECTIVE, msg=f"开场指令里不该出现「{word}」")
|
||||
self.assertIn("实拍画面", OPENING_SHOT_DIRECTIVE)
|
||||
self.assertIn("屏幕保持干净", OPENING_SHOT_DIRECTIVE)
|
||||
|
||||
@@ -1333,3 +1333,4 @@ class QuickCreateCoordinatorTests(TestCase):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user