webm file supported

This commit is contained in:
2026-09-12 11:28:32 +08:00
parent 67c7ad3d0f
commit ab4ff6c25a

View File

@@ -29,6 +29,60 @@ from .transcription import (
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
MOSS_ALGORITHM_VERSION = "moss-punctuation-v3" MOSS_ALGORITHM_VERSION = "moss-punctuation-v3"
SILENCE_ALGORITHM_VERSION = "silence-rms-v1" SILENCE_ALGORITHM_VERSION = "silence-rms-v1"
_CUES_ID = b"\x1e\x53\xb6\x80"
_CLUSTER_ID = b"\x1f\x43\xb6\x75"
_HEADER_SCAN_SIZE = 64 * 1024
_WEBM_SUFFIXES = {".webm", ".mkv"}
def _webm_cues_at_front(filepath: Path) -> bool:
"""Return True if WebM/MKV CUES appear before the first Cluster."""
try:
with open(filepath, "rb") as f:
header = f.read(_HEADER_SCAN_SIZE)
except OSError:
return True # can't read → assume OK, don't touch
cues_pos = header.find(_CUES_ID)
cluster_pos = header.find(_CLUSTER_ID)
if cues_pos != -1 and (cluster_pos == -1 or cues_pos < cluster_pos):
return True
return False
def _ensure_webm_cues_front(filepath: Path) -> None:
"""Re-mux a WebM/MKV file (stream copy) if CUES are not at the front.
YouTube-dl / yt-dlp writes CUES at the end by default, which slows HTTP
Range seeking. This runs once during upload processing and takes seconds.
"""
if filepath.suffix.lower() not in _WEBM_SUFFIXES:
return
if _webm_cues_at_front(filepath):
return
ffmpeg = shutil.which("ffmpeg")
if not ffmpeg:
logger.warning("ffmpeg not found; skipping WebM CUES optimization.")
return
tmp = filepath.with_suffix(".cues_tmp" + filepath.suffix)
try:
result = subprocess.run(
[ffmpeg, "-y", "-loglevel", "error",
"-i", str(filepath), "-c", "copy",
"-cues_to_front", "1", str(tmp)],
capture_output=True, timeout=300,
)
if result.returncode == 0 and tmp.is_file() and tmp.stat().st_size > 0:
tmp.replace(filepath)
logger.info("WebM CUES moved to front: %s", filepath.name)
else:
logger.warning(
"WebM CUES re-mux failed for %s: rc=%d stderr=%s",
filepath.name, result.returncode, result.stderr.decode()[-200:],
)
except (subprocess.TimeoutExpired, OSError) as exc:
logger.warning("WebM CUES re-mux error for %s: %s", filepath.name, exc)
finally:
tmp.unlink(missing_ok=True)
class VideoProcessor: class VideoProcessor:
@@ -55,6 +109,7 @@ class VideoProcessor:
self.repository.mark_processing(video_hash) self.repository.mark_processing(video_hash)
work_path: Optional[Path] = None work_path: Optional[Path] = None
try: try:
_ensure_webm_cues_front(media_path)
if self.transcriber.available: if self.transcriber.available:
work_path = self.settings.work_dir / f"{video_hash}-{uuid.uuid4().hex}.wav" work_path = self.settings.work_dir / f"{video_hash}-{uuid.uuid4().hex}.wav"
extract_audio(media_path, work_path) extract_audio(media_path, work_path)