tntgroup's picture
deploy merged code
9b53f70
Raw History Blame Contribute Delete
2.86 kB
"""Tiện ích cho test: tạo video/âm thanh mẫu bằng ffmpeg, đo thời lượng."""
from __future__ import annotations
import os
import shutil
import subprocess
FFMPEG = shutil.which("ffmpeg") or "ffmpeg"
FFPROBE = shutil.which("ffprobe") or "ffprobe"
def make_video(path: str, dur: float = 2.0, size: str = "320x240",
rate: int = 15, with_audio: bool = False, color: str = "blue"):
os.makedirs(os.path.dirname(path), exist_ok=True)
if with_audio:
cmd = [FFMPEG, "-y", "-hide_banner", "-loglevel", "error",
"-f", "lavfi", "-i", f"testsrc=size={size}:rate={rate}:duration={dur}",
"-f", "lavfi", "-i", f"sine=frequency=330:duration={dur}",
"-c:v", "libx264", "-pix_fmt", "yuv420p", "-c:a", "aac",
"-shortest", path]
else:
cmd = [FFMPEG, "-y", "-hide_banner", "-loglevel", "error",
"-f", "lavfi", "-i", f"color=c={color}:s={size}:rate={rate}:d={dur}",
"-c:v", "libx264", "-pix_fmt", "yuv420p", "-an", path]
subprocess.run(cmd, check=True, capture_output=True)
return path
def make_audio(path: str, dur: float = 2.0, freq: int = 440):
os.makedirs(os.path.dirname(path), exist_ok=True)
subprocess.run([FFMPEG, "-y", "-hide_banner", "-loglevel", "error",
"-f", "lavfi", "-i", f"sine=frequency={freq}:duration={dur}",
"-c:a", "aac", path], check=True, capture_output=True)
return path
def duration(path: str) -> float:
out = subprocess.run([FFPROBE, "-v", "error", "-show_entries",
"format=duration", "-of", "csv=p=0", path],
capture_output=True, text=True).stdout.strip()
try:
return float(out)
except ValueError:
return 0.0
def has_audio(path: str) -> bool:
out = subprocess.run([FFPROBE, "-v", "error", "-select_streams", "a",
"-show_entries", "stream=codec_name", "-of", "csv=p=0", path],
capture_output=True, text=True).stdout.strip()
return bool(out)
def dimensions(path: str) -> tuple[int, int]:
"""(width, height) của stream video đầu tiên."""
out = subprocess.run([FFPROBE, "-v", "error", "-select_streams", "v:0",
"-show_entries", "stream=width,height", "-of", "csv=p=0:s=x", path],
capture_output=True, text=True).stdout.strip()
try:
w, h = out.split("x")
return int(w), int(h)
except ValueError:
return (0, 0)
def has_video(path: str) -> bool:
out = subprocess.run([FFPROBE, "-v", "error", "-select_streams", "v",
"-show_entries", "stream=codec_name", "-of", "csv=p=0", path],
capture_output=True, text=True).stdout.strip()
return bool(out)