fix: the rewriter's own cut openers and views never become camera targets
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
efc5757950
commit
2abd7fc30f
+21
-2
@@ -232,7 +232,7 @@ def add_camera_moves(text, seed=None, chance=1.0):
|
||||
bodies = [text[m.end():(marks[i + 1].start() if i + 1 < len(marks) else len(text))]
|
||||
for i, m in enumerate(marks)]
|
||||
parts = [_split_sound(b) for b in bodies]
|
||||
cands = [candidates(p[0]) for p in parts]
|
||||
cands = [candidates(own_words_removed(p[0])) for p in parts]
|
||||
header_lemmas = {c[0] for c in candidates(header)}
|
||||
# In (nearly) every shot = about the whole prompt, not this shot. 70%: with three shots a
|
||||
# noun shared by two of them is still a topic of those two, only all three is a constant.
|
||||
@@ -326,7 +326,7 @@ def add_shot_cuts(text, seconds, seed=0, chance=0.5, pieces=()):
|
||||
return text, info
|
||||
header = text[:marks[0].start()]
|
||||
parts = [_split_sound(b) for b in bodies]
|
||||
cands = [candidates(p[0]) for p in parts]
|
||||
cands = [candidates(own_words_removed(p[0])) for p in parts]
|
||||
header_lemmas = {c[0] for c in candidates(header)}
|
||||
need = max(2, math.ceil(0.7 * len(bodies))) if len(bodies) > 1 else 10 ** 9
|
||||
seen = {}
|
||||
@@ -413,3 +413,22 @@ def add_shot_views(text, seed=0, chance=0.4):
|
||||
last = view
|
||||
out.append(m.group(0) + body)
|
||||
return "".join(out), added
|
||||
|
||||
|
||||
_VIEW_SENTENCE = re.compile(r"^\s*(?:" + "|".join(re.escape(v) for v in VIEWS) + r")\.\s*", re.I)
|
||||
|
||||
|
||||
def own_words_removed(picture):
|
||||
"""`picture` without what this module wrote into it (its own cut openers and views) and
|
||||
without the bare cut words of a user-written opener ("At 00:03.500, the camera cuts to"),
|
||||
whose content after them is kept: those words are not the shot's content and must never
|
||||
become a target or a topic."""
|
||||
picture = _OUR_OPENER.sub("", picture, count=1)
|
||||
picture = _CUT_WORDS.sub("", picture, count=1)
|
||||
return _VIEW_SENTENCE.sub("", picture, count=1)
|
||||
|
||||
|
||||
_OUR_OPENER = re.compile(r"^\s*At \d\d:\d\d\.\d{3},\s*(?:" + "|".join(re.escape(o) for o in CUT_OPENERS)
|
||||
+ r")\.\s*", re.I)
|
||||
_CUT_WORDS = re.compile(r"^\s*(?:At \d\d:\d\d\.\d{3},\s*)?(?:the\s+)?(?:camera|shot)\s+"
|
||||
r"(?:cuts|transitions|changes|switches)\s+to\b\s*", re.I)
|
||||
|
||||
@@ -370,3 +370,28 @@ def test_the_phrases_we_write_never_say_the_camera_pulls_out():
|
||||
"""Only what the rewriter writes; a shortcut may say it as an action."""
|
||||
for group in (sc.MOVES_DETAIL, sc.MOVES_OTHER, sc.MOVES_TRAVEL, sc.MOVES_THEN, sc.MOVES_FINISH):
|
||||
assert not any("pulls out" in m for m in group), group
|
||||
|
||||
|
||||
def test_words_the_rewriter_wrote_never_become_targets():
|
||||
"""'The camera pans from the shot transitions to the tip': the cut opener was read as
|
||||
the shot's own content."""
|
||||
pytest.importorskip("spacy")
|
||||
P = (HEAD + "[Shot 1] <Subject 1> waves. [Shot 2] At 00:04.000, the shot transitions to the next "
|
||||
"moment. Side view. <Subject 2> touches <Subject 2>'s chin, then reaches for the lamp.")
|
||||
_out, rep = sc.add_camera_moves(P, seed=1, chance=1.0)
|
||||
m = rep[1]["move"] or ""
|
||||
assert "transition" not in m and "moment" not in m and "view" not in m.lower(), m
|
||||
assert "chin" in m or "lamp" in m
|
||||
|
||||
|
||||
def test_the_full_pipeline_output_has_no_own_words_in_a_move():
|
||||
pytest.importorskip("spacy")
|
||||
P = (HEAD + f"[Shot 1] {PA} [Shot 2] {PB} {PC} " + MUSIC)
|
||||
for seed in range(20):
|
||||
a, _ = sc.add_shot_cuts(P, 12, seed=seed, chance=1.0, pieces=PIECES)
|
||||
b, _ = sc.add_shot_views(a, seed=seed, chance=1.0)
|
||||
_out, rep = sc.add_camera_moves(b, seed=seed, chance=1.0)
|
||||
for r in rep:
|
||||
t = (r["target"] or "").lower()
|
||||
assert not any(w in t for w in ("transition", "moment", "beat", "new angle", "new view",
|
||||
"switch", "changes")), t
|
||||
|
||||
Reference in New Issue
Block a user