diff --git a/Docs/DEPLOY_MANUAL.md b/Docs/DEPLOY_MANUAL.md index cb30132..3c2858c 100644 --- a/Docs/DEPLOY_MANUAL.md +++ b/Docs/DEPLOY_MANUAL.md @@ -258,7 +258,32 @@ chmod +x run_latentsync.sh pm2 start ./run_latentsync.sh --name vigent2-latentsync ``` -### 4. 保存当前列表 (开机自启) +### 4. 启动 Qwen3-TTS 声音克隆服务 (可选) + +> 如需使用声音克隆功能,需要启动此服务。 + +1. 安装 HTTP 服务依赖: +```bash +conda activate qwen-tts +pip install fastapi uvicorn python-multipart +``` + +2. 启动脚本位于项目根目录: `run_qwen_tts.sh` + +3. 使用 pm2 启动: +```bash +cd /home/rongye/ProgramFiles/ViGent2 +pm2 start ./run_qwen_tts.sh --name vigent2-qwen-tts +pm2 save +``` + +4. 验证服务: +```bash +# 检查健康状态 +curl http://localhost:8009/health +``` + +### 5. 保存当前列表 (开机自启) ```bash pm2 save @@ -271,6 +296,7 @@ pm2 startup pm2 status # 查看所有服务状态 pm2 logs # 查看所有日志 pm2 logs vigent2-backend # 查看后端日志 +pm2 logs vigent2-qwen-tts # 查看 Qwen3-TTS 日志 pm2 restart all # 重启所有服务 pm2 stop vigent2-latentsync # 停止 LatentSync 服务 pm2 delete all # 删除所有服务 @@ -370,6 +396,7 @@ python3 -c "import torch; print(torch.cuda.is_available())" sudo lsof -i :8006 sudo lsof -i :3002 sudo lsof -i :8007 +sudo lsof -i :8009 # Qwen3-TTS ``` ### 查看日志 @@ -379,6 +406,7 @@ sudo lsof -i :8007 pm2 logs vigent2-backend pm2 logs vigent2-frontend pm2 logs vigent2-latentsync +pm2 logs vigent2-qwen-tts ``` ### SSH 连接卡顿 / 系统响应慢 diff --git a/Docs/DevLogs/Day13.md b/Docs/DevLogs/Day13.md new file mode 100644 index 0000000..efedf24 --- /dev/null +++ b/Docs/DevLogs/Day13.md @@ -0,0 +1,279 @@ +# Day 13 - 声音克隆功能集成完成 + +**日期**:2026-01-29 + +--- + +## 🎙️ Qwen3-TTS 服务集成 + +### 背景 +在 Day 12 完成 Qwen3-TTS 模型部署后,今日重点是将其集成到 ViGent2 系统中,提供完整的声音克隆功能。 + +### 架构设计 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 前端 (Next.js) │ +│ 参考音频上传 → TTS 模式选择 → 视频生成请求 │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ 后端 (FastAPI :8006) │ +│ ref-audios API → voice_clone_service → video_service │ +└─────────────────────────────────────────────────────────────┘ + │ + ▼ +┌─────────────────────────────────────────────────────────────┐ +│ Qwen3-TTS 服务 (FastAPI :8009) │ +│ HTTP /generate → 返回克隆音频 │ +└─────────────────────────────────────────────────────────────┘ +``` + +### Qwen3-TTS HTTP 服务 (`qwen_tts_server.py`) + +创建独立的 FastAPI 服务,运行在 8009 端口: + +```python +from fastapi import FastAPI, UploadFile, Form, HTTPException +from fastapi.responses import Response +import torch +import soundfile as sf +from qwen_tts import Qwen3TTSModel +import io, os + +app = FastAPI(title="Qwen3-TTS Voice Clone Service") + +# GPU 配置 +GPU_ID = os.getenv("QWEN_TTS_GPU_ID", "0") +model = None + +@app.on_event("startup") +async def load_model(): + global model + model = Qwen3TTSModel.from_pretrained( + "./checkpoints/0.6B-Base", + device_map=f"cuda:{GPU_ID}", + dtype=torch.bfloat16, + ) + +@app.get("/health") +async def health(): + return {"service": "Qwen3-TTS", "ready": model is not None, "gpu_id": GPU_ID} + +@app.post("/generate") +async def generate( + ref_audio: UploadFile, + text: str = Form(...), + ref_text: str = Form(""), + language: str = Form("Chinese"), +): + # 保存临时参考音频 + ref_path = f"/tmp/ref_{ref_audio.filename}" + with open(ref_path, "wb") as f: + f.write(await ref_audio.read()) + + # 生成克隆音频 + wavs, sr = model.generate_voice_clone( + text=text, + language=language, + ref_audio=ref_path, + ref_text=ref_text or "一段参考音频。", + ) + + # 返回 WAV 音频 + buffer = io.BytesIO() + sf.write(buffer, wavs[0], sr, format="WAV") + buffer.seek(0) + return Response(content=buffer.read(), media_type="audio/wav") +``` + +### 后端声音克隆服务 (`voice_clone_service.py`) + +通过 HTTP 调用 Qwen3-TTS 服务: + +```python +import aiohttp +from loguru import logger + +QWEN_TTS_URL = "http://localhost:8009" + +async def generate_cloned_audio( + ref_audio_path: str, + text: str, + output_path: str, + ref_text: str = "", +) -> str: + """调用 Qwen3-TTS 服务生成克隆音频""" + + async with aiohttp.ClientSession() as session: + with open(ref_audio_path, "rb") as f: + data = aiohttp.FormData() + data.add_field("ref_audio", f, filename="ref.wav") + data.add_field("text", text) + data.add_field("ref_text", ref_text) + + async with session.post(f"{QWEN_TTS_URL}/generate", data=data) as resp: + if resp.status != 200: + raise Exception(f"Qwen3-TTS error: {resp.status}") + + audio_data = await resp.read() + with open(output_path, "wb") as out: + out.write(audio_data) + + return output_path +``` + +--- + +## 📂 参考音频管理 API + +### 新增 API 端点 (`ref_audios.py`) + +| 端点 | 方法 | 功能 | +|------|------|------| +| `/api/ref-audios` | GET | 获取参考音频列表 | +| `/api/ref-audios` | POST | 上传参考音频 | +| `/api/ref-audios/{id}` | DELETE | 删除参考音频 | + +### Supabase Bucket 配置 + +为参考音频创建独立存储桶: + +```sql +-- 创建 ref-audios bucket +INSERT INTO storage.buckets (id, name, public) +VALUES ('ref-audios', 'ref-audios', true) +ON CONFLICT (id) DO NOTHING; + +-- RLS 策略 +CREATE POLICY "Allow public uploads" ON storage.objects +FOR INSERT TO anon WITH CHECK (bucket_id = 'ref-audios'); + +CREATE POLICY "Allow public read" ON storage.objects +FOR SELECT TO anon USING (bucket_id = 'ref-audios'); + +CREATE POLICY "Allow public delete" ON storage.objects +FOR DELETE TO anon USING (bucket_id = 'ref-audios'); +``` + +--- + +## 🎨 前端声音克隆 UI + +### TTS 模式选择 + +在视频生成页面新增声音克隆选项: + +```tsx +{/* TTS 模式选择 */} +
+ + +
+``` + +### 参考音频管理 + +新增参考音频上传和列表展示功能: + +| 功能 | 实现 | +|------|------| +| 音频上传 | 拖拽上传 WAV/MP3,直传 Supabase | +| 列表展示 | 显示文件名、时长、上传时间 | +| 快速选择 | 点击即选中作为参考音频 | +| 删除功能 | 删除不需要的参考音频 | + +--- + +## ✅ 端到端测试验证 + +### 测试流程 +1. **上传参考音频**: 3 秒参考音频 → Supabase ref-audios bucket +2. **选择声音克隆模式**: TTS 模式切换为 "声音克隆" +3. **输入文案**: 测试口播文案 +4. **生成视频**: + - TTS 阶段调用 Qwen3-TTS (17.7s) + - LipSync 阶段调用 LatentSync (122.8s) +5. **播放验证**: 视频声音与参考音色一致 + +### 测试结果 +- ✅ 参考音频上传成功 +- ✅ Qwen3-TTS 生成克隆音频 (15s 推理,4.6s 音频) +- ✅ LatentSync 唇形同步正常 +- ✅ 总生成时间 143.1s +- ✅ 前端视频播放正常 + +--- + +## 🔧 PM2 服务配置 + +### 新增 Qwen3-TTS 服务 + +**前置依赖安装**: +```bash +conda activate qwen-tts +pip install fastapi uvicorn python-multipart +``` + +启动脚本 `run_qwen_tts.sh` (位于项目**根目录**): +```bash +#!/bin/bash +cd /home/rongye/ProgramFiles/ViGent2/models/Qwen3-TTS +/home/rongye/ProgramFiles/miniconda3/envs/qwen-tts/bin/python qwen_tts_server.py +``` + +PM2 管理命令: +```bash +# 进入根目录启动 +cd /home/rongye/ProgramFiles/ViGent2 +pm2 start ./run_qwen_tts.sh --name vigent2-qwen-tts +pm2 save + +# 查看状态 +pm2 status + +# 查看日志 +pm2 logs vigent2-qwen-tts --lines 50 +``` + +### 完整服务列表 + +| 服务名 | 端口 | 功能 | +|--------|------|------| +| vigent2-backend | 8006 | FastAPI 后端 | +| vigent2-frontend | 3002 | Next.js 前端 | +| vigent2-latentsync | 8007 | LatentSync 唇形同步 | +| vigent2-qwen-tts | 8009 | Qwen3-TTS 声音克隆 | + +--- + +## 📁 今日修改文件清单 + +| 文件 | 变更类型 | 说明 | +|------|----------|------| +| `models/Qwen3-TTS/qwen_tts_server.py` | 新增 | Qwen3-TTS HTTP 推理服务 | +| `run_qwen_tts.sh` | 新增 | PM2 启动脚本 (根目录) | +| `backend/app/services/voice_clone_service.py` | 新增 | 声音克隆服务 (HTTP 调用) | +| `backend/app/api/ref_audios.py` | 新增 | 参考音频管理 API | +| `backend/app/main.py` | 修改 | 注册 ref-audios 路由 | +| `frontend/src/app/page.tsx` | 修改 | TTS 模式选择 + 参考音频 UI | + +--- + +## 🔗 相关文档 + +- [task_complete.md](../task_complete.md) - 任务总览 +- [Day12.md](./Day12.md) - iOS 兼容与 Qwen3-TTS 部署 +- [QWEN3_TTS_DEPLOY.md](../QWEN3_TTS_DEPLOY.md) - Qwen3-TTS 部署指南 +- [DEPLOY_MANUAL.md](../DEPLOY_MANUAL.md) - 完整部署手册 diff --git a/Docs/FRONTEND_DEV.md b/Docs/FRONTEND_DEV.md index f7e04a8..4adb8f5 100644 --- a/Docs/FRONTEND_DEV.md +++ b/Docs/FRONTEND_DEV.md @@ -180,3 +180,52 @@ const formatDate = (timestamp: number) => { 2. [ ] 所有 API 请求使用 `api.get/post/delete()` 而非原生 `fetch` 3. [ ] 日期格式化使用固定格式函数,不用 `toLocaleString()` 4. [ ] 添加 `'use client'` 指令(如需客户端交互) + +--- + +## 声音克隆 (Voice Clone) 功能 + +### API 端点 + +| 接口 | 方法 | 功能 | +|------|------|------| +| `/api/ref-audios` | POST | 上传参考音频 (multipart/form-data: file + ref_text) | +| `/api/ref-audios` | GET | 列出用户的参考音频 | +| `/api/ref-audios/{id}` | DELETE | 删除参考音频 (id 需 encodeURIComponent) | + +### 视频生成 API 扩展 + +```typescript +// EdgeTTS 模式 (默认) +await api.post('/api/videos/generate', { + material_path: '...', + text: '口播文案', + tts_mode: 'edgetts', + voice: 'zh-CN-YunxiNeural', +}); + +// 声音克隆模式 +await api.post('/api/videos/generate', { + material_path: '...', + text: '口播文案', + tts_mode: 'voiceclone', + ref_audio_id: 'user_id/timestamp_name.wav', + ref_text: '参考音频对应文字', +}); +``` + +### 在线录音 + +使用 `MediaRecorder` API 录制音频,格式为 `audio/webm`,上传后后端自动转换为 WAV (16kHz mono)。 + +```typescript +// 录音需要用户授权麦克风 +const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); +const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' }); +``` + +### UI 结构 + +配音方式使用 Tab 切换: +- **EdgeTTS 音色** - 预设音色 2x3 网格 +- **声音克隆** - 参考音频列表 + 在线录音 + 参考文字输入 diff --git a/Docs/Logs.md b/Docs/Logs.md index 8cf5efd..2a0ea8b 100644 --- a/Docs/Logs.md +++ b/Docs/Logs.md @@ -1,29 +1,333 @@ -rongye@r730-ubuntu:~/ProgramFiles/Supabase$ docker compose up -d -[+] up 136/136 - ✔ Image timberio/vector:0.28.1-alpine Pulled 63.3ss - ✔ Image supabase/storage-api:v1.33.0 Pulled 78.6ss - ✔ Image darthsim/imgproxy:v3.30.1 Pulled 151.9s - ✔ Image supabase/postgres-meta:v0.95.1 Pulled 87.5ss - ✔ Image supabase/logflare:1.27.0 Pulled 229.2s - ✔ Image supabase/postgres:15.8.1.085 Pulled 268.3s - ✔ Image supabase/supavisor:2.7.4 Pulled 101.6s - ✔ Image supabase/realtime:v2.68.0 Pulled 56.5ss - ✔ Image postgrest/postgrest:v14.1 Pulled 201.8s - ✔ Image supabase/edge-runtime:v1.69.28 Pulled 254.0s - ✔ Network supabase_default Created 0.1s - ✔ Volume supabase_db-config Created 0.1s - ✔ Container supabase-vector Healthy 16.9s - ✔ Container supabase-imgproxy Created 7.4s - ✔ Container supabase-db Healthy 20.6s - ✔ Container supabase-analytics Created 0.4s - ✔ Container supabase-edge-functions Created 1.8s - ✔ Container supabase-auth Created 1.7s - ✔ Container supabase-studio Created 2.0s - ✔ Container realtime-dev.supabase-realtime Created 1.7s - ✔ Container supabase-pooler Created 1.8s - ✔ Container supabase-kong Created 1.7s - ✔ Container supabase-meta Created 2.0s - ✔ Container supabase-rest Created 0.9s - ✔ Container supabase-storage Created 1.4s -Error response from daemon: failed to set up container networking: driver failed programming external connectivity on endpoint supabase-analytics (2fd60a510a1f16bf29f8f5140f14ef457a284c5b65a2567b7be250a4f9708f34): failed to bind host port 0.0.0.0:4000/tcp: address already in use -[ble: exit 1] \ No newline at end of file +rongye@r730-ubuntu:~$ pm2 logs vigent2-qwen-tts +[TAILING] Tailing last 15 lines for [vigent2-qwen-tts] process (change the value with --lines option) +/home/rongye/.pm2/logs/vigent2-qwen-tts-error.log last 15 lines: +13|vigent2 | Setting `pad_token_id` to `eos_token_id`:2150 for open-end generation. + +/home/rongye/.pm2/logs/vigent2-qwen-tts-out.log last 15 lines: +13|vigent2 | 🔄 Loading Qwen3-TTS model... +13|vigent2 | +13|vigent2 | ******** +13|vigent2 | Warning: flash-attn is not installed. Will only run the manual PyTorch version. Please install flash-attn for faster inference. +13|vigent2 | ******** +13|vigent2 | +13|vigent2 | ✅ Qwen3-TTS model loaded in 8.6s +13|vigent2 | INFO: 127.0.0.1:56814 - "GET /health HTTP/1.1" 200 OK +13|vigent2 | 🎤 Generating: 大家好,欢迎来到我的频道,今天给大家分享一些有趣的内容。... +13|vigent2 | 📝 Ref text: 其实生活中有许多美好的瞬间,比如清晨的阳光,或者一杯温热的清茶。希望这次生成的音色能够自然、流畅,完... +13|vigent2 | [WARNING] Min value of input waveform signal is -1.006709337234497 +13|vigent2 | [WARNING] Max value of input waveform signal is 1.0008893013000488 +13|vigent2 | ✅ Generated in 15.0s, duration: 4.6s +13|vigent2 | INFO: 127.0.0.1:36556 - "POST /generate HTTP/1.1" 200 OK + + + + +rongye@r730-ubuntu:~$ pm2 logs vigent2-backend --lines 400 +[TAILING] Tailing last 400 lines for [vigent2-backend] process (change the value with --lines option) +/home/rongye/.pm2/logs/vigent2-backend-out.log last 400 lines: +11|vigent2 | Storage endpoint URL should have a trailing slash. +11|vigent2 | Storage endpoint URL should have a trailing slash. +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769651820268 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769651825016 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/publish/accounts HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769651828852 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769654501430 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769654987404 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/ref-audios HTTP/1.1" 500 Internal Server Error +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769655093628 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/ref-audios HTTP/1.1" 500 Internal Server Error +11|vigent2 | Storage endpoint URL should have a trailing slash. +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769655569331 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/videos/generate HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | [Pipeline] TTS completed in 17.7s +11|vigent2 | [LipSync] Health check: ready=True +11|vigent2 | [LipSync] Starting LatentSync inference... +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | [Pipeline] LipSync completed in 122.8s +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | [Pipeline] Total generation time: 143.1s +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/tasks/bf4760b8-e338-49ee-9777-828c1ef0c855 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/publish/accounts HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769655769762 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/publish/accounts HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769655923194 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769655960629 HTTP/1.1" 403 Forbidden +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 403 Forbidden +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 403 Forbidden +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/auth/logout HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/auth/login HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769655964287 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/publish/accounts HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 403 Forbidden +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/auth/logout HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/publish/accounts HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/auth/login HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769656015718 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769656233290 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "POST /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/publish/accounts HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769656987465 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/materials?t=1769657141569 HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/videos/generated HTTP/1.1" 200 OK +11|vigent2 | INFO: 27.17.161.128:0 - "GET /api/ref-audios HTTP/1.1" 200 OK + +/home/rongye/.pm2/logs/vigent2-backend-error.log last 400 lines: +11|vigent2 | rnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:00.756 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:06:00.757 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-fetch-dest': 'empty', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1', 'accept': 'application/json, text/plain, */*', 'referer': 'https://vigent.hbyrkj.top/', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'accept-language': 'en-US,en;q=0.9', 'priority': 'u=3, i', 'accept-encoding': 'gzip, deflate, br', 'cookie': 'access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiN2JlNWIzNWYtMzQ0Ni00ZTIyLWEzMTktZTc5M2NlNDBmYTRiIiwiZXhwIjoxNzcwMTc4MTE0fQ.pk4sCAkd9hcN6fE5_8RXH42zfMl7YPSV5i1R9QeER4s; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1760758482696%2C%220199f562-16c1-7fcb-9bef-fdc33838b6a8%22%2C1760758470336%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_session=RudderEncrypt%3AU2FsdGVkX19ssBuVw9hBTDRVrnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:00.765 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/ref-audios - Status: 403 - Duration: 0.02s +11|vigent2 | 2026-01-29 11:06:00.766 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 403 - Duration: 0.01s +11|vigent2 | 2026-01-29 11:06:00.812 | INFO | app.main:dispatch:21 - START Request: POST https://vigent.hbyrkj.top/api/auth/logout +11|vigent2 | 2026-01-29 11:06:00.812 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'content-length': '0', 'accept': '*/*', 'sec-fetch-site': 'same-origin', 'origin': 'https://vigent.hbyrkj.top', 'sec-fetch-mode': 'cors', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1', 'referer': 'https://vigent.hbyrkj.top/', 'sec-fetch-dest': 'empty', 'accept-language': 'en-US,en;q=0.9', 'priority': 'u=3, i', 'accept-encoding': 'gzip, deflate, br', 'cookie': 'access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiN2JlNWIzNWYtMzQ0Ni00ZTIyLWEzMTktZTc5M2NlNDBmYTRiIiwiZXhwIjoxNzcwMTc4MTE0fQ.pk4sCAkd9hcN6fE5_8RXH42zfMl7YPSV5i1R9QeER4s; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1760758482696%2C%220199f562-16c1-7fcb-9bef-fdc33838b6a8%22%2C1760758470336%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_session=RudderEncrypt%3AU2FsdGVkX19ssBuVw9hBTDRVrnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:00.815 | INFO | app.main:dispatch:26 - END Request: POST https://vigent.hbyrkj.top/api/auth/logout - Status: 200 - Duration: 0.00s +11|vigent2 | 2026-01-29 11:06:03.694 | INFO | app.main:dispatch:21 - START Request: POST https://vigent.hbyrkj.top/api/auth/login +11|vigent2 | 2026-01-29 11:06:03.695 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'content-length': '58', 'accept': '*/*', 'content-type': 'application/json', 'sec-fetch-site': 'same-origin', 'origin': 'https://vigent.hbyrkj.top', 'sec-fetch-mode': 'cors', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1', 'referer': 'https://vigent.hbyrkj.top/login', 'sec-fetch-dest': 'empty', 'accept-language': 'en-US,en;q=0.9', 'priority': 'u=3, i', 'accept-encoding': 'gzip, deflate, br', 'cookie': 'ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1760758482696%2C%220199f562-16c1-7fcb-9bef-fdc33838b6a8%22%2C1760758470336%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_session=RudderEncrypt%3AU2FsdGVkX19ssBuVw9hBTDRVrnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:04.185 | INFO | app.api.auth:login:157 - 用户登录: lamnickdavid@gmail.com +11|vigent2 | 2026-01-29 11:06:04.185 | INFO | app.main:dispatch:26 - END Request: POST https://vigent.hbyrkj.top/api/auth/login - Status: 200 - Duration: 0.49s +11|vigent2 | 2026-01-29 11:06:04.359 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/materials?t=1769655964287 +11|vigent2 | 2026-01-29 11:06:04.359 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-fetch-dest': 'empty', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1', 'accept': 'application/json, text/plain, */*', 'referer': 'https://vigent.hbyrkj.top/', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'accept-language': 'en-US,en;q=0.9', 'priority': 'u=3, i', 'accept-encoding': 'gzip, deflate, br', 'cookie': 'access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMWE0NzczNTktZmMwZS00MjVhLTk3MGUtODc1ZTcyNjFjYWJiIiwiZXhwIjoxNzcwMjYwNzY0fQ.X-nGjaX_gwaJw995Zuw_fnj2oY_K-oM6tgwMDR4pDQk; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1760758482696%2C%220199f562-16c1-7fcb-9bef-fdc33838b6a8%22%2C1760758470336%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_session=RudderEncrypt%3AU2FsdGVkX19ssBuVw9hBTDRVrnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:04.377 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/ref-audios +11|vigent2 | 2026-01-29 11:06:04.377 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-fetch-dest': 'empty', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1', 'accept': 'application/json, text/plain, */*', 'referer': 'https://vigent.hbyrkj.top/', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'accept-language': 'en-US,en;q=0.9', 'priority': 'u=3, i', 'accept-encoding': 'gzip, deflate, br', 'cookie': 'access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMWE0NzczNTktZmMwZS00MjVhLTk3MGUtODc1ZTcyNjFjYWJiIiwiZXhwIjoxNzcwMjYwNzY0fQ.X-nGjaX_gwaJw995Zuw_fnj2oY_K-oM6tgwMDR4pDQk; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1760758482696%2C%220199f562-16c1-7fcb-9bef-fdc33838b6a8%22%2C1760758470336%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_session=RudderEncrypt%3AU2FsdGVkX19ssBuVw9hBTDRVrnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:04.392 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:06:04.392 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-fetch-dest': 'empty', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1', 'accept': 'application/json, text/plain, */*', 'referer': 'https://vigent.hbyrkj.top/', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'accept-language': 'en-US,en;q=0.9', 'priority': 'u=3, i', 'accept-encoding': 'gzip, deflate, br', 'cookie': 'access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMWE0NzczNTktZmMwZS00MjVhLTk3MGUtODc1ZTcyNjFjYWJiIiwiZXhwIjoxNzcwMjYwNzY0fQ.X-nGjaX_gwaJw995Zuw_fnj2oY_K-oM6tgwMDR4pDQk; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1760758482696%2C%220199f562-16c1-7fcb-9bef-fdc33838b6a8%22%2C1760758470336%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_session=RudderEncrypt%3AU2FsdGVkX19ssBuVw9hBTDRVrnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:04.478 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/materials?t=1769655964287 - Status: 200 - Duration: 0.12s +11|vigent2 | 2026-01-29 11:06:04.491 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 200 - Duration: 0.10s +11|vigent2 | 2026-01-29 11:06:04.614 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/ref-audios - Status: 200 - Duration: 0.24s +11|vigent2 | 2026-01-29 11:06:16.329 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/publish/accounts +11|vigent2 | 2026-01-29 11:06:16.329 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/publish', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiNDk2N2QwNjMtNjhhZC00NzFkLThhMWQtOGE1MmJhODAxZjBjIiwiZXhwIjoxNzcwMTc4MzM4fQ.k9JOPKwqHrNTTNOsUQlMuA63rOETStl7uWXAIIDLGtA'} +11|vigent2 | 2026-01-29 11:06:16.333 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:06:16.333 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/publish', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiNDk2N2QwNjMtNjhhZC00NzFkLThhMWQtOGE1MmJhODAxZjBjIiwiZXhwIjoxNzcwMTc4MzM4fQ.k9JOPKwqHrNTTNOsUQlMuA63rOETStl7uWXAIIDLGtA'} +11|vigent2 | 2026-01-29 11:06:16.342 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/publish/accounts - Status: 200 - Duration: 0.01s +11|vigent2 | 2026-01-29 11:06:16.343 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 403 - Duration: 0.01s +11|vigent2 | 2026-01-29 11:06:16.397 | INFO | app.main:dispatch:21 - START Request: POST https://vigent.hbyrkj.top/api/auth/logout +11|vigent2 | 2026-01-29 11:06:16.397 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'content-length': '0', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'accept': '*/*', 'origin': 'https://vigent.hbyrkj.top', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/publish', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiNDk2N2QwNjMtNjhhZC00NzFkLThhMWQtOGE1MmJhODAxZjBjIiwiZXhwIjoxNzcwMTc4MzM4fQ.k9JOPKwqHrNTTNOsUQlMuA63rOETStl7uWXAIIDLGtA'} +11|vigent2 | 2026-01-29 11:06:16.398 | INFO | app.main:dispatch:26 - END Request: POST https://vigent.hbyrkj.top/api/auth/logout - Status: 200 - Duration: 0.00s +11|vigent2 | 2026-01-29 11:06:28.685 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:06:28.686 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-fetch-dest': 'empty', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1', 'accept': 'application/json, text/plain, */*', 'referer': 'https://vigent.hbyrkj.top/publish', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'accept-language': 'en-US,en;q=0.9', 'priority': 'u=3, i', 'accept-encoding': 'gzip, deflate, br', 'cookie': 'access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMWE0NzczNTktZmMwZS00MjVhLTk3MGUtODc1ZTcyNjFjYWJiIiwiZXhwIjoxNzcwMjYwNzY0fQ.X-nGjaX_gwaJw995Zuw_fnj2oY_K-oM6tgwMDR4pDQk; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1760758482696%2C%220199f562-16c1-7fcb-9bef-fdc33838b6a8%22%2C1760758470336%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_session=RudderEncrypt%3AU2FsdGVkX19ssBuVw9hBTDRVrnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:28.704 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/publish/accounts +11|vigent2 | 2026-01-29 11:06:28.705 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-fetch-dest': 'empty', 'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.2 Mobile/15E148 Safari/604.1', 'accept': 'application/json, text/plain, */*', 'referer': 'https://vigent.hbyrkj.top/publish', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'accept-language': 'en-US,en;q=0.9', 'priority': 'u=3, i', 'accept-encoding': 'gzip, deflate, br', 'cookie': 'access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMWE0NzczNTktZmMwZS00MjVhLTk3MGUtODc1ZTcyNjFjYWJiIiwiZXhwIjoxNzcwMjYwNzY0fQ.X-nGjaX_gwaJw995Zuw_fnj2oY_K-oM6tgwMDR4pDQk; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1760758482696%2C%220199f562-16c1-7fcb-9bef-fdc33838b6a8%22%2C1760758470336%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_session=RudderEncrypt%3AU2FsdGVkX19ssBuVw9hBTDRVrnPaKCW6D20R7A4QpeumwXIRUkzHtaFASP40bWfE6KL05g4rq6VbZFQ9X4FVBZ2lbwW%2Faa32knjuye8aa1ejtZEGmyfXpfcryezEIy0gmYYjjT7lKB6HAupj9%2FCezQ%3D%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX1%2BpEG8yoPZBpac674EsBSuEU0HhlEZGMLIKNfviY6GGLzzbk6%2BbdfmzJ5s1nr16B0NNWzywMDwDD00Cktdf8N50BWw0Pp7Xuy2cOM6L15tjqobzRZyayXyVA1o%2B5kHPODaa3yg4cjWjee8OqG1qRaX4EwOXc0YzPZI%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX1%2BRY4oSsXW07D0HdYfXZhDpJS%2Fl%2F%2Bysns8Xand%2BMI7%2FJBIRw1RV%2FIJPzbTSpW8kmvwLCsUosyNPtsZbl3lGRDOM4YJIL%2BaFVjvjAWDo0WA89ezEeTVY9hzd9rwV3A6dbv5vJhrEdjolAkub50ItC47iV1fIGb%2FN3vI%3D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19r9Vr3ov%2BP30OgbarNSaCn6bebg11iU%2B8UV7b%2F116JurvSpJ77d%2FdZ62kjIP%2BMF3h3R9RathLKFQ%3D%3D; rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX19CE%2F3GmyTsZHCQhdFWdzYnJYPdvCMBFbM%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX18t2%2FxrnN2HPEqTssR572nq%2FgCim9EQN7E%3D'} +11|vigent2 | 2026-01-29 11:06:28.710 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/publish/accounts - Status: 200 - Duration: 0.01s +11|vigent2 | 2026-01-29 11:06:28.745 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 200 - Duration: 0.06s +11|vigent2 | 2026-01-29 11:06:51.021 | INFO | app.main:dispatch:21 - START Request: POST https://vigent.hbyrkj.top/api/auth/login +11|vigent2 | 2026-01-29 11:06:51.021 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'content-length': '58', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'content-type': 'application/json', 'sec-ch-ua-mobile': '?0', 'accept': '*/*', 'origin': 'https://vigent.hbyrkj.top', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/login', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D'} +11|vigent2 | 2026-01-29 11:06:51.624 | INFO | app.api.auth:login:157 - 用户登录: lamnickdavid@gmail.com +11|vigent2 | 2026-01-29 11:06:51.625 | INFO | app.main:dispatch:26 - END Request: POST https://vigent.hbyrkj.top/api/auth/login - Status: 200 - Duration: 0.60s +11|vigent2 | 2026-01-29 11:06:51.806 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/materials?t=1769656015718 +11|vigent2 | 2026-01-29 11:06:51.806 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:06:51.820 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:06:51.821 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:06:51.834 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/ref-audios +11|vigent2 | 2026-01-29 11:06:51.834 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:06:51.865 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/materials?t=1769656015718 - Status: 200 - Duration: 0.06s +11|vigent2 | 2026-01-29 11:06:51.941 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 200 - Duration: 0.12s +11|vigent2 | 2026-01-29 11:06:52.076 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/ref-audios - Status: 200 - Duration: 0.24s +11|vigent2 | 2026-01-29 11:10:29.354 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/materials?t=1769656233290 +11|vigent2 | 2026-01-29 11:10:29.354 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:10:29.405 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/ref-audios +11|vigent2 | 2026-01-29 11:10:29.406 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:10:29.423 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:10:29.423 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:10:29.474 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/materials?t=1769656233290 - Status: 200 - Duration: 0.12s +11|vigent2 | 2026-01-29 11:10:29.535 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 200 - Duration: 0.11s +11|vigent2 | 2026-01-29 11:10:29.653 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/ref-audios - Status: 200 - Duration: 0.25s +11|vigent2 | 2026-01-29 11:11:20.032 | INFO | app.main:dispatch:21 - START Request: POST https://vigent.hbyrkj.top/api/ref-audios +11|vigent2 | 2026-01-29 11:11:20.032 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'content-length': '204514', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'content-type': 'multipart/form-data; boundary=----WebKitFormBoundaryBGjf99CuOGlQdB7a', 'sec-ch-ua-mobile': '?0', 'origin': 'https://vigent.hbyrkj.top', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:11:20.536 | INFO | app.services.storage:upload_file:97 - Storage upload success: 94cd91e3-7d89-45e8-9d85-e8ba0660d74c/1769656280_myvoice.wav +11|vigent2 | 2026-01-29 11:11:20.576 | INFO | app.services.storage:upload_file:97 - Storage upload success: 94cd91e3-7d89-45e8-9d85-e8ba0660d74c/1769656280_myvoice.json +11|vigent2 | 2026-01-29 11:11:20.584 | INFO | app.main:dispatch:26 - END Request: POST https://vigent.hbyrkj.top/api/ref-audios - Status: 200 - Duration: 0.55s +11|vigent2 | 2026-01-29 11:11:20.638 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/ref-audios +11|vigent2 | 2026-01-29 11:11:20.638 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:11:21.086 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/ref-audios - Status: 200 - Duration: 0.45s +11|vigent2 | 2026-01-29 11:22:58.683 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:22:58.684 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/publish', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:22:58.742 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/publish/accounts +11|vigent2 | 2026-01-29 11:22:58.743 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/publish', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:22:58.747 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/publish/accounts - Status: 200 - Duration: 0.01s +11|vigent2 | 2026-01-29 11:22:58.798 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 200 - Duration: 0.11s +11|vigent2 | 2026-01-29 11:23:03.509 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/materials?t=1769656987465 +11|vigent2 | 2026-01-29 11:23:03.510 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:23:03.535 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:23:03.535 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:23:03.551 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/ref-audios +11|vigent2 | 2026-01-29 11:23:03.552 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:23:03.569 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/materials?t=1769656987465 - Status: 200 - Duration: 0.06s +11|vigent2 | 2026-01-29 11:23:03.658 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 200 - Duration: 0.12s +11|vigent2 | 2026-01-29 11:23:03.996 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/ref-audios - Status: 200 - Duration: 0.44s +11|vigent2 | 2026-01-29 11:25:37.605 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/ref-audios +11|vigent2 | 2026-01-29 11:25:37.605 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:25:37.653 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/materials?t=1769657141569 +11|vigent2 | 2026-01-29 11:25:37.653 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:25:37.673 | INFO | app.main:dispatch:21 - START Request: GET https://vigent.hbyrkj.top/api/videos/generated +11|vigent2 | 2026-01-29 11:25:37.674 | INFO | app.main:dispatch:22 - HEADERS: {'connection': 'upgrade', 'host': 'vigent.hbyrkj.top', 'x-real-ip': '27.17.161.128', 'x-forwarded-for': '27.17.161.128', 'x-forwarded-proto': 'https', 'sec-ch-ua-platform': '"Windows"', 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36', 'accept': 'application/json, text/plain, */*', 'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Google Chrome";v="144"', 'sec-ch-ua-mobile': '?0', 'sec-fetch-site': 'same-origin', 'sec-fetch-mode': 'cors', 'sec-fetch-dest': 'empty', 'referer': 'https://vigent.hbyrkj.top/', 'accept-encoding': 'gzip, deflate, br, zstd', 'accept-language': 'en-US,en;q=0.9,zh;q=0.8,zh-CN;q=0.7', 'priority': 'u=1, i', 'cookie': 'rl_page_init_referrer=RudderEncrypt%3AU2FsdGVkX1%2FRWtsIwIaguDp15em58SDrIwOvRJVXeK4%3D; rl_page_init_referring_domain=RudderEncrypt%3AU2FsdGVkX1%2BVZN6tniQmiO5L2fGVdcrYOkqG%2BRHkNFw%3D; ph_phc_4URIAm1uYfJO7j8kWSe0J8lc8IqnstRLS7Jx8NcakHo_posthog=%7B%22distinct_id%22%3A%22f6a1ba3602218bc1551bb81b48167bf7484eeb86ed8ee9484fa83f1267023264%230d2437ec-d81b-491c-991f-0b6559daa00d%22%2C%22%24sesid%22%3A%5B1762504332341%2C%22019a5d6c-ae21-7d75-8919-11e9621a135f%22%2C1762503994906%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22%24direct%22%2C%22u%22%3A%22https%3A%2F%2Fn8n.hbyrkj.top%2Fsignin%3Fredirect%3D%25252F%22%7D%7D; rl_anonymous_id=RudderEncrypt%3AU2FsdGVkX19aTpWYcHFt3zhITFSLk1XAMr9V2jBWQwsuLDNLXh93pTlQ%2FUpvwmv6h%2Fl1bW4xH83hrkWPCTkSYg%3D%3D; rl_group_id=RudderEncrypt%3AU2FsdGVkX1%2BhywVlN3t3ypqwAMgqlh7ZRNLMKnFMhxA%3D; rl_group_trait=RudderEncrypt%3AU2FsdGVkX19jAKNOmR%2FnSngsWGVcmYB2qyvsbh3wQc0%3D; rl_user_id=RudderEncrypt%3AU2FsdGVkX180hU8QtHwPe3dPd1o7rEP7efRzFgCIvuIPRwbE3dWE0aEQCCMpQTN%2B7AGEtH6mjRvEuqcbfOdaX4TtJGL2jHbdcZUuA7Mpjf0uvsZ15LToi0zM1NWR7i6wE2z4vcYyFaBdB1uTJq3SxhX2WsqWe4YiT12vld0E%2F5w%3D; rl_trait=RudderEncrypt%3AU2FsdGVkX19tgs8QN46oDejOzAvFyTx%2FIVRu7LAGDzh2eg%2FAhV8eY%2FyjW12D%2BtSOVq6NLF2lSZcY40rlQ%2B1fUc3DAe2euuWhIECOtlxtY5Hho11ZdHGB8lZ4CSLo%2BWmSIjzmkQ33RgkeNF9eYV4AV1PpdZZ%2Fjyl%2BVjCQtaNVV5c%3D; rl_session=RudderEncrypt%3AU2FsdGVkX19jm82pV3xfWHI%2FE6QaUo5xFQZuXuYh%2FkUCBhyJGY7TqzAK3YDkYppIpUipS7LtUSxm6iWAAp3vGhbB58MN7hrVa8imlwsuL7ceFNN%2BR1uTEvKTR8wWKaii2Xzs%2FYnhG3X8kmImIfYZgg%3D%3D; access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI5NGNkOTFlMy03ZDg5LTQ1ZTgtOWQ4NS1lOGJhMDY2MGQ3NGMiLCJzZXNzaW9uX3Rva2VuIjoiMjFjMmEwMmItYjY5Ny00MGVjLWIwMmItMjI1YzJjOWUyZGMzIiwiZXhwIjoxNzcwMjYwODExfQ.MpOjnbwllAzarfaoTk1SzYVMqAEXBEMyRt5UyiJ90Qw'} +11|vigent2 | 2026-01-29 11:25:37.781 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/materials?t=1769657141569 - Status: 200 - Duration: 0.13s +11|vigent2 | 2026-01-29 11:25:37.792 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/videos/generated - Status: 200 - Duration: 0.12s +11|vigent2 | 2026-01-29 11:25:38.087 | INFO | app.main:dispatch:26 - END Request: GET https://vigent.hbyrkj.top/api/ref-audios - Status: 200 - Duration: 0.48s + + + + + +rongye@r730-ubuntu:~$ pm2 logs vigent2-latentsync +[TAILING] Tailing last 15 lines for [vigent2-latentsync] process (change the value with --lines option) +/home/rongye/.pm2/logs/vigent2-latentsync-out.log last 15 lines: +/home/rongye/.pm2/logs/vigent2-latentsync-error.log last 15 lines: \ No newline at end of file diff --git a/Docs/QWEN3_TTS_DEPLOY.md b/Docs/QWEN3_TTS_DEPLOY.md index b37e970..14bda2e 100644 --- a/Docs/QWEN3_TTS_DEPLOY.md +++ b/Docs/QWEN3_TTS_DEPLOY.md @@ -169,24 +169,106 @@ python test_inference.py --- +## 步骤 6: 安装 HTTP 服务依赖 + +```bash +conda activate qwen-tts +pip install fastapi uvicorn python-multipart +``` + +--- + +## 步骤 7: 启动服务 (PM2 管理) + +### 手动测试 + +```bash +conda activate qwen-tts +cd /home/rongye/ProgramFiles/ViGent2/models/Qwen3-TTS +python qwen_tts_server.py +``` + +访问 http://localhost:8009/health 验证服务状态。 + +### PM2 常驻服务 + +> ⚠️ **注意**:启动脚本 `run_qwen_tts.sh` 位于项目**根目录**,而非 models/Qwen3-TTS 目录。 + +1. 使用启动脚本: +```bash +cd /home/rongye/ProgramFiles/ViGent2 +pm2 start ./run_qwen_tts.sh --name vigent2-qwen-tts +pm2 save +``` + +2. 查看日志: +```bash +pm2 logs vigent2-qwen-tts +``` + +3. 重启服务: +```bash +pm2 restart vigent2-qwen-tts +``` + +--- + ## 目录结构 部署完成后,目录结构应如下: ``` -/home/rongye/ProgramFiles/ViGent2/models/Qwen3-TTS/ -├── checkpoints/ -│ ├── Tokenizer/ # 语音编解码器 -│ └── 0.6B-Base/ # 声音克隆模型 -├── qwen_tts/ # 源码 -│ ├── inference/ -│ ├── models/ -│ └── ... -├── examples/ -│ └── myvoice.wav # 参考音频 -├── pyproject.toml -├── requirements.txt -└── test_inference.py # 测试脚本 +/home/rongye/ProgramFiles/ViGent2/ +├── run_qwen_tts.sh # PM2 启动脚本 (根目录) +└── models/Qwen3-TTS/ + ├── checkpoints/ + │ ├── Tokenizer/ # 语音编解码器 + │ └── 0.6B-Base/ # 声音克隆模型 + ├── qwen_tts/ # 源码 + │ ├── inference/ + │ ├── models/ + │ └── ... + ├── examples/ + │ └── myvoice.wav # 参考音频 + ├── qwen_tts_server.py # HTTP 推理服务 (端口 8009) + ├── pyproject.toml + ├── requirements.txt + └── test_inference.py # 测试脚本 +``` + +--- + +## API 参考 + +### 健康检查 + +``` +GET http://localhost:8009/health +``` + +响应: +```json +{ + "service": "Qwen3-TTS Voice Clone", + "model": "0.6B-Base", + "ready": true, + "gpu_id": 0 +} +``` + +### 声音克隆生成 + +``` +POST http://localhost:8009/generate +Content-Type: multipart/form-data + +Fields: + - ref_audio: 参考音频文件 (WAV) + - text: 要合成的文本 + - ref_text: 参考音频的转写文字 + - language: 语言 (默认 Chinese) + +Response: audio/wav 文件 ``` --- @@ -244,6 +326,46 @@ Qwen3-TTS 0.6B 通常只需要 4-6GB VRAM。如果遇到 OOM: --- +## 后端 ViGent2 集成 + +### 声音克隆服务 (`voice_clone_service.py`) + +后端通过 HTTP 调用 Qwen3-TTS 服务: + +```python +import aiohttp + +QWEN_TTS_URL = "http://localhost:8009" + +async def generate_cloned_audio(ref_audio_path: str, text: str, output_path: str): + async with aiohttp.ClientSession() as session: + with open(ref_audio_path, "rb") as f: + data = aiohttp.FormData() + data.add_field("ref_audio", f, filename="ref.wav") + data.add_field("text", text) + + async with session.post(f"{QWEN_TTS_URL}/generate", data=data) as resp: + audio_data = await resp.read() + with open(output_path, "wb") as out: + out.write(audio_data) + return output_path +``` + +### 参考音频 Supabase Bucket + +```sql +-- 创建 ref-audios bucket +INSERT INTO storage.buckets (id, name, public) +VALUES ('ref-audios', 'ref-audios', true) +ON CONFLICT (id) DO NOTHING; + +-- RLS 策略 +CREATE POLICY "Allow public uploads" ON storage.objects +FOR INSERT TO anon WITH CHECK (bucket_id = 'ref-audios'); +``` + +--- + ## 参考链接 - [Qwen3-TTS GitHub](https://github.com/QwenLM/Qwen3-TTS) @@ -251,3 +373,4 @@ Qwen3-TTS 0.6B 通常只需要 4-6GB VRAM。如果遇到 OOM: - [HuggingFace 模型](https://huggingface.co/collections/Qwen/qwen3-tts) - [技术报告](https://arxiv.org/abs/2601.15621) - [官方博客](https://qwen.ai/blog?id=qwen3tts-0115) + diff --git a/Docs/implementation_plan.md b/Docs/implementation_plan.md index 283d0a7..de16596 100644 --- a/Docs/implementation_plan.md +++ b/Docs/implementation_plan.md @@ -47,7 +47,7 @@ | **任务队列** | Celery + Redis | RQ / Dramatiq | | **唇形同步** | **LatentSync 1.6** | MuseTalk / Wav2Lip | | **TTS 配音** | EdgeTTS | CosyVoice | -| **声音克隆** | GPT-SoVITS (可选) | - | +| **声音克隆** | **Qwen3-TTS 0.6B** ✅ | GPT-SoVITS | | **视频处理** | FFmpeg | MoviePy | | **自动发布** | social-auto-upload | 自行实现 | | **数据库** | SQLite → PostgreSQL | MySQL | @@ -323,6 +323,17 @@ cp -r SuperIPAgent/social-auto-upload backend/social_upload - [x] 端口冲突解决 (3003/8008/8444) - [x] Basic Auth 管理后台保护 +### 阶段十七:声音克隆功能集成 (Day 13) ✅ + +> **目标**:实现用户自定义声音克隆能力 + +- [x] Qwen3-TTS HTTP 服务 (独立 FastAPI,端口 8009) +- [x] 声音克隆服务封装 (voice_clone_service.py) +- [x] 参考音频管理 API (上传/列表/删除) +- [x] 前端 TTS 模式选择 UI +- [x] Supabase ref-audios Bucket 配置 +- [x] 端到端测试验证 + --- ## 项目目录结构 (最终) diff --git a/Docs/serene-conjuring-volcano.md b/Docs/serene-conjuring-volcano.md new file mode 100644 index 0000000..35d3b59 --- /dev/null +++ b/Docs/serene-conjuring-volcano.md @@ -0,0 +1,220 @@ +# Qwen3-TTS 声音克隆集成到 ViGent2 + +## 需求概述 +1. 前端支持上传/在线录制参考音频(wav, mp3, m4a 等) +2. EdgeTTS 音色保留,增加 Qwen3-TTS 声音克隆界面 +3. 两种 TTS 方式做成统一界面(Tab 切换) +4. 声音克隆使用相同的口播文案输入 + +## 架构设计 + +### GPU 分配 +| GPU | 服务 | 模型 | +|-----|------|------| +| GPU0 | Qwen3-TTS | 0.6B-Base (声音克隆) | +| GPU1 | LatentSync | 1.6 (唇形同步) | + +### 存储 +- 新增 Supabase bucket: `ref_audios` +- 路径格式: `{user_id}/{timestamp}_{filename}.wav` + +--- + +## 实现步骤 + +### 1. 后端:新建声音克隆服务 +**文件**: `backend/app/services/voice_clone_service.py` + +```python +class VoiceCloneService: + def __init__(self): + self.gpu_id = 0 + self.model_path = "models/Qwen3-TTS/checkpoints/0.6B-Base" + self._model = None + self._lock = asyncio.Lock() + + async def generate_audio(self, text, ref_audio_path, ref_text, output_path, language="Chinese"): + # 使用 Qwen3TTSModel.generate_voice_clone() +``` + +### 2. 后端:新建参考音频 API +**文件**: `backend/app/api/ref_audios.py` + +| 接口 | 方法 | 功能 | +|------|------|------| +| `/api/ref-audios` | POST | 上传参考音频 + ref_text | +| `/api/ref-audios` | GET | 列出用户的参考音频 | +| `/api/ref-audios/{id}` | DELETE | 删除参考音频 | + +上传时自动转换为 wav (16kHz mono),存储 ref_text 元数据。 + +### 3. 后端:修改视频生成 API +**文件**: `backend/app/api/videos.py` + +扩展 GenerateRequest: +```python +class GenerateRequest(BaseModel): + text: str + voice: str = "zh-CN-YunxiNeural" + material_path: str + # 新增 + tts_mode: str = "edgetts" # "edgetts" | "voiceclone" + ref_audio_id: Optional[str] = None + ref_text: Optional[str] = None +``` + +修改 `_process_video_generation()`: +```python +if req.tts_mode == "voiceclone": + await voice_clone_service.generate_audio(...) +else: + await tts_service.generate_audio(...) +``` + +### 4. 后端:注册路由 +**文件**: `backend/app/main.py` + +```python +from app.api import ref_audios +app.include_router(ref_audios.router, prefix="/api/ref-audios", tags=["ref-audios"]) +``` + +### 5. 前端:改造音色选择区域 +**文件**: `frontend/src/app/page.tsx` + +**新增状态**: +```typescript +const [ttsMode, setTtsMode] = useState<'edgetts' | 'voiceclone'>('edgetts'); +const [refAudios, setRefAudios] = useState([]); +const [selectedRefAudio, setSelectedRefAudio] = useState(null); +const [refText, setRefText] = useState(''); + +// 在线录音相关 +const [isRecording, setIsRecording] = useState(false); +const [recordedBlob, setRecordedBlob] = useState(null); +const [recordingTime, setRecordingTime] = useState(0); +const mediaRecorderRef = useRef(null); +``` + +**UI 结构**: +``` +┌─────────────────────────────────────┐ +│ 🎙️ 选择配音方式 │ +├─────────────────────────────────────┤ +│ [EdgeTTS 音色] [声音克隆] ← Tab │ +├─────────────────────────────────────┤ +│ Tab 1: 现有音色 2x3 网格 │ +│ │ +│ Tab 2: 声音克隆 │ +│ ┌───────────────────────────────┐ │ +│ │ 📁 我的参考音频 │ │ +│ │ [ref1] [ref2] [+上传] │ │ +│ └───────────────────────────────┘ │ +│ ┌───────────────────────────────┐ │ +│ │ 🎤 或在线录音 │ │ +│ │ [开始录音] [停止] 时长: 0:05 │ │ +│ │ (录音完成后显示试听和使用按钮) │ │ +│ └───────────────────────────────┘ │ +│ ┌───────────────────────────────┐ │ +│ │ 📝 参考音频文字 (必填) │ │ +│ │ [textarea] │ │ +│ └───────────────────────────────┘ │ +└─────────────────────────────────────┘ +``` + +**在线录音逻辑**: +```typescript +const startRecording = async () => { + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' }); + const chunks: BlobPart[] = []; + + mediaRecorder.ondataavailable = (e) => chunks.push(e.data); + mediaRecorder.onstop = () => { + const blob = new Blob(chunks, { type: 'audio/webm' }); + setRecordedBlob(blob); + stream.getTracks().forEach(track => track.stop()); + }; + + mediaRecorder.start(); + setIsRecording(true); + mediaRecorderRef.current = mediaRecorder; +}; + +const stopRecording = () => { + mediaRecorderRef.current?.stop(); + setIsRecording(false); +}; + +const useRecording = async () => { + // 将录音 Blob 上传到后端 + const formData = new FormData(); + formData.append('file', recordedBlob, 'recording.webm'); + formData.append('ref_text', refText); + const { data } = await api.post('/api/ref-audios', formData); + // 上传成功后刷新列表并选中 + fetchRefAudios(); + setSelectedRefAudio(data); +}; +``` + +### 6. 前端:修改生成请求 +```typescript +const handleGenerate = async () => { + const payload = { + material_path: materialObj.path, + text: text, + tts_mode: ttsMode, + ...(ttsMode === 'edgetts' + ? { voice } + : { ref_audio_id: selectedRefAudio.id, ref_text: refText }) + }; + await api.post('/api/videos/generate', payload); +}; +``` + +--- + +## 文件清单 + +### 新建 +| 文件 | 描述 | +|------|------| +| `backend/app/services/voice_clone_service.py` | 声音克隆服务 | +| `backend/app/api/ref_audios.py` | 参考音频管理 API | + +### 修改 +| 文件 | 修改内容 | +|------|----------| +| `backend/app/api/videos.py` | 扩展 GenerateRequest,修改 TTS 调用逻辑 | +| `backend/app/main.py` | 注册 ref_audios 路由 | +| `backend/app/services/storage.py` | 添加 BUCKET_REF_AUDIOS | +| `frontend/src/app/page.tsx` | Tab 切换 UI、参考音频选择、refText 输入 | + +--- + +## 验证方法 + +1. **后端测试**: + ```bash + # 启动后端 + cd backend && uvicorn app.main:app --port 8006 + + # 测试参考音频上传 + curl -X POST http://localhost:8006/api/ref-audios \ + -F "file=@test.wav" -F "ref_text=测试文字" + + # 测试声音克隆生成 + curl -X POST http://localhost:8006/api/videos/generate \ + -H "Content-Type: application/json" \ + -d '{"text":"测试文案","tts_mode":"voiceclone","ref_audio_id":"xxx","ref_text":"参考文字","material_path":"..."}' + ``` + +2. **前端测试**: + - 打开首页,确认 Tab 切换正常 + - 上传参考音频,确认列表显示 + - 选择声音克隆模式,填写参考文字,点击生成 + - 确认生成的视频使用克隆的声音 + +3. **端到端测试**: + - 上传参考音频 → 选择声音克隆 → 输入口播文案 → 生成视频 → 播放验证声音 diff --git a/Docs/task_complete.md b/Docs/task_complete.md index 9d6f4fb..7ca70ca 100644 --- a/Docs/task_complete.md +++ b/Docs/task_complete.md @@ -2,21 +2,21 @@ **项目**:ViGent2 数字人口播视频生成系统 **服务器**:Dell R730 (2× RTX 3090 24GB) -**更新时间**:2026-01-28 -**整体进度**:100%(Day 12 iOS 兼容、移动端优化、Qwen3-TTS 部署) +**更新时间**:2026-01-29 +**整体进度**:100%(Day 13 声音克隆功能集成完成) ## 📖 快速导航 | 章节 | 说明 | |------|------| -| [已完成任务](#-已完成任务) | Day 1-12 完成的功能 | +| [已完成任务](#-已完成任务) | Day 1-13 完成的功能 | | [后续规划](#️-后续规划) | 待办项目 | | [进度统计](#-进度统计) | 各模块完成度 | | [里程碑](#-里程碑) | 关键节点 | | [时间线](#-时间线) | 开发历程 | **相关文档**: -- [Day 日志](file:///d:/CodingProjects/Antigravity/ViGent2/Docs/DevLogs/) (Day1-Day12) +- [Day 日志](file:///d:/CodingProjects/Antigravity/ViGent2/Docs/DevLogs/) (Day1-Day13) - [部署指南](file:///d:/CodingProjects/Antigravity/ViGent2/Docs/DEPLOY_MANUAL.md) - [Qwen3-TTS 部署](file:///d:/CodingProjects/Antigravity/ViGent2/Docs/QWEN3_TTS_DEPLOY.md) @@ -169,15 +169,23 @@ - [x] **发布页面 UI 重构** (立即发布/定时发布按钮分离,防误触设计) - [x] **Qwen3-TTS 0.6B 部署** (声音克隆模型,GPU0,3秒参考音频快速克隆) +### 阶段二十:声音克隆功能集成 (Day 13) +- [x] **Qwen3-TTS HTTP 服务** (独立 FastAPI 服务,端口 8009) +- [x] **声音克隆服务** (voice_clone_service.py,HTTP 调用封装) +- [x] **参考音频管理 API** (上传/列表/删除) +- [x] **前端 TTS 模式选择** (EdgeTTS / 声音克隆切换) +- [x] **Supabase ref-audios Bucket** (参考音频存储桶 + RLS 策略) +- [x] **端到端测试验证** (声音克隆完整流程测试通过) + --- ## 🛤️ 后续规划 ### 🔴 优先待办 -- [ ] **Qwen3-TTS 集成到 ViGent2** - 前端 UI + 后端服务集成 - [ ] 批量视频生成架构设计 ### 🟠 功能完善 +- [x] Qwen3-TTS 集成到 ViGent2 ✅ Day 13 完成 - [x] 定时发布功能 ✅ Day 7 完成 - [ ] **后端定时发布** - 替代平台端定时,使用 APScheduler 实现任务调度 - [ ] 批量视频生成 @@ -358,3 +366,11 @@ Day 12: iOS 兼容与移动端优化 ✅ 完成 - **Qwen3-TTS 0.6B 部署** (声音克隆模型,GPU0) - **部署文档** (QWEN3_TTS_DEPLOY.md) +Day 13: 声音克隆功能集成 ✅ 完成 + - Qwen3-TTS HTTP 服务 (独立 FastAPI,端口 8009) + - 声音克隆服务 (voice_clone_service.py) + - 参考音频管理 API (上传/列表/删除) + - 前端 TTS 模式选择 (EdgeTTS / 声音克隆) + - Supabase ref-audios Bucket 配置 + - 端到端测试验证通过 + diff --git a/README.md b/README.md index 0338e33..acd7961 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,7 @@ - 🎬 **唇形同步** - LatentSync 1.6 驱动,512×512 高分辨率 Diffusion 模型 - 🎙️ **TTS 配音** - EdgeTTS 多音色支持(云溪、晓晓等) +- 🔊 **声音克隆** - Qwen3-TTS 0.6B,3秒参考音频快速克隆 🆕 - 📱 **全自动发布** - 扫码登录 + Cookie持久化,支持多平台(B站/抖音/小红书)定时发布 - 🖥️ **Web UI** - Next.js 现代化界面,iOS/Android 移动端适配 - 🔐 **用户系统** - Supabase + JWT 认证,支持管理员后台、注册/登录 @@ -27,6 +28,7 @@ | 认证 | **JWT** + HttpOnly Cookie | | 唇形同步 | **LatentSync 1.6** (Latent Diffusion, 512×512) | | TTS | EdgeTTS | +| 声音克隆 | **Qwen3-TTS 0.6B** | | 视频处理 | FFmpeg | | 自动发布 | Playwright | @@ -141,7 +143,8 @@ nohup python -m scripts.server > server.log 2>&1 & | **API 服务** | `http://<服务器IP>:8006` | 后端 Swagger | | **认证管理 (Studio)** | `https://supabase.hbyrkj.top` | 需要 Basic Auth | | **认证 API (Kong)** | `https://api.hbyrkj.top` | Supabase 接口 | -| **模型服务** | `http://<服务器IP>:8007` | LatentSync | +| **唇形同步服务** | `http://<服务器IP>:8007` | LatentSync | +| **声音克隆服务** | `http://<服务器IP>:8009` | Qwen3-TTS | --- diff --git a/backend/app/api/ref_audios.py b/backend/app/api/ref_audios.py new file mode 100644 index 0000000..f36758a --- /dev/null +++ b/backend/app/api/ref_audios.py @@ -0,0 +1,276 @@ +""" +参考音频管理 API +支持上传/列表/删除参考音频,用于 Qwen3-TTS 声音克隆 +""" +from fastapi import APIRouter, UploadFile, File, Form, HTTPException, Depends +from pydantic import BaseModel +from typing import List, Optional +from pathlib import Path +from loguru import logger +import time +import json +import subprocess +import tempfile +import os +import re + +from app.core.deps import get_current_user +from app.services.storage import storage_service + +router = APIRouter() + +# 支持的音频格式 +ALLOWED_AUDIO_EXTENSIONS = {'.wav', '.mp3', '.m4a', '.webm', '.ogg', '.flac', '.aac'} + +# 参考音频 bucket +BUCKET_REF_AUDIOS = "ref-audios" + + +class RefAudioResponse(BaseModel): + id: str + name: str + path: str # signed URL for playback + ref_text: str + duration_sec: float + created_at: int + + +class RefAudioListResponse(BaseModel): + items: List[RefAudioResponse] + + +def sanitize_filename(filename: str) -> str: + """清理文件名,移除特殊字符""" + safe_name = re.sub(r'[<>:"/\\|?*\s]', '_', filename) + if len(safe_name) > 50: + ext = Path(safe_name).suffix + safe_name = safe_name[:50 - len(ext)] + ext + return safe_name + + +def get_audio_duration(file_path: str) -> float: + """获取音频时长 (秒)""" + try: + result = subprocess.run( + ['ffprobe', '-v', 'quiet', '-show_entries', 'format=duration', + '-of', 'csv=p=0', file_path], + capture_output=True, text=True, timeout=10 + ) + return float(result.stdout.strip()) + except Exception as e: + logger.warning(f"获取音频时长失败: {e}") + return 0.0 + + +def convert_to_wav(input_path: str, output_path: str) -> bool: + """将音频转换为 WAV 格式 (16kHz, mono)""" + try: + subprocess.run([ + 'ffmpeg', '-y', '-i', input_path, + '-ar', '16000', # 16kHz 采样率 + '-ac', '1', # 单声道 + '-acodec', 'pcm_s16le', # 16-bit PCM + output_path + ], capture_output=True, timeout=60, check=True) + return True + except Exception as e: + logger.error(f"音频转换失败: {e}") + return False + + +@router.post("", response_model=RefAudioResponse) +async def upload_ref_audio( + file: UploadFile = File(...), + ref_text: str = Form(...), + user: dict = Depends(get_current_user) +): + """ + 上传参考音频 + + - file: 音频文件 (支持 wav, mp3, m4a, webm 等) + - ref_text: 参考音频的转写文字 (必填) + """ + user_id = user["id"] + + # 验证文件扩展名 + ext = Path(file.filename).suffix.lower() + if ext not in ALLOWED_AUDIO_EXTENSIONS: + raise HTTPException( + status_code=400, + detail=f"不支持的音频格式: {ext}。支持的格式: {', '.join(ALLOWED_AUDIO_EXTENSIONS)}" + ) + + # 验证 ref_text + if not ref_text or len(ref_text.strip()) < 2: + raise HTTPException(status_code=400, detail="参考文字不能为空") + + try: + # 创建临时文件 + with tempfile.NamedTemporaryFile(delete=False, suffix=ext) as tmp_input: + content = await file.read() + tmp_input.write(content) + tmp_input_path = tmp_input.name + + # 转换为 WAV 格式 + tmp_wav_path = tmp_input_path + ".wav" + if ext != '.wav': + if not convert_to_wav(tmp_input_path, tmp_wav_path): + raise HTTPException(status_code=500, detail="音频格式转换失败") + else: + # 即使是 wav 也要标准化格式 + convert_to_wav(tmp_input_path, tmp_wav_path) + + # 获取音频时长 + duration = get_audio_duration(tmp_wav_path) + if duration < 1.0: + raise HTTPException(status_code=400, detail="音频时长过短,至少需要 1 秒") + if duration > 60.0: + raise HTTPException(status_code=400, detail="音频时长过长,最多 60 秒") + + # 生成存储路径 + timestamp = int(time.time()) + safe_name = sanitize_filename(Path(file.filename).stem) + storage_path = f"{user_id}/{timestamp}_{safe_name}.wav" + + # 上传 WAV 文件到 Supabase + with open(tmp_wav_path, 'rb') as f: + wav_data = f.read() + + await storage_service.upload_file( + bucket=BUCKET_REF_AUDIOS, + path=storage_path, + file_data=wav_data, + content_type="audio/wav" + ) + + # 上传元数据 JSON + metadata = { + "ref_text": ref_text.strip(), + "original_filename": file.filename, + "duration_sec": duration, + "created_at": timestamp + } + metadata_path = f"{user_id}/{timestamp}_{safe_name}.json" + await storage_service.upload_file( + bucket=BUCKET_REF_AUDIOS, + path=metadata_path, + file_data=json.dumps(metadata, ensure_ascii=False).encode('utf-8'), + content_type="application/json" + ) + + # 获取签名 URL + signed_url = await storage_service.get_signed_url(BUCKET_REF_AUDIOS, storage_path) + + # 清理临时文件 + os.unlink(tmp_input_path) + if os.path.exists(tmp_wav_path): + os.unlink(tmp_wav_path) + + return RefAudioResponse( + id=storage_path, + name=file.filename, + path=signed_url, + ref_text=ref_text.strip(), + duration_sec=duration, + created_at=timestamp + ) + + except HTTPException: + raise + except Exception as e: + logger.error(f"上传参考音频失败: {e}") + raise HTTPException(status_code=500, detail=f"上传失败: {str(e)}") + + +@router.get("", response_model=RefAudioListResponse) +async def list_ref_audios(user: dict = Depends(get_current_user)): + """列出当前用户的所有参考音频""" + user_id = user["id"] + + try: + # 列出用户目录下的文件 + files = await storage_service.list_files(BUCKET_REF_AUDIOS, user_id) + + # 过滤出 .wav 文件并获取对应的 metadata + items = [] + for f in files: + name = f.get("name", "") + if not name.endswith(".wav"): + continue + + storage_path = f"{user_id}/{name}" + + # 尝试读取 metadata + metadata_name = name.replace(".wav", ".json") + metadata_path = f"{user_id}/{metadata_name}" + + ref_text = "" + duration_sec = 0.0 + created_at = 0 + + try: + # 获取 metadata 内容 + metadata_url = await storage_service.get_signed_url(BUCKET_REF_AUDIOS, metadata_path) + import httpx + async with httpx.AsyncClient() as client: + resp = await client.get(metadata_url) + if resp.status_code == 200: + metadata = resp.json() + ref_text = metadata.get("ref_text", "") + duration_sec = metadata.get("duration_sec", 0.0) + created_at = metadata.get("created_at", 0) + except Exception as e: + logger.warning(f"读取 metadata 失败: {e}") + # 从文件名提取时间戳 + try: + created_at = int(name.split("_")[0]) + except: + pass + + # 获取音频签名 URL + signed_url = await storage_service.get_signed_url(BUCKET_REF_AUDIOS, storage_path) + + items.append(RefAudioResponse( + id=storage_path, + name=name, + path=signed_url, + ref_text=ref_text, + duration_sec=duration_sec, + created_at=created_at + )) + + # 按创建时间倒序排列 + items.sort(key=lambda x: x.created_at, reverse=True) + + return RefAudioListResponse(items=items) + + except Exception as e: + logger.error(f"列出参考音频失败: {e}") + raise HTTPException(status_code=500, detail=f"获取列表失败: {str(e)}") + + +@router.delete("/{audio_id:path}") +async def delete_ref_audio(audio_id: str, user: dict = Depends(get_current_user)): + """删除参考音频""" + user_id = user["id"] + + # 安全检查:确保只能删除自己的文件 + if not audio_id.startswith(f"{user_id}/"): + raise HTTPException(status_code=403, detail="无权删除此文件") + + try: + # 删除 WAV 文件 + await storage_service.delete_file(BUCKET_REF_AUDIOS, audio_id) + + # 删除 metadata JSON + metadata_path = audio_id.replace(".wav", ".json") + try: + await storage_service.delete_file(BUCKET_REF_AUDIOS, metadata_path) + except: + pass # metadata 可能不存在 + + return {"success": True, "message": "删除成功"} + + except Exception as e: + logger.error(f"删除参考音频失败: {e}") + raise HTTPException(status_code=500, detail=f"删除失败: {str(e)}") diff --git a/backend/app/api/videos.py b/backend/app/api/videos.py index da936b8..03ea7e7 100644 --- a/backend/app/api/videos.py +++ b/backend/app/api/videos.py @@ -11,6 +11,7 @@ import os from app.services.tts_service import TTSService from app.services.video_service import VideoService from app.services.lipsync_service import LipSyncService +from app.services.voice_clone_service import voice_clone_service from app.services.storage import storage_service from app.core.config import settings from app.core.deps import get_current_user @@ -21,6 +22,10 @@ class GenerateRequest(BaseModel): text: str voice: str = "zh-CN-YunxiNeural" material_path: str + # 声音克隆模式新增字段 + tts_mode: str = "edgetts" # "edgetts" | "voiceclone" + ref_audio_id: Optional[str] = None # 参考音频 storage path + ref_text: Optional[str] = None # 参考音频的转写文字 tasks = {} # In-memory task store @@ -95,13 +100,42 @@ async def _process_video_generation(task_id: str, req: GenerateRequest, user_id: await _download_material(req.material_path, input_material_path) # 1. TTS - 进度 5% -> 25% - tasks[task_id]["message"] = "正在生成语音 (TTS)..." + tasks[task_id]["message"] = "正在生成语音..." tasks[task_id]["progress"] = 10 - tts = TTSService() - audio_path = temp_dir / f"{task_id}_audio.mp3" + audio_path = temp_dir / f"{task_id}_audio.wav" temp_files.append(audio_path) - await tts.generate_audio(req.text, req.voice, str(audio_path)) + + if req.tts_mode == "voiceclone": + # 声音克隆模式 + if not req.ref_audio_id or not req.ref_text: + raise ValueError("声音克隆模式需要提供参考音频和参考文字") + + tasks[task_id]["message"] = "正在下载参考音频..." + + # 从 Supabase 下载参考音频 + ref_audio_local = temp_dir / f"{task_id}_ref.wav" + temp_files.append(ref_audio_local) + + ref_audio_url = await storage_service.get_signed_url( + bucket="ref-audios", + path=req.ref_audio_id + ) + await _download_material(ref_audio_url, ref_audio_local) + + tasks[task_id]["message"] = "正在克隆声音 (Qwen3-TTS)..." + await voice_clone_service.generate_audio( + text=req.text, + ref_audio_path=str(ref_audio_local), + ref_text=req.ref_text, + output_path=str(audio_path), + language="Chinese" + ) + else: + # EdgeTTS 模式 (默认) + tasks[task_id]["message"] = "正在生成语音 (EdgeTTS)..." + tts = TTSService() + await tts.generate_audio(req.text, req.voice, str(audio_path)) tts_time = time.time() - start_time print(f"[Pipeline] TTS completed in {tts_time:.1f}s") @@ -217,6 +251,12 @@ async def lipsync_health(): return await lipsync.check_health() +@router.get("/voiceclone/health") +async def voiceclone_health(): + """获取声音克隆服务健康状态""" + return await voice_clone_service.check_health() + + @router.get("/generated") async def list_generated_videos(current_user: dict = Depends(get_current_user)): """从 Storage 读取当前用户生成的视频列表""" diff --git a/backend/app/main.py b/backend/app/main.py index 88752e2..93c2af0 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -2,7 +2,7 @@ from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.middleware.cors import CORSMiddleware from app.core import config -from app.api import materials, videos, publish, login_helper, auth, admin +from app.api import materials, videos, publish, login_helper, auth, admin, ref_audios from loguru import logger import os @@ -55,6 +55,7 @@ app.include_router(publish.router, prefix="/api/publish", tags=["Publish"]) app.include_router(login_helper.router, prefix="/api", tags=["LoginHelper"]) app.include_router(auth.router) # /api/auth app.include_router(admin.router) # /api/admin +app.include_router(ref_audios.router, prefix="/api/ref-audios", tags=["RefAudios"]) @app.on_event("startup") diff --git a/backend/app/services/storage.py b/backend/app/services/storage.py index 462b89c..519754b 100644 --- a/backend/app/services/storage.py +++ b/backend/app/services/storage.py @@ -16,6 +16,26 @@ class StorageService: self.supabase: Client = get_supabase() self.BUCKET_MATERIALS = "materials" self.BUCKET_OUTPUTS = "outputs" + self.BUCKET_REF_AUDIOS = "ref-audios" + # 确保所有 bucket 存在 + self._ensure_buckets() + + def _ensure_buckets(self): + """确保所有必需的 bucket 存在""" + buckets = [self.BUCKET_MATERIALS, self.BUCKET_OUTPUTS, self.BUCKET_REF_AUDIOS] + try: + existing = self.supabase.storage.list_buckets() + existing_names = {b.name for b in existing} if existing else set() + for bucket_name in buckets: + if bucket_name not in existing_names: + try: + self.supabase.storage.create_bucket(bucket_name, options={"public": True}) + logger.info(f"Created bucket: {bucket_name}") + except Exception as e: + # 可能已存在,忽略错误 + logger.debug(f"Bucket {bucket_name} creation skipped: {e}") + except Exception as e: + logger.warning(f"Failed to ensure buckets: {e}") def _convert_to_public_url(self, url: str) -> str: """将内部 URL 转换为公网可访问的 URL""" diff --git a/backend/app/services/voice_clone_service.py b/backend/app/services/voice_clone_service.py new file mode 100644 index 0000000..871850c --- /dev/null +++ b/backend/app/services/voice_clone_service.py @@ -0,0 +1,110 @@ +""" +声音克隆服务 +通过 HTTP 调用 Qwen3-TTS 独立服务 (端口 8009) +""" +import httpx +from pathlib import Path +from typing import Optional +from loguru import logger + +from app.core.config import settings + +# Qwen3-TTS 服务地址 +QWEN_TTS_URL = "http://localhost:8009" + + +class VoiceCloneService: + """声音克隆服务 - 调用 Qwen3-TTS HTTP API""" + + def __init__(self): + self.base_url = QWEN_TTS_URL + # 健康状态缓存 + self._health_cache: Optional[dict] = None + self._health_cache_time: float = 0 + + async def generate_audio( + self, + text: str, + ref_audio_path: str, + ref_text: str, + output_path: str, + language: str = "Chinese" + ) -> str: + """ + 使用声音克隆生成语音 + + Args: + text: 要合成的文本 + ref_audio_path: 参考音频本地路径 + ref_text: 参考音频的转写文字 + output_path: 输出 wav 路径 + language: 语言 (Chinese/English/Auto) + + Returns: + 输出文件路径 + """ + logger.info(f"🎤 Voice Clone: {text[:30]}...") + Path(output_path).parent.mkdir(parents=True, exist_ok=True) + + # 读取参考音频 + with open(ref_audio_path, "rb") as f: + ref_audio_data = f.read() + + # 调用 Qwen3-TTS 服务 + timeout = httpx.Timeout(300.0) # 5分钟超时 + async with httpx.AsyncClient(timeout=timeout) as client: + try: + response = await client.post( + f"{self.base_url}/generate", + files={"ref_audio": ("ref.wav", ref_audio_data, "audio/wav")}, + data={ + "text": text, + "ref_text": ref_text, + "language": language + } + ) + response.raise_for_status() + + # 保存返回的音频 + with open(output_path, "wb") as f: + f.write(response.content) + + logger.info(f"✅ Voice clone saved: {output_path}") + return output_path + + except httpx.HTTPStatusError as e: + logger.error(f"Qwen3-TTS API error: {e.response.status_code} - {e.response.text}") + raise RuntimeError(f"声音克隆服务错误: {e.response.text}") + except httpx.RequestError as e: + logger.error(f"Qwen3-TTS connection error: {e}") + raise RuntimeError("无法连接声音克隆服务,请检查服务是否启动") + + async def check_health(self) -> dict: + """健康检查""" + import time + + # 5分钟缓存 + now = time.time() + if self._health_cache and (now - self._health_cache_time) < 300: + return self._health_cache + + try: + async with httpx.AsyncClient(timeout=5.0) as client: + response = await client.get(f"{self.base_url}/health") + response.raise_for_status() + self._health_cache = response.json() + self._health_cache_time = now + return self._health_cache + except Exception as e: + logger.warning(f"Qwen3-TTS health check failed: {e}") + return { + "service": "Qwen3-TTS Voice Clone", + "model": "0.6B-Base", + "ready": False, + "gpu_id": 0, + "error": str(e) + } + + +# 单例 +voice_clone_service = VoiceCloneService() diff --git a/frontend/README.md b/frontend/README.md index f697d3f..0097139 100644 --- a/frontend/README.md +++ b/frontend/README.md @@ -19,6 +19,11 @@ ViGent2 的前端界面,采用 Next.js 14 + TailwindCSS 构建。 - **发布配置**: 设置视频标题、标签、简介。 - **定时任务**: 支持 "立即发布" 或 "定时发布"。 +### 3. 声音克隆 [Day 13 新增] +- **TTS 模式选择**: EdgeTTS (预设音色) / 声音克隆 (自定义音色) 切换。 +- **参考音频管理**: 上传/列表/删除参考音频 (3-20秒 WAV)。 +- **一键克隆**: 选择参考音频后自动调用 Qwen3-TTS 服务。 + ## 🛠️ 技术栈 - **框架**: Next.js 14 (App Router) diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx index e413e7f..9ecf4f8 100644 --- a/frontend/src/app/page.tsx +++ b/frontend/src/app/page.tsx @@ -1,7 +1,7 @@ "use client"; -import { useState, useEffect } from "react"; +import { useState, useEffect, useRef } from "react"; import Link from "next/link"; import api from "@/lib/axios"; @@ -34,6 +34,15 @@ interface GeneratedVideo { created_at: number; } +interface RefAudio { + id: string; + name: string; + path: string; + ref_text: string; + duration_sec: number; + created_at: number; +} + // 格式化日期(避免 Hydration 错误) const formatDate = (timestamp: number) => { const d = new Date(timestamp * 1000); @@ -65,6 +74,21 @@ export default function Home() { const [selectedVideoId, setSelectedVideoId] = useState(null); + // 声音克隆相关状态 + const [ttsMode, setTtsMode] = useState<'edgetts' | 'voiceclone'>('edgetts'); + const [refAudios, setRefAudios] = useState([]); + const [selectedRefAudio, setSelectedRefAudio] = useState(null); + const [refText, setRefText] = useState('其实生活中有许多美好的瞬间,比如清晨的阳光,或者一杯温热的清茶。希望这次生成的音色能够自然、流畅,完美还原出我最真实的声音状态。'); + const [isUploadingRef, setIsUploadingRef] = useState(false); + const [uploadRefError, setUploadRefError] = useState(null); + + // 在线录音相关 + const [isRecording, setIsRecording] = useState(false); + const [recordedBlob, setRecordedBlob] = useState(null); + const [recordingTime, setRecordingTime] = useState(0); + const mediaRecorderRef = useRef(null); + const recordingIntervalRef = useRef(null); + // 可选音色 const voices = [ { id: "zh-CN-YunxiNeural", name: "云溪 (男声-年轻)" }, @@ -74,10 +98,14 @@ export default function Home() { { id: "zh-CN-XiaoyiNeural", name: "晓伊 (女声-温柔)" }, ]; + // 声音克隆固定参考文字(用户录音/上传时需要读这段话) + const FIXED_REF_TEXT = "其实生活中有许多美好的瞬间,比如清晨的阳光,或者一杯温热的清茶。希望这次生成的音色能够自然、流畅,完美还原出我最真实的声音状态。"; + // 加载素材列表和历史视频 useEffect(() => { fetchMaterials(); fetchGeneratedVideos(); + fetchRefAudios(); }, []); const fetchMaterials = async () => { @@ -111,6 +139,115 @@ export default function Home() { } }; + // 获取参考音频列表 + const fetchRefAudios = async () => { + try { + const { data } = await api.get('/api/ref-audios'); + setRefAudios(data.items || []); + } catch (error) { + console.error("获取参考音频失败:", error); + } + }; + + // 上传参考音频(使用固定参考文字) + const uploadRefAudio = async (file: File) => { + const refTextInput = FIXED_REF_TEXT; + + setIsUploadingRef(true); + setUploadRefError(null); + + try { + const formData = new FormData(); + formData.append('file', file); + formData.append('ref_text', refTextInput); + + const { data } = await api.post('/api/ref-audios', formData, { + headers: { 'Content-Type': 'multipart/form-data' }, + }); + + await fetchRefAudios(); + setSelectedRefAudio(data); + setRefText(data.ref_text); + setIsUploadingRef(false); + } catch (err: any) { + console.error("Upload ref audio failed:", err); + setIsUploadingRef(false); + const errorMsg = err.response?.data?.detail || err.message || String(err); + setUploadRefError(`上传失败: ${errorMsg}`); + } + }; + + // 删除参考音频 + const deleteRefAudio = async (audioId: string) => { + if (!confirm("确定要删除这个参考音频吗?")) return; + try { + await api.delete(`/api/ref-audios/${encodeURIComponent(audioId)}`); + fetchRefAudios(); + if (selectedRefAudio?.id === audioId) { + setSelectedRefAudio(null); + setRefText(''); + } + } catch (error) { + alert("删除失败: " + error); + } + }; + + // 开始录音 + const startRecording = async () => { + try { + const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); + const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/webm' }); + const chunks: BlobPart[] = []; + + mediaRecorder.ondataavailable = (e) => chunks.push(e.data); + mediaRecorder.onstop = () => { + const blob = new Blob(chunks, { type: 'audio/webm' }); + setRecordedBlob(blob); + stream.getTracks().forEach(track => track.stop()); + }; + + mediaRecorder.start(); + setIsRecording(true); + setRecordingTime(0); + mediaRecorderRef.current = mediaRecorder; + + // 计时器 + recordingIntervalRef.current = setInterval(() => { + setRecordingTime(prev => prev + 1); + }, 1000); + } catch (err) { + alert('无法访问麦克风,请检查权限设置'); + console.error(err); + } + }; + + // 停止录音 + const stopRecording = () => { + mediaRecorderRef.current?.stop(); + setIsRecording(false); + if (recordingIntervalRef.current) { + clearInterval(recordingIntervalRef.current); + recordingIntervalRef.current = null; + } + }; + + // 使用录音(上传到后端,使用固定参考文字) + const useRecording = async () => { + if (!recordedBlob) return; + + const file = new File([recordedBlob], 'recording.webm', { type: 'audio/webm' }); + await uploadRefAudio(file); + setRecordedBlob(null); + setRecordingTime(0); + }; + + // 格式化录音时长 + const formatRecordingTime = (seconds: number) => { + const mins = Math.floor(seconds / 60); + const secs = seconds % 60; + return `${mins}:${secs.toString().padStart(2, '0')}`; + }; + // 删除素材 const deleteMaterial = async (materialId: string) => { if (!confirm("确定要删除这个素材吗?")) return; @@ -195,6 +332,14 @@ export default function Home() { return; } + // 声音克隆模式校验 + if (ttsMode === 'voiceclone') { + if (!selectedRefAudio) { + alert("请选择或上传参考音频"); + return; + } + } + setIsGenerating(true); setGeneratedVideo(null); @@ -206,13 +351,22 @@ export default function Home() { return; } - // 创建生成任务 - const { data } = await api.post('/api/videos/generate', { + // 构建请求参数 + const payload: Record = { material_path: materialObj.path, text: text, - voice: voice, - add_subtitle: true, - }); + tts_mode: ttsMode, + }; + + if (ttsMode === 'edgetts') { + payload.voice = voice; + } else { + payload.ref_audio_id = selectedRefAudio!.id; + payload.ref_text = refText; + } + + // 创建生成任务 + const { data } = await api.post('/api/videos/generate', payload); const taskId = data.task_id; @@ -433,32 +587,207 @@ export default function Home() { - {/* 音色选择 */} + {/* 配音方式选择 */}

