allow ajust sentences

This commit is contained in:
2026-08-30 11:07:50 +08:00
parent 508a26ba02
commit 0d0b82e095
9 changed files with 270 additions and 3 deletions

View File

@@ -491,6 +491,121 @@ class VideoRepository:
for row in result_rows
]
def adjust_sentence_boundary(
self,
video_hash: str,
sentence_index: int,
delta_ms: int,
) -> Optional[List[SentenceBoundary]]:
"""Move one sentence end and link the next sentence's start to it."""
normalized_hash = normalize_video_hash(video_hash)
with self._connect() as connection:
video = connection.execute(
"SELECT duration_ms FROM videos WHERE video_hash = ?",
(normalized_hash,),
).fetchone()
if video is None or video["duration_ms"] is None:
return None
current = connection.execute(
"""
SELECT * FROM sentences
WHERE video_hash = ? AND sentence_index = ?
""",
(normalized_hash, sentence_index),
).fetchone()
if current is None:
return None
following = connection.execute(
"""
SELECT * FROM sentences
WHERE video_hash = ? AND sentence_index = ?
""",
(normalized_hash, sentence_index + 1),
).fetchone()
duration_ms = int(video["duration_ms"])
minimum_end = current["start_ms"] + 1
maximum_end = duration_ms
if following is not None:
maximum_end = min(maximum_end, following["end_ms"] - 1)
new_end_ms = current["end_ms"] + delta_ms
if new_end_ms < minimum_end or new_end_ms > maximum_end:
raise ValueError(
"The adjusted boundary must remain inside both sentences."
)
current_duration_ms = new_end_ms - current["start_ms"]
current_reference_ms = current["reference_speech_duration_ms"] or current_duration_ms
current_reference_ms = min(
current_duration_ms,
max(1, current_reference_ms + delta_ms),
)
connection.execute(
"""
UPDATE sentences
SET end_ms = ?, reference_speech_duration_ms = ?
WHERE video_hash = ? AND sentence_index = ?
""",
(
new_end_ms,
current_reference_ms,
normalized_hash,
sentence_index,
),
)
updated_indexes = [sentence_index]
if following is not None:
old_start_ms = following["start_ms"]
next_duration_ms = following["end_ms"] - new_end_ms
next_reference_ms = following["reference_speech_duration_ms"] or next_duration_ms
next_reference_ms = min(
next_duration_ms,
max(1, next_reference_ms - (new_end_ms - old_start_ms)),
)
connection.execute(
"""
UPDATE sentences
SET start_ms = ?, reference_speech_duration_ms = ?
WHERE video_hash = ? AND sentence_index = ?
""",
(
new_end_ms,
next_reference_ms,
normalized_hash,
sentence_index + 1,
),
)
updated_indexes.append(sentence_index + 1)
connection.execute(
"UPDATE videos SET updated_at = ? WHERE video_hash = ?",
(utc_now(), normalized_hash),
)
placeholders = ", ".join("?" for _ in updated_indexes)
result_rows = connection.execute(
f"""
SELECT * FROM sentences
WHERE video_hash = ? AND sentence_index IN ({placeholders})
ORDER BY sentence_index
""",
(normalized_hash, *updated_indexes),
).fetchall()
return [
SentenceBoundary(
index=row["sentence_index"],
start_ms=row["start_ms"],
end_ms=row["end_ms"],
text=row["text"],
language=row["language"],
reference_speech_duration_ms=row["reference_speech_duration_ms"],
)
for row in result_rows
]
def create_dub_share(
self,
*,