feat: support tiktok download cookies
This commit is contained in:
@@ -29,6 +29,8 @@ SUBJECT_ASSET_IMAGE_MODEL=gpt-image-2
|
||||
SUBJECT_ASSET_IMAGE_MODELS=gpt-image-2
|
||||
# 可选:本地网络需要代理访问 ai.skg.com 时配置;launchd 不一定继承 shell 代理变量。
|
||||
AI_HTTP_PROXY=
|
||||
YTDLP_COOKIES_FILE=
|
||||
YTDLP_COOKIES_FROM_BROWSER=
|
||||
VIDEO_MODEL=seedance
|
||||
VIDEO_MODEL_SEEDANCE=seedance-2-fast
|
||||
VIDEO_MODEL_KLING=kling-omni
|
||||
|
||||
39
api/main.py
39
api/main.py
@@ -92,6 +92,8 @@ PRODUCT_ASSET_MIN_LONG_SIDE = max(512, int(os.getenv("PRODUCT_ASSET_MIN_LONG_SID
|
||||
PRODUCT_ASSET_MIN_SHORT_SIDE = max(320, int(os.getenv("PRODUCT_ASSET_MIN_SHORT_SIDE", "600")))
|
||||
PRODUCT_ASSET_JPEG_QUALITY = max(80, min(95, int(os.getenv("PRODUCT_ASSET_JPEG_QUALITY", "92"))))
|
||||
VIDEO_MODEL = os.getenv("VIDEO_MODEL", "seedance").strip() or "seedance"
|
||||
YTDLP_COOKIES_FILE = os.getenv("YTDLP_COOKIES_FILE", "").strip()
|
||||
YTDLP_COOKIES_FROM_BROWSER = os.getenv("YTDLP_COOKIES_FROM_BROWSER", "").strip()
|
||||
AUDIO_PRODUCT_BRIEF = os.getenv(
|
||||
"AUDIO_PRODUCT_BRIEF",
|
||||
"SKG 智能按摩产品,主打日常肩颈、腰背、眼部、膝盖或足部放松;广告表达要高级、干净、可信,不做医疗疗效承诺。",
|
||||
@@ -1031,6 +1033,35 @@ def run(cmd: list[str], cwd: Path | None = None) -> str:
|
||||
return res.stdout
|
||||
|
||||
|
||||
def ytdlp_cookie_args() -> list[str]:
|
||||
if YTDLP_COOKIES_FILE:
|
||||
cookies = Path(YTDLP_COOKIES_FILE).expanduser()
|
||||
if not cookies.exists():
|
||||
raise RuntimeError("TikTok cookies 文件不可用,请检查 YTDLP_COOKIES_FILE 配置。")
|
||||
return ["--cookies", str(cookies)]
|
||||
if YTDLP_COOKIES_FROM_BROWSER:
|
||||
return ["--cookies-from-browser", YTDLP_COOKIES_FROM_BROWSER]
|
||||
return []
|
||||
|
||||
|
||||
def normalize_download_error(error: Exception) -> str:
|
||||
raw = str(error)
|
||||
lower = raw.lower()
|
||||
auth_required = (
|
||||
"log in for access" in lower
|
||||
or "login" in lower and "cookies" in lower
|
||||
or "cookies-from-browser" in lower
|
||||
or "sign in" in lower and "tiktok" in lower
|
||||
)
|
||||
if auth_required:
|
||||
return (
|
||||
"TikTok 下载需要登录态。请上传视频文件,或在后端配置 "
|
||||
"YTDLP_COOKIES_FILE / YTDLP_COOKIES_FROM_BROWSER 后重试。"
|
||||
f"原始错误:{raw}"
|
||||
)
|
||||
return raw
|
||||
|
||||
|
||||
# ---- 启发式选帧工具 ----
|
||||
import imagehash
|
||||
import numpy as np
|
||||
@@ -1696,13 +1727,15 @@ def pipeline_download(job_id: str) -> None:
|
||||
update(job, status="downloading", message="本地上传 · 跳过下载", progress=15)
|
||||
else:
|
||||
update(job, status="downloading", message="yt-dlp 下载中…", progress=5)
|
||||
run([
|
||||
cmd = [
|
||||
"yt-dlp", "-f", "best[ext=mp4]/best",
|
||||
"-o", str(mp4),
|
||||
"--no-warnings", "--no-playlist",
|
||||
"--retries", "3",
|
||||
*ytdlp_cookie_args(),
|
||||
job.url,
|
||||
])
|
||||
]
|
||||
run(cmd)
|
||||
if not mp4.exists():
|
||||
raise RuntimeError("下载完成但找不到 source.mp4")
|
||||
|
||||
@@ -1725,7 +1758,7 @@ def pipeline_download(job_id: str) -> None:
|
||||
)
|
||||
except Exception as e:
|
||||
message = "视频元数据解析失败" if stage == "metadata" else "下载失败"
|
||||
update(job, status="failed", error=str(e), message=message)
|
||||
update(job, status="failed", error=normalize_download_error(e), message=message)
|
||||
|
||||
|
||||
def pipeline_analyze(
|
||||
|
||||
Reference in New Issue
Block a user