- 🎙️ 选择配音音色 + 🎙️ 选择配音方式

-
- {voices.map((v) => ( - - ))} + + {/* Tab 切换 */} +
+ +
+ + {/* EdgeTTS 音色列表 */} + {ttsMode === 'edgetts' && ( +
+ {voices.map((v) => ( + + ))} +
+ )} + + {/* 声音克隆区域 */} + {ttsMode === 'voiceclone' && ( +
+ {/* 参考音频列表 */} +
+
+ 📁 我的参考音频 +
+ { + const file = e.target.files?.[0]; + if (file) { + uploadRefAudio(file); + } + e.target.value = ''; + }} + className="hidden" + /> + + +
+
+ + {isUploadingRef && ( +
+ ⏳ 上传中... +
+ )} + + {uploadRefError && ( +
+ ❌ {uploadRefError} + +
+ )} + + {refAudios.length === 0 ? ( +
+ 暂无参考音频,请上传或录制 +
+ ) : ( +
+ {refAudios.map((audio) => ( +
{ + setSelectedRefAudio(audio); + setRefText(audio.ref_text); + }} + > +
{audio.name}
+
{audio.duration_sec.toFixed(1)}s
+ +
+ ))} +
+ )} +
+ + {/* 在线录音 */} +
+ 🎤 或在线录音 +
+ {!isRecording ? ( + + ) : ( + + )} + {isRecording && ( + + 🔴 录音中 {formatRecordingTime(recordingTime)} + + )} +
+ + {recordedBlob && !isRecording && ( +
+
+ ✅ 录音完成 ({formatRecordingTime(recordingTime)}) +
+ +
+ )} +
+ + {/* 参考音频文字(固定,用户需要朗读此段落) */} +
+ +
+ {FIXED_REF_TEXT} +
+

