From c2d8ebab4b6950cebe3056843dff1c9786fe5a5a Mon Sep 17 00:00:00 2001 From: xiaoxia Date: Thu, 17 Sep 2026 17:54:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(douyin):=20ASR=E8=BF=94=E5=9B=9E=E7=A9=BA?= =?UTF-8?q?=E6=97=B6=EF=BC=88=E6=97=A0=E6=97=81=E7=99=BD=E8=A7=86=E9=A2=91?= =?UTF-8?q?=EF=BC=89=E4=BD=BF=E7=94=A8Feed=20desc=E5=85=9C=E5=BA=95?= =?UTF-8?q?=EF=BC=8C=E9=81=BF=E5=85=8D503?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/api/app/api/routes/scripts_ai.py | 33 +++++++++++++++++++-------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/apps/api/app/api/routes/scripts_ai.py b/apps/api/app/api/routes/scripts_ai.py index 7bf1d3f0b..c42722dc1 100644 --- a/apps/api/app/api/routes/scripts_ai.py +++ b/apps/api/app/api/routes/scripts_ai.py @@ -356,7 +356,7 @@ def _fetch_ttwid(): # 方式一:直接调 ttwid 注册接口 try: with httpx.Client(timeout=8, follow_redirects=True, verify=False) as http: - http.post( + r = http.post( "https://ttwid.bytedance.com/ttwid/union/register/", json={ "region": "cn", @@ -769,7 +769,7 @@ def _ytdlp_download_and_local_asr(page_url, temp_dir, cookiefile=None): cookie_files_to_try.append(cookiefile) # 2. 合成 cookie 重试(复用 _ytdlp_extract 的 cookie 生成逻辑,8次重试) - import time as _time + import secrets, time as _time ttwid = _fetch_ttwid() for i in range(8): if i % 3 == 0: @@ -945,10 +945,9 @@ def _html_scrape_direct_url(page_url, timeout=15): @router.get("/douyin/__debug_diag") def douyin_diag(): """[Staging only] 容器内网络/yt-dlp诊断""" - import tempfile as _tf - import time as _t - import httpx as _httpx + import time as _t + import tempfile as _tf import yt_dlp as _ytdlp results = {} @@ -1244,17 +1243,31 @@ def extract_from_douyin( if text: break + # ASR 可能返回空(视频无旁白/只有BGM/环境音),此时用 feed_desc 作为文案兜底 + if feed_desc and not text: + text = feed_desc.strip() + logger.info( + "抖音 ASR 未识别到语音(第%d轮),使用 Feed API desc 作为文案: desc_len=%d", + round_idx + 1, len(text), + ) + break + # 本轮全链路失败,等一下重试(直链未拿到可能是瞬时限流) if round_idx < max_rounds - 1: logger.info("第%d轮全链路失败,等待后重试", round_idx + 1) time.sleep(1.5) if not text: - logger.warning("抖音文案提取全部失败: url=%s", page_url) - raise HTTPException( - status_code=status.HTTP_503_SERVICE_UNAVAILABLE, - detail="抖音链接解析暂时不可用,请稍后重试或手动输入文案", - ) + # 终极兜底:所有 ASR 路径均失败/返回空时,若 Feed API 拿到了 desc 就直接用 + if feed_desc: + text = feed_desc.strip() + logger.info("抖音所有 ASR 路径均失败,最终使用 Feed desc 作为文案: desc_len=%d", len(text)) + else: + logger.warning("抖音文案提取全部失败: url=%s", page_url) + raise HTTPException( + status_code=status.HTTP_503_SERVICE_UNAVAILABLE, + detail="抖音链接解析暂时不可用,请稍后重试或手动输入文案", + ) return ExtractFromDouyinResponse( text=text,