Skip to content

抖音视频下载 API

基于 FastAPI + Playwright + hellotik.app 的抖音视频无水印下载服务,支持多画质自动缓存与 OneDrive 备份。

在线调试

输入你的 Token 并选择端点进行测试。


架构

用户 → api-dy.opccii.com → Cloudflare(CDN+SSL) → Nginx → uvicorn(127.0.0.1:8000)

                                                            ┌──────────┴──────────┐
                                                            │     Worker          │
                                                            │  ─ 缓存维护         │
                                                            │  ─ 健康检查         │
                                                            │  ─ OneDrive 备份    │
                                                            └──────────┬──────────┘

                                                            ┌──────────▼──────────┐
                                                            │      MySQL          │
                                                            │  videos / links     │
                                                            │  backups / ip_records│
                                                            └─────────────────────┘

端点一览

方法路径说明鉴权
GET/api/random从缓存池随机返回一个视频Token
GET/api/status缓存池状态Token
POST/api/submit提交抖音链接加入队列Token
POST/api/warmup立即爬取一个视频,阻塞返回Token
GET/api/admin/videos视频列表(支持筛选/分页)Admin Token
POST/api/admin/videos手动新增视频Admin Token
DELETE/api/admin/videos/{id}删除视频Admin Token
POST/api/admin/videos/{id}/retry重试爬取Admin Token
POST/api/admin/videos/batch批量导入链接Admin Token
GET/api/admin/stats统计面板Admin Token

公共接口

随机获取视频

GET /api/random

从缓存池随机返回一个已就绪的视频。

成功响应:

json
{
  "ok": true,
  "video": {
    "id": 13,
    "title": "和小狗一起! #抖音潮流舞蹈大赛# dancechallenge #潮流舞蹈挑战",
    "url": "https://v11-default.365yg.com/064d44c548b7144d05630a771b79ca79/...",
    "quality": "超高清",
    "fallback": {
      "720p": "https://v26-default.365yg.com/...",
      "540p": "https://v26-default.365yg.com/..."
    }
  },
  "cache_status": { "ready": 6, "target": 10 }
}

错误响应:

json
{
  "ok": false,
  "error": "no_cache",
  "hint": "缓存池为空,请先提交视频或等待爬取完成",
  "cache_status": { "ready": 0, "target": 10 }
}

查询缓存状态

GET /api/status

查询当前缓存池状态。

响应示例:

json
{ "ready": 6, "target": 10, "total": 15, "failed": 2, "deleted": 1, "expired": 0 }

提交链接

POST /api/submit

提交抖音分享链接加入爬取队列。链接自动去重,重复提交返回已有 ID。

请求参数:

参数类型必填说明
share_urlstring抖音分享链接

响应示例:

json
{ "ok": true, "message": "已加入队列", "id": 13 }

立即爬取

POST /api/warmup

立即爬取指定视频,阻塞等待返回结果(最长 60s)。

可省略 share_url —— 此时从队列中取一个 pending 视频爬取;也可指定链接。

请求参数:

参数类型必填说明
share_urlstring抖音分享链接(为空则从队列取)

成功响应:

json
{
  "ok": true,
  "video": {
    "id": 13,
    "title": "和小狗一起! #抖音潮流舞蹈大赛# dancechallenge #潮流舞蹈挑战",
    "url": "https://v11-default.365yg.com/...",
    "quality": "超高清",
    "fallback": {
      "720p": "https://v26-default.365yg.com/...",
      "540p": "https://v26-default.365yg.com/..."
    }
  },
  "cache_status": { "ready": 6, "target": 10 }
}

错误响应:

json
// 队列为空
{ "ok": false, "error": "no_pending", "hint": "暂无待爬取视频,请先提交链接" }
// 爬取超时
{ "ok": false, "error": "爬取超时,请稍后重试" }
// 解析失败(链接无效/视频已删除/hellotik 不支持)
{ "ok": false, "error": "解析返回空结果" }

管理接口

需要 Admin Token 鉴权。

视频列表

GET /api/admin/videos

查看视频列表,支持状态筛选和分页。

查询参数:

参数默认值说明
status全部筛选:pending ready failed deleted expired
page1页码
size20每页条数(最大 100)

新增视频

POST /api/admin/videos

手动新增视频链接。

请求参数:

参数类型必填说明
share_urlstring抖音分享链接

删除视频

DELETE /api/admin/videos/{id}

删除视频及关联数据。

路径参数:

参数类型说明
idinteger视频 ID

重试爬取

POST /api/admin/videos/{id}/retry

重置视频状态为 pending,触发重新爬取。

路径参数:

参数类型说明
idinteger视频 ID

批量导入

POST /api/admin/videos/batch

批量导入抖音链接。

请求参数:

参数类型必填说明
urlsstring[]抖音分享链接数组

统计面板

GET /api/admin/stats

统计面板。

响应示例:

json
{
  "total": 50,
  "by_status": { "pending": 10, "ready": 30, "failed": 5, "deleted": 3, "expired": 2 },
  "backup_rate": "30/30",
  "total_size_bytes": 12884901888
}

视频画质

爬虫自动采集所有可用画质并按优先级排序:

超高清 → 4K → 原画 → 1080p → 720p → 540p → 480p → 高清
  • /api/random 返回最高可用画质作为主链接,其余画质放入 fallback
  • Worker 备份自动选择最高画质上传 OneDrive

缓存机制

项目
缓存目标10 个就绪视频
Worker 窗口2 小时无请求自动停止
爬取间隔30-60s(随机,防限流)
链接健康检查每 4 小时

Worker 行为

场景行为
服务空闲 2hWorker 自动停止,0 资源占用
新请求到达Worker 立即启动,刷新窗口计时
ready < 10从 pending 队列补充爬取
链接失效标记 is_available=0,全失效则标记 expired
新视频就绪下载最高画质 → rclone 上传 OneDrive

数据库

说明
videos视频主表(状态机:pending → ready/failed/deleted/expired)
linksCDN 链接表(按画质拆分)
backupsOneDrive 备份记录
ip_recordsIP 鉴权记录(白名单/黑名单/失败计数)

OneDrive 备份

Worker 自动执行:

视频 status=ready → 检测未备份 → get_best_link(最高画质)
→ 下载到 /tmp/douyin_backup/{id}_tmp.mp4
→ 重命名为 {aweme_id}.mp4
→ rclone move → onedrive:douyin_backup/{aweme_id}.mp4
→ 写入 backups 表

错误码速查

HTTP错误原因
200no_cache缓存池无就绪视频
200no_pending队列无待爬取视频
200解析返回空结果hellotik 无法解析该链接
200爬取超时单次爬取超 60s
401未授权缺少 token 参数
401Token 无效token 错误(剩余尝试次数)
403IP 已被封禁连续 10 次鉴权失败
400无效的抖音分享链接格式URL 格式不匹配