try
This commit is contained in:
@@ -542,18 +542,23 @@ def get_video_duration(path: str) -> float:
|
||||
def compress_video(input_path: str, output_path: str,
|
||||
max_duration: int = VIDEO_MAX_DURATION_S,
|
||||
max_size_bytes: int = VIDEO_MAX_SIZE_BYTES) -> bool:
|
||||
"""
|
||||
Trim to max_duration and compress to fit max_size_bytes.
|
||||
Returns True on success.
|
||||
"""
|
||||
try:
|
||||
duration = get_video_duration(input_path)
|
||||
trim_to = min(duration, max_duration)
|
||||
|
||||
# Target bitrate calculation (leave 10 % headroom)
|
||||
# Guard: ffprobe returned 0 = file is not a valid video
|
||||
if duration <= 0:
|
||||
logging.error(
|
||||
f"❌ compress_video: ffprobe returned duration={duration} "
|
||||
f"— file is not a valid video: {input_path} "
|
||||
f"({os.path.getsize(input_path)} bytes)"
|
||||
)
|
||||
return False
|
||||
|
||||
trim_to = min(duration, max_duration)
|
||||
|
||||
target_bits = max_size_bytes * 8 * 0.90
|
||||
target_kbps = int(target_bits / trim_to / 1000)
|
||||
video_kbps = max(200, target_kbps - 128) # reserve 128 k for audio
|
||||
video_kbps = max(200, target_kbps - 128)
|
||||
|
||||
logging.info(
|
||||
f"🎬 Compressing: duration={duration:.1f}s → trim={trim_to:.1f}s, "
|
||||
@@ -633,7 +638,10 @@ def download_video(url: str, output_path: str,
|
||||
|
||||
def download_video_ytdlp(url: str, output_path: str,
|
||||
cookies: list = None) -> bool:
|
||||
"""Download a video using yt-dlp, optionally injecting cookies."""
|
||||
"""
|
||||
Download a video using yt-dlp with TikTok impersonation support.
|
||||
curl_cffi must be installed for impersonation to work.
|
||||
"""
|
||||
cookie_file = None
|
||||
try:
|
||||
import yt_dlp
|
||||
@@ -644,9 +652,11 @@ def download_video_ytdlp(url: str, output_path: str,
|
||||
"quiet": True,
|
||||
"no_warnings": False,
|
||||
"merge_output_format": "mp4",
|
||||
# ── TikTok impersonation ───────────────────────────────────
|
||||
# Requires curl_cffi: pip install curl-cffi
|
||||
"impersonate": "chrome",
|
||||
}
|
||||
|
||||
# Write cookies to a temp Netscape file if provided
|
||||
if cookies:
|
||||
cookie_file = _write_netscape_cookies(cookies)
|
||||
if cookie_file:
|
||||
@@ -655,14 +665,21 @@ def download_video_ytdlp(url: str, output_path: str,
|
||||
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
|
||||
ydl.download([url])
|
||||
|
||||
if os.path.exists(output_path) and os.path.getsize(output_path) > 10_000:
|
||||
logging.info(
|
||||
f"✅ yt-dlp download OK: "
|
||||
f"{os.path.getsize(output_path) / 1024 / 1024:.1f} MB"
|
||||
# Validate: must exist AND be a real video (> 50 KB)
|
||||
if os.path.exists(output_path):
|
||||
size = os.path.getsize(output_path)
|
||||
if size > 50_000:
|
||||
logging.info(
|
||||
f"✅ yt-dlp download OK: {size / 1024 / 1024:.1f} MB"
|
||||
)
|
||||
return True
|
||||
logging.error(
|
||||
f"❌ yt-dlp output too small ({size} bytes) — "
|
||||
f"likely an HTML error page, not a video."
|
||||
)
|
||||
return True
|
||||
return False
|
||||
|
||||
logging.error("❌ yt-dlp produced no output file or file too small.")
|
||||
logging.error("❌ yt-dlp produced no output file.")
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
@@ -672,7 +689,6 @@ def download_video_ytdlp(url: str, output_path: str,
|
||||
if cookie_file and os.path.exists(cookie_file):
|
||||
os.unlink(cookie_file)
|
||||
|
||||
|
||||
def _write_netscape_cookies(cookies: list) -> str | None:
|
||||
"""Write cookies list to a Netscape-format temp file for yt-dlp."""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user