Files
feedmill-auto-label/scripts/transcode_archive.py
T
asus 5c7c122105 feat: add counting bench, triage, and dataset modules
This commit includes major additions and updates to the frontend and backend architectures, introducing new dataset management, live counting features, batch processing, and triage logic. Includes new UI pages, components, and API routes.
2026-08-14 16:28:52 +07:00

67 lines
2.4 KiB
Python
Executable File

#!/usr/bin/env python3
"""Transcode video archive files to browser-compatible H.264 MP4 format."""
import os
import sys
import subprocess
import shutil
from pathlib import Path
VIDEO_EXTS = {".mp4", ".mkv", ".mov", ".avi", ".webm", ".m4v"}
def probe_codec(file_path: Path) -> str:
cmd = [
"ffprobe", "-v", "error", "-select_streams", "v:0",
"-show_entries", "stream=codec_name",
"-of", "default=noprint_wrappers=1:nokey=1", str(file_path)
]
res = subprocess.run(cmd, capture_output=True, text=True)
return res.stdout.strip().lower()
def transcode_video(file_path: Path):
tmp_path = file_path.with_name(f"_transcoded_{file_path.stem}.mp4")
cmd = [
"ffmpeg", "-hide_banner", "-loglevel", "error", "-y",
"-i", str(file_path),
"-c:v", "libx264", "-preset", "fast", "-crf", "22",
"-c:a", "aac", "-b:a", "128k",
"-movflags", "+faststart",
str(tmp_path)
]
res = subprocess.run(cmd)
if res.returncode == 0 and tmp_path.exists() and tmp_path.stat().st_size > 0:
# Save as .mp4
target_path = file_path.with_suffix(".mp4")
if target_path != file_path and file_path.exists():
file_path.unlink()
shutil.move(str(tmp_path), str(target_path))
print(f" ✅ Transcoded -> {target_path}")
else:
if tmp_path.exists():
tmp_path.unlink()
print(f" ❌ Failed to transcode {file_path}")
def process_archive(archive_dir: Path):
if not archive_dir.exists():
print(f"Archive directory {archive_dir} does not exist.")
return
print(f"Scanning {archive_dir} for non-H.264 videos...")
for root, _, files in os.walk(archive_dir):
for file in sorted(files):
file_path = Path(root) / file
if file_path.suffix.lower() in VIDEO_EXTS and not file.startswith("_transcoded_"):
codec = probe_codec(file_path)
if not codec:
print(f"⚠️ Could not probe codec or unreadable: {file_path}")
continue
if codec != "h264":
print(f"🔄 Converting {file_path} (current codec: {codec})...")
transcode_video(file_path)
else:
print(f" ✓ Already H.264: {file_path}")
if __name__ == "__main__":
target = Path(sys.argv[1]) if len(sys.argv) > 1 else Path("data/archive")
process_archive(target)