add sentences borders enable in pc player

This commit is contained in:
2026-09-10 08:58:33 +08:00
parent 39896a5c24
commit 9980f78cfc
7 changed files with 556 additions and 23 deletions

View File

@@ -14,7 +14,8 @@ from .audio_metrics import (
refine_sentence_start_ms,
)
from .config import Settings
from .generate_boundaries import ALGORITHM_VERSION, make_entry
from .generate_boundaries import ALGORITHM_VERSION, make_entry, media_duration_ms
from sentence_analysis import detect_sentence_boundaries
from .models import SentenceBoundary, SentenceBoundaryDocument
from .oss import VolcanoOSSUploader
from .repository import VideoRepository
@@ -27,6 +28,7 @@ from .transcription import (
logger = logging.getLogger(__name__)
MOSS_ALGORITHM_VERSION = "moss-punctuation-v3"
SILENCE_ALGORITHM_VERSION = "silence-rms-v1"
class VideoProcessor:
@@ -417,6 +419,67 @@ def document_from_transcript(
)
def generate_audio_boundary_document(
*,
video_hash: str,
audio_path: Path,
transcriber: Transcriber,
language: Optional[str] = None,
) -> SentenceBoundaryDocument:
"""Generate sentence boundaries for a client-supplied audio file.
The caller owns ``audio_path`` and is responsible for deleting it. Nothing
in this function copies or registers the audio in application storage.
"""
duration_ms = media_duration_ms(audio_path)
transcript = None
if transcriber.available:
try:
transcript = transcriber.transcribe(audio_path, language)
except Exception as exc:
logger.warning("Audio boundary transcription failed; using silence fallback: %s", exc)
if transcript is not None:
document = document_from_transcript(
video_hash=video_hash,
duration_ms=duration_ms,
transcript=transcript,
language=language,
audio_path=audio_path,
)
if document.sentences:
return document
starts = detect_sentence_boundaries(audio_path)
if not starts:
raise ValueError("No sentence boundaries could be detected in the audio.")
starts_ms = sorted({max(0, min(duration_ms - 1, int(round(start * 1000)))) for start in starts})
sentences: List[SentenceBoundary] = []
for index, start_ms in enumerate(starts_ms):
end_ms = starts_ms[index + 1] if index + 1 < len(starts_ms) else duration_ms
if end_ms <= start_ms:
continue
sentences.append(
SentenceBoundary(
index=len(sentences),
start_ms=start_ms,
end_ms=end_ms,
text=None,
language=language,
)
)
if not sentences:
raise ValueError("Detected audio boundaries do not form valid sentence ranges.")
return SentenceBoundaryDocument(
video_hash=video_hash,
duration_ms=duration_ms,
algorithm_version=SILENCE_ALGORITHM_VERSION,
sentences=sentences,
)
def _media_duration_ms(path: Path) -> int:
from .generate_boundaries import media_duration_ms