webm file supported
This commit is contained in:
@@ -29,6 +29,60 @@ from .transcription import (
|
||||
logger = logging.getLogger(__name__)
|
||||
MOSS_ALGORITHM_VERSION = "moss-punctuation-v3"
|
||||
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:
|
||||
@@ -55,6 +109,7 @@ class VideoProcessor:
|
||||
self.repository.mark_processing(video_hash)
|
||||
work_path: Optional[Path] = None
|
||||
try:
|
||||
_ensure_webm_cues_front(media_path)
|
||||
if self.transcriber.available:
|
||||
work_path = self.settings.work_dir / f"{video_hash}-{uuid.uuid4().hex}.wav"
|
||||
extract_audio(media_path, work_path)
|
||||
|
||||
Reference in New Issue
Block a user