fixed a bug
This commit is contained in:
@@ -239,55 +239,75 @@ def _parse_word_timestamps(raw_words) -> Optional[List[WordTimestamp]]:
|
||||
return words or None
|
||||
|
||||
|
||||
_PERIOD_BOUNDARY = re.compile(r"\.+")
|
||||
_PUNCTUATION_BOUNDARY = re.compile(r"[.?]+")
|
||||
|
||||
|
||||
def split_segment_by_periods(
|
||||
segment: TranscriptionSegment,
|
||||
def split_sentences_at_punctuation(
|
||||
segments: List[TranscriptionSegment],
|
||||
) -> List[TranscriptionSegment]:
|
||||
"""Split one whisper segment into sentences at periods (".")."""
|
||||
text = segment.text.strip()
|
||||
if not text:
|
||||
return []
|
||||
"""Merge whisper segments and cut sentences at periods/question marks.
|
||||
|
||||
Whisper's own segment breaks often fall mid-sentence, so text is accumulated
|
||||
across segments and a sentence is only closed once the accumulated text
|
||||
reaches a period or a question mark.
|
||||
"""
|
||||
sentences: List[TranscriptionSegment] = []
|
||||
pieces: List[str] = []
|
||||
cursor = 0
|
||||
for match in _PERIOD_BOUNDARY.finditer(text):
|
||||
piece = text[cursor:match.end()].strip()
|
||||
if piece.strip(".").strip():
|
||||
pieces.append(piece)
|
||||
cursor = match.end()
|
||||
tail = text[cursor:].strip()
|
||||
if tail:
|
||||
pieces.append(tail)
|
||||
if len(pieces) <= 1:
|
||||
return [segment] if pieces else []
|
||||
ends = _sentence_end_seconds(segment, pieces)
|
||||
sub_segments: List[TranscriptionSegment] = []
|
||||
start = segment.start_seconds
|
||||
for piece, end in zip(pieces, ends):
|
||||
if end > start:
|
||||
sub_segments.append(
|
||||
start_seconds: Optional[float] = None
|
||||
last_segment_end: Optional[float] = None
|
||||
|
||||
def flush(end_seconds: float) -> None:
|
||||
nonlocal pieces, start_seconds
|
||||
text = " ".join(piece for piece in pieces if piece).strip()
|
||||
if text and start_seconds is not None and end_seconds > start_seconds:
|
||||
sentences.append(
|
||||
TranscriptionSegment(
|
||||
start_seconds=start,
|
||||
end_seconds=end,
|
||||
text=piece,
|
||||
speaker=segment.speaker,
|
||||
start_seconds=start_seconds,
|
||||
end_seconds=end_seconds,
|
||||
text=text,
|
||||
)
|
||||
)
|
||||
start = end
|
||||
return sub_segments
|
||||
pieces = []
|
||||
start_seconds = None
|
||||
|
||||
|
||||
def _sentence_end_seconds(
|
||||
segment: TranscriptionSegment, pieces: List[str]
|
||||
) -> List[float]:
|
||||
lengths = [len(piece) for piece in pieces]
|
||||
total = sum(lengths)
|
||||
if segment.words and len(segment.words) >= len(pieces):
|
||||
word_ends = _word_boundary_ends(segment, lengths)
|
||||
if _valid_boundaries(segment, word_ends):
|
||||
return word_ends + [segment.end_seconds]
|
||||
return _proportional_ends(segment, lengths) + [segment.end_seconds]
|
||||
for segment in sorted(
|
||||
segments, key=lambda item: (item.start_seconds, item.end_seconds)
|
||||
):
|
||||
text = segment.text.strip()
|
||||
if not text:
|
||||
continue
|
||||
if not pieces:
|
||||
start_seconds = segment.start_seconds
|
||||
seg_pieces: List[str] = []
|
||||
cursor = 0
|
||||
for match in _PUNCTUATION_BOUNDARY.finditer(text):
|
||||
piece = text[cursor:match.end()].strip()
|
||||
cursor = match.end()
|
||||
if piece.strip(".?").strip():
|
||||
seg_pieces.append(piece)
|
||||
tail = text[cursor:].strip()
|
||||
if tail:
|
||||
seg_pieces.append(tail)
|
||||
if not seg_pieces:
|
||||
continue
|
||||
lengths = [len(piece) for piece in seg_pieces]
|
||||
ends: List[float] = []
|
||||
if segment.words and len(segment.words) >= len(seg_pieces):
|
||||
ends = _word_boundary_ends(segment, lengths)
|
||||
if not _valid_boundaries(segment, ends):
|
||||
ends = []
|
||||
if not ends:
|
||||
ends = _proportional_ends(segment, lengths)
|
||||
last_segment_end = segment.end_seconds
|
||||
for index, piece in enumerate(seg_pieces):
|
||||
pieces.append(piece)
|
||||
if piece[-1] in ".?":
|
||||
end_seconds = ends[index] if index < len(ends) else segment.end_seconds
|
||||
flush(end_seconds)
|
||||
start_seconds = end_seconds
|
||||
if pieces:
|
||||
flush(last_segment_end if last_segment_end is not None else start_seconds)
|
||||
return sentences
|
||||
|
||||
|
||||
def _word_boundary_ends(
|
||||
|
||||
Reference in New Issue
Block a user