+ 请清晰朗读上述内容完成录音,系统将以此为参考克隆您的声音 +

+
+
+ )}
{/* 生成按钮 */}
- - + + ); } diff --git a/models/Qwen3-TTS/qwen_tts_server.py b/models/Qwen3-TTS/qwen_tts_server.py new file mode 100644 index 0000000..910d4cc --- /dev/null +++ b/models/Qwen3-TTS/qwen_tts_server.py @@ -0,0 +1,189 @@ +""" +Qwen3-TTS 独立推理服务 +端口: 8009 +GPU: 0 + +启动方式: + conda activate qwen-tts + python qwen_tts_server.py + +PM2 启动: + pm2 start qwen_tts_server.py --name qwen-tts --interpreter /home/rongye/ProgramFiles/miniconda3/envs/qwen-tts/bin/python +""" +import os +import sys +import tempfile +import time +from pathlib import Path +from typing import Optional + +# 设置 GPU +os.environ["CUDA_VISIBLE_DEVICES"] = "0" + +from fastapi import FastAPI, HTTPException, UploadFile, File, Form +from fastapi.responses import FileResponse +from pydantic import BaseModel +import uvicorn + +app = FastAPI(title="Qwen3-TTS Voice Clone Service", version="1.0") + +# 模型路径 +MODEL_PATH = Path(__file__).parent / "checkpoints" / "0.6B-Base" + +# 全局模型实例 +_model = None +_model_loaded = False + + +def load_model(): + """加载模型(启动时调用)""" + global _model, _model_loaded + + if _model_loaded: + return + + print("🔄 Loading Qwen3-TTS model...") + start = time.time() + + import torch + from qwen_tts import Qwen3TTSModel + + _model = Qwen3TTSModel.from_pretrained( + str(MODEL_PATH), + device_map="cuda:0", + dtype=torch.bfloat16, + ) + + _model_loaded = True + print(f"✅ Qwen3-TTS model loaded in {time.time() - start:.1f}s") + + +class GenerateRequest(BaseModel): + text: str + ref_text: str + language: str = "Chinese" + + +class HealthResponse(BaseModel): + service: str + model: str + ready: bool + gpu_id: int + + +@app.on_event("startup") +async def startup(): + """服务启动时预加载模型""" + try: + load_model() + except Exception as e: + print(f"❌ Model loading failed: {e}") + + +@app.get("/health", response_model=HealthResponse) +async def health(): + """健康检查""" + gpu_ok = False + try: + import torch + gpu_ok = torch.cuda.is_available() + except: + pass + + return HealthResponse( + service="Qwen3-TTS Voice Clone", + model="0.6B-Base", + ready=_model_loaded and gpu_ok, + gpu_id=0 + ) + + +@app.post("/generate") +async def generate( + ref_audio: UploadFile = File(...), + text: str = Form(...), + ref_text: str = Form(...), + language: str = Form("Chinese") +): + """ + 声音克隆生成 + + Args: + ref_audio: 参考音频文件 (WAV) + text: 要合成的文本 + ref_text: 参考音频的转写文字 + language: 语言 (Chinese/English/Auto) + + Returns: + 生成的音频文件 (WAV) + """ + if not _model_loaded: + raise HTTPException(status_code=503, detail="Model not loaded") + + import soundfile as sf + + # 保存上传的参考音频到临时文件 + with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as tmp_ref: + content = await ref_audio.read() + tmp_ref.write(content) + ref_audio_path = tmp_ref.name + + # 生成输出路径 + output_path = tempfile.mktemp(suffix=".wav") + + try: + print(f"🎤 Generating: {text[:30]}...") + print(f"📝 Ref text: {ref_text[:50]}...") + + start = time.time() + + wavs, sr = _model.generate_voice_clone( + text=text, + language=language, + ref_audio=ref_audio_path, + ref_text=ref_text, + ) + + sf.write(output_path, wavs[0], sr) + + duration = len(wavs[0]) / sr + print(f"✅ Generated in {time.time() - start:.1f}s, duration: {duration:.1f}s") + + # 返回音频文件 + return FileResponse( + output_path, + media_type="audio/wav", + filename="output.wav", + background=None # 让客户端下载完再删除 + ) + + except Exception as e: + print(f"❌ Generation failed: {e}") + raise HTTPException(status_code=500, detail=str(e)) + finally: + # 清理参考音频临时文件 + try: + os.unlink(ref_audio_path) + except: + pass + + +@app.on_event("shutdown") +async def shutdown(): + """清理临时文件""" + # 清理 /tmp 中的残留文件 + import glob + for f in glob.glob("/tmp/tmp*.wav"): + try: + os.unlink(f) + except: + pass + + +if __name__ == "__main__": + uvicorn.run( + app, + host="0.0.0.0", + port=8009, + log_level="info" + ) diff --git a/run_qwen_tts.sh b/run_qwen_tts.sh new file mode 100644 index 0000000..278db32 --- /dev/null +++ b/run_qwen_tts.sh @@ -0,0 +1,9 @@ +#!/bin/bash +# Qwen3-TTS 声音克隆服务启动脚本 +# 端口: 8009 +# GPU: 0 + +cd /home/rongye/ProgramFiles/ViGent2/models/Qwen3-TTS + +# 使用 qwen-tts conda 环境的 Python +/home/rongye/ProgramFiles/miniconda3/envs/qwen-tts/bin/python qwen_tts_server.py