init
This commit is contained in:
BIN
开发文档/参考网站.jpg
Normal file
BIN
开发文档/参考网站.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 439 KiB |
98
开发文档/哔哩哔哩解析.postman_collection.json
Normal file
98
开发文档/哔哩哔哩解析.postman_collection.json
Normal file
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"info": {
|
||||
"_postman_id": "8813fbd0-cdcf-443e-9b29-d62a8a7f891f",
|
||||
"name": "哔哩哔哩解析",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"_exporter_id": "49242368",
|
||||
"_collection_link": "https://lixin0229-2646365.postman.co/workspace/shihao's-Workspace~249f47cc-12a0-4152-8c64-d21cf5552a6c/collection/49242368-8813fbd0-cdcf-443e-9b29-d62a8a7f891f?action=share&source=collection_link&creator=49242368"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "米人API",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://api.mir6.com/api/bzjiexi?url=https://www.bilibili.com/video/BV1vrU6B4ELQ/?share_source=copy_web%26vd_source=8977adbddf938cc18f327c3c21c5120c",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"api",
|
||||
"mir6",
|
||||
"com"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"bzjiexi"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "url",
|
||||
"value": "https://www.bilibili.com/video/BV1vrU6B4ELQ/?share_source=copy_web%26vd_source=8977adbddf938cc18f327c3c21c5120c"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "BugPKAPI",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://api.bugpk.com/api/bilibili?url=https://www.bilibili.com/video/BV1vrU6B4ELQ/?share_source=copy_web%26vd_source=8977adbddf938cc18f327c3c21c5120c",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"api",
|
||||
"bugpk",
|
||||
"com"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"bilibili"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "url",
|
||||
"value": "https://www.bilibili.com/video/BV1vrU6B4ELQ/?share_source=copy_web&vd_source=8977adbddf938cc18f327c3c21c5120c"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "妖狐API",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://api.yaohud.cn/api/v6/video/bili?key=SM227DLC0ZgJ6DXJhAx&url=https://www.bilibili.com/video/BV1vrU6B4ELQ/?share_source=copy_web%26vd_source=8977adbddf938cc18f327c3c21c5120c",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"api",
|
||||
"yaohud",
|
||||
"cn"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"v6",
|
||||
"video",
|
||||
"bili"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "key",
|
||||
"value": "SM227DLC0ZgJ6DXJhAx"
|
||||
},
|
||||
{
|
||||
"key": "url",
|
||||
"value": "https://www.bilibili.com/video/BV1vrU6B4ELQ/?share_source=copy_web&vd_source=8977adbddf938cc18f327c3c21c5120c"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
}
|
||||
173
开发文档/开发需求.md
Normal file
173
开发文档/开发需求.md
Normal file
@@ -0,0 +1,173 @@
|
||||
# 短视频解析平台 —— 开发需求文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
本项目是一个聚合多家短视频解析接口的 Web 平台,对外提供统一的视频解析服务。
|
||||
后台支持管理员管理解析接口、用户、站点配置等功能,并支持基础的限流与队列控制。
|
||||
|
||||
## 2. 技术栈与基础要求
|
||||
|
||||
- 后端语言:**Python**
|
||||
- 数据库:**MySQL**
|
||||
- 前端:Web 页面,需**适配移动端(响应式布局)**
|
||||
- 部署形态:Web 应用(具体框架、部署方式可由开发时确定)
|
||||
|
||||
## 3. 主要功能模块
|
||||
|
||||
### 3.1 前台解析平台
|
||||
|
||||
1. 用户可在前台输入短视频链接,平台调用内部解析接口,返回统一格式的数据。
|
||||
2. 平台内部对接多个解析接口(含多个哔哩哔哩解析接口),通过“适配器模式”进行统一封装。
|
||||
3. 前台展示解析结果时,只需要以下字段:
|
||||
- 封面(cover)
|
||||
- 视频 URL(video_url)
|
||||
- 标题(title)
|
||||
- 简介(description)
|
||||
4. 前台页面需要适配移动端,保证在手机端有良好显示与操作体验。
|
||||
|
||||
### 3.2 用户系统
|
||||
|
||||
1. **注册登录**
|
||||
- 用户通过**邮箱注册**,注册时需要邮箱验证码。
|
||||
- 支持登录、退出登录。
|
||||
2. **邮箱验证码场景**
|
||||
- 用户注册
|
||||
- 重置密码
|
||||
- 找回密码
|
||||
上述操作均需要发送邮箱验证码并进行校验。
|
||||
3. **用户信息存储(MySQL)**
|
||||
- 用户名(名称)
|
||||
- 邮箱
|
||||
- 密码(需加密存储)
|
||||
- 注册 / 最近登录 IP
|
||||
- 使用解析的次数(可按总次数和/或按日统计)
|
||||
- 用户分组(如:游客、普通用户、VIP 用户、SVIP 用户)
|
||||
4. **解析次数限制**
|
||||
- 未登录用户:每天最多解析 **5 次**
|
||||
- 已登录用户:每天最多解析 **10 次**
|
||||
- 管理员后台可根据用户所属分组自定义每日解析次数(见「用户分组管理」)。
|
||||
|
||||
### 3.3 用户分组与限流策略
|
||||
|
||||
1. 默认用户分组:**普通用户**
|
||||
2. 预设分组类型(可在后台配置每日解析次数):
|
||||
- 游客
|
||||
- 普通用户
|
||||
- VIP 用户
|
||||
- SVIP 用户
|
||||
3. 功能需求:
|
||||
- 管理员可在后台给用户分配 / 修改所属分组。
|
||||
- 每个分组可单独配置“每日最大解析次数”。
|
||||
- 平台在用户发起解析时,需要根据分组和当日已用次数进行校验与限制。
|
||||
|
||||
### 3.4 队列与并发控制
|
||||
|
||||
1. 平台采用**队列模式**处理解析请求:
|
||||
- 多用户同时访问时,请求需要进入队列排队。
|
||||
2. **并发上限控制**:
|
||||
- 默认最大并发解析数为 **3**。
|
||||
- 并发上限值需支持在后台由管理员配置。
|
||||
3. 队列中的请求按照先进先出(FIFO)处理,并在前台给出简要提示(例如:排队中、预计等待等,可以简单实现)。
|
||||
|
||||
## 4. 解析接口与适配器设计
|
||||
|
||||
### 4.1 多解析接口接入
|
||||
|
||||
1. 在“开发文档文件夹”中有多个解析接口的 API 文档。
|
||||
2. 平台需要为**每一个解析接口**开发独立的**适配器(Adapter)**:
|
||||
- 负责调用对应的第三方解析 API。
|
||||
- 将第三方接口返回的数据**统一映射**为平台标准数据结构:
|
||||
```json
|
||||
{
|
||||
"cover": "...",
|
||||
"video_url": "...",
|
||||
"title": "...",
|
||||
"description": "..."
|
||||
}
|
||||
```
|
||||
3. 若某些 API **没有开发文档或示例返回值**:
|
||||
- 使用其自带的测试链接进行调用。
|
||||
- 开发过程中自行记录返回值结构和字段含义,并在代码或内部文档中进行整理记录。
|
||||
|
||||
### 4.2 哔哩哔哩多接口负载均衡与健康检查
|
||||
|
||||
1. 哔哩哔哩解析接口将接入 **3 个不同的接口**。
|
||||
2. 平台需要对这 3 个接口做**负载均衡**,例如:
|
||||
- 轮询
|
||||
- 权重
|
||||
- 或按健康状态优先级选择
|
||||
3. 管理员后台需提供任务配置:
|
||||
- 可以设置**定时任务**,定期对这三个 B 站接口执行健康检查。
|
||||
- 检查使用的视频链接由管理员在后台自行配置(如健康检查用的固定测试视频链接)。
|
||||
4. **健康检查逻辑**:
|
||||
- 定时任务按设定时间间隔调用 3 个接口,对测试视频链接进行解析。
|
||||
- 如解析失败、超时或返回异常等,视为健康检查不通过。
|
||||
- 健康检查不通过时,需给管理员发送邮件告警(可简要说明是哪个接口异常)。
|
||||
|
||||
## 5. 管理员后台功能
|
||||
|
||||
### 5.1 管理员账户与安全
|
||||
|
||||
1. 默认管理员账号:
|
||||
- 用户名:`shihao`
|
||||
- 密码:`80012029Lz`
|
||||
2. 管理员登录系统后,可以为自己的账号开启**二次验证(2FA)**:
|
||||
- 支持基于 TOTP(如 Google Authenticator)或其他实现方式(具体实现可由开发决定)。
|
||||
3. 后台需要基本的权限控制,非管理员账号无法访问后台管理页面。
|
||||
|
||||
### 5.2 站点配置管理
|
||||
|
||||
管理员可以在后台管理以下站点级配置:
|
||||
|
||||
1. 网站基础信息
|
||||
- 网站 Logo(上传或填 URL)
|
||||
- 网站标题
|
||||
- 网站公告(可显示在前台)
|
||||
- 网站底部信息(如备案号、版权信息等)
|
||||
2. 并发与队列配置
|
||||
- 最大并发解析数(默认 3,可修改)
|
||||
3. 用户分组配置
|
||||
- 各分组每日解析次数限制
|
||||
4. 解析接口管理
|
||||
- 各解析接口启用 / 禁用
|
||||
- 各接口权重(如用于简单负载均衡)
|
||||
- B 站接口健康检查测试链接配置及定时任务配置参数
|
||||
|
||||
### 5.3 SMTP 邮件配置与负载均衡
|
||||
|
||||
1. 系统初始使用一套**默认 SMTP 配置**。
|
||||
2. 管理员可以在后台:
|
||||
- 修改默认 SMTP 配置
|
||||
- 新增多个 SMTP 配置
|
||||
- 对多个 SMTP 进行**负载均衡**(如轮询发送或故障切换)。
|
||||
3. 提供**发送测试邮件**功能,方便管理员验证 SMTP 配置是否可用。
|
||||
4. SMTP 配置将用于:
|
||||
- 用户注册验证码邮件
|
||||
- 找回密码 / 重置密码验证码邮件
|
||||
- 管理员通知邮件(例如接口健康检查失败告警)
|
||||
|
||||
### 5.4 统计与日志
|
||||
|
||||
管理员后台需要提供基础统计信息展示,包括但不限于:
|
||||
|
||||
1. 访问 / 解析统计
|
||||
- 按 IP 统计使用次数
|
||||
- 总解析次数、成功/失败次数
|
||||
- 按时间维度的分布(例如每日/每小时解析次数趋势)
|
||||
2. 接口使用情况
|
||||
- 各解析接口被调用次数
|
||||
- 失败率、平均响应时间(可选,视实现复杂度)
|
||||
3. 用户使用情况
|
||||
- 各用户解析次数
|
||||
- 各用户分组下的使用量对比
|
||||
|
||||
(统计精度可以根据实际实现情况简化,核心是能看到基本的 IP 使用、时间分布和接口使用情况)
|
||||
|
||||
---
|
||||
|
||||
## 6. 安全与其他要求
|
||||
|
||||
1. 用户密码必须进行加密存储(如使用 PBKDF2、bcrypt 等方式)。
|
||||
2. 接口调用需做好基础的异常处理、超时控制及错误日志记录。
|
||||
3. 对解析次数限制、队列和并发控制要在服务端进行校验,避免被前端绕过。
|
||||
4. 所有配置项(如 SMTP、站点信息、分组限制、并发数等)需持久化存储在数据库或配置表中,并在后台可视化管理。
|
||||
619
开发文档/抖音API接口文档.md
Normal file
619
开发文档/抖音API接口文档.md
Normal file
@@ -0,0 +1,619 @@
|
||||
# 抖音视频解析 API 接口文档
|
||||
|
||||
## 概述
|
||||
|
||||
本文档描述了自部署的抖音视频解析 API 接口,用于从抖音分享链接中提取视频信息和下载视频文件。
|
||||
|
||||
**API 基础地址**: `https://dy.zoomcaronline.net`
|
||||
|
||||
---
|
||||
|
||||
## 接口列表
|
||||
|
||||
### 1. 提取视频 ID
|
||||
|
||||
从抖音分享链接中提取 `aweme_id`(视频唯一标识符)。
|
||||
|
||||
#### 请求信息
|
||||
|
||||
- **接口地址**: `/api/douyin/web/get_aweme_id`
|
||||
- **请求方法**: `GET`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||||
|--------|------|------|------|------|
|
||||
| url | string | 是 | 抖音分享链接 | `https://v.douyin.com/FLNGa7kXvMY/` |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```bash
|
||||
GET https://dy.zoomcaronline.net/api/douyin/web/get_aweme_id?url=https://v.douyin.com/FLNGa7kXvMY/
|
||||
```
|
||||
|
||||
```javascript
|
||||
// JavaScript 示例
|
||||
const response = await fetch('https://dy.zoomcaronline.net/api/douyin/web/get_aweme_id?url=https://v.douyin.com/FLNGa7kXvMY/');
|
||||
const data = await response.json();
|
||||
```
|
||||
|
||||
```python
|
||||
# Python 示例
|
||||
import requests
|
||||
|
||||
url = "https://dy.zoomcaronline.net/api/douyin/web/get_aweme_id"
|
||||
params = {"url": "https://v.douyin.com/FLNGa7kXvMY/"}
|
||||
response = requests.get(url, params=params)
|
||||
data = response.json()
|
||||
```
|
||||
|
||||
#### 响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": "7576474555553706981"
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应字段说明
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| code | integer | 状态码,200 表示成功 |
|
||||
| msg | string | 响应消息 |
|
||||
| data | string | 视频 ID (aweme_id) |
|
||||
|
||||
---
|
||||
|
||||
### 2. 获取视频详细信息
|
||||
|
||||
根据 `aweme_id` 获取视频的完整信息,包括作者、描述、封面图、视频地址等。
|
||||
|
||||
#### 请求信息
|
||||
|
||||
- **接口地址**: `/api/douyin/web/fetch_one_video`
|
||||
- **请求方法**: `GET`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||||
|--------|------|------|------|------|
|
||||
| aweme_id | string | 是 | 视频 ID | `7576474555553706981` |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```bash
|
||||
GET https://dy.zoomcaronline.net/api/douyin/web/fetch_one_video?aweme_id=7576474555553706981
|
||||
```
|
||||
|
||||
```javascript
|
||||
// JavaScript 示例
|
||||
const awemeId = "7576474555553706981";
|
||||
const response = await fetch(`https://dy.zoomcaronline.net/api/douyin/web/fetch_one_video?aweme_id=${awemeId}`);
|
||||
const data = await response.json();
|
||||
```
|
||||
|
||||
```python
|
||||
# Python 示例
|
||||
import requests
|
||||
|
||||
url = "https://dy.zoomcaronline.net/api/douyin/web/fetch_one_video"
|
||||
params = {"aweme_id": "7576474555553706981"}
|
||||
response = requests.get(url, params=params)
|
||||
data = response.json()
|
||||
```
|
||||
|
||||
#### 响应示例(精简版)
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"router": "/api/douyin/web/fetch_one_video",
|
||||
"data": {
|
||||
"aweme_detail": {
|
||||
"aweme_id": "7576474555553706981",
|
||||
"desc": "#美女 #漫展 #cos #二次元 #正常穿搭无不良引导",
|
||||
"create_time": 1764035452,
|
||||
"duration": 7315,
|
||||
"author": {
|
||||
"uid": "7558808540429747259",
|
||||
"nickname": "小鱼小鱼🐟",
|
||||
"signature": "永做真我!\n点赞+关注 休闲娱乐不迷路",
|
||||
"avatar_thumb": {
|
||||
"url_list": ["https://p3-pc.douyinpic.com/aweme/100x100/..."]
|
||||
},
|
||||
"follower_count": 2325,
|
||||
"total_favorited": 22399,
|
||||
"sec_uid": "MS4wLjABAAAAdl73D1NlE1ws4rViqBn9A_RKcKl3Sa-2LNi_SnO4a3w...",
|
||||
"short_id": "24435946694",
|
||||
"unique_id": "24435946694"
|
||||
},
|
||||
"video": {
|
||||
"cover_original_scale": {
|
||||
"url_list": [
|
||||
"https://p3-pc-sign.douyinpic.com/...",
|
||||
"https://p9-pc-sign.douyinpic.com/..."
|
||||
]
|
||||
},
|
||||
"play_addr": {
|
||||
"url_list": [
|
||||
"https://v5-hl-szyd-ov.zjcdn.com/...",
|
||||
"https://v5-dy-o-abtest.zjcdn.com/...",
|
||||
"https://www.douyin.com/aweme/v1/play/..."
|
||||
]
|
||||
},
|
||||
"duration": 7315,
|
||||
"width": 1080,
|
||||
"height": 1920
|
||||
},
|
||||
"statistics": {
|
||||
"digg_count": 12345,
|
||||
"comment_count": 678,
|
||||
"share_count": 90,
|
||||
"play_count": 567890
|
||||
},
|
||||
"music": {
|
||||
"id": "7123456789",
|
||||
"title": "原声",
|
||||
"author": "小鱼小鱼🐟",
|
||||
"play_url": {
|
||||
"url_list": ["https://..."]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 响应字段说明
|
||||
|
||||
##### 根字段
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| code | integer | 状态码,200 表示成功 |
|
||||
| router | string | 路由信息 |
|
||||
| data | object | 视频详细数据 |
|
||||
|
||||
##### data.aweme_detail 核心字段
|
||||
|
||||
| 字段路径 | 类型 | 说明 | 示例值 |
|
||||
|----------|------|------|--------|
|
||||
| **基本信息** |
|
||||
| aweme_id | string | 视频唯一 ID | "7576474555553706981" |
|
||||
| desc | string | 视频描述/标题 | "#美女 #漫展 #cos" |
|
||||
| create_time | integer | 创建时间(Unix 时间戳) | 1764035452 |
|
||||
| duration | integer | 视频时长(毫秒) | 7315 |
|
||||
| **作者信息 (author)** |
|
||||
| author.uid | string | 作者用户 ID | "7558808540429747259" |
|
||||
| author.nickname | string | 作者昵称 | "小鱼小鱼🐟" |
|
||||
| author.signature | string | 作者签名/简介 | "永做真我!" |
|
||||
| author.avatar_thumb.url_list | array | 作者头像 URL 列表 | ["https://..."] |
|
||||
| author.follower_count | integer | 粉丝数 | 2325 |
|
||||
| author.total_favorited | integer | 获赞总数 | 22399 |
|
||||
| author.sec_uid | string | 作者安全 ID(用于分享) | "MS4wLjABAAAA..." |
|
||||
| author.short_id | string | 作者短 ID | "24435946694" |
|
||||
| author.unique_id | string | 作者唯一 ID(抖音号) | "24435946694" |
|
||||
| **视频信息 (video)** |
|
||||
| video.play_addr.url_list | array | **视频播放地址列表(重要)** | ["https://v5-hl..."] |
|
||||
| video.cover_original_scale.url_list | array | **封面图 URL 列表(原始尺寸)** | ["https://p3-pc..."] |
|
||||
| video.duration | integer | 视频时长(毫秒) | 7315 |
|
||||
| video.width | integer | 视频宽度(像素) | 1080 |
|
||||
| video.height | integer | 视频高度(像素) | 1920 |
|
||||
| **统计数据 (statistics)** |
|
||||
| statistics.digg_count | integer | 点赞数 | 12345 |
|
||||
| statistics.comment_count | integer | 评论数 | 678 |
|
||||
| statistics.share_count | integer | 分享数 | 90 |
|
||||
| statistics.play_count | integer | 播放数 | 567890 |
|
||||
| **音乐信息 (music)** |
|
||||
| music.id | string | 音乐 ID | "7123456789" |
|
||||
| music.title | string | 音乐标题 | "原声" |
|
||||
| music.author | string | 音乐作者 | "小鱼小鱼🐟" |
|
||||
| music.play_url.url_list | array | 音乐播放地址列表 | ["https://..."] |
|
||||
|
||||
##### 关键字段提取路径
|
||||
|
||||
**最常用的字段提取代码**:
|
||||
|
||||
```python
|
||||
# 提取视频信息
|
||||
aweme_detail = response.json()["data"]["aweme_detail"]
|
||||
|
||||
# 作者信息
|
||||
author_name = aweme_detail["author"]["nickname"]
|
||||
author_avatar = aweme_detail["author"]["avatar_thumb"]["url_list"][0]
|
||||
author_uid = aweme_detail["author"]["uid"]
|
||||
|
||||
# 视频描述
|
||||
video_desc = aweme_detail["desc"]
|
||||
|
||||
# 封面图(取第一个)
|
||||
cover_url = aweme_detail["video"]["cover_original_scale"]["url_list"][0]
|
||||
|
||||
# 视频播放地址(取第一个,通常是最优质的)
|
||||
video_url = aweme_detail["video"]["play_addr"]["url_list"][0]
|
||||
|
||||
# 视频时长(毫秒)
|
||||
duration_ms = aweme_detail["duration"]
|
||||
duration_sec = duration_ms / 1000 # 转换为秒
|
||||
|
||||
# 统计数据
|
||||
likes = aweme_detail["statistics"]["digg_count"]
|
||||
comments = aweme_detail["statistics"]["comment_count"]
|
||||
shares = aweme_detail["statistics"]["share_count"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 下载视频文件
|
||||
|
||||
直接从抖音分享链接下载视频文件(无水印)。
|
||||
|
||||
#### 请求信息
|
||||
|
||||
- **接口地址**: `/api/download`
|
||||
- **请求方法**: `GET`
|
||||
- **请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||||
|--------|------|------|------|------|
|
||||
| url | string | 是 | 抖音分享链接 | `https://v.douyin.com/FLNGa7kXvMY/` |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```bash
|
||||
GET https://dy.zoomcaronline.net/api/download?url=https://v.douyin.com/FLNGa7kXvMY/
|
||||
```
|
||||
|
||||
```javascript
|
||||
// JavaScript 示例 - 下载视频
|
||||
const response = await fetch('https://dy.zoomcaronline.net/api/download?url=https://v.douyin.com/FLNGa7kXvMY/');
|
||||
const blob = await response.blob();
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = 'douyin_video.mp4';
|
||||
a.click();
|
||||
```
|
||||
|
||||
```python
|
||||
# Python 示例 - 下载视频
|
||||
import requests
|
||||
|
||||
url = "https://dy.zoomcaronline.net/api/download"
|
||||
params = {"url": "https://v.douyin.com/FLNGa7kXvMY/"}
|
||||
response = requests.get(url, params=params)
|
||||
|
||||
# 保存视频文件
|
||||
with open("douyin_video.mp4", "wb") as f:
|
||||
f.write(response.content)
|
||||
```
|
||||
|
||||
```php
|
||||
// PHP 示例 - 下载视频
|
||||
<?php
|
||||
$url = "https://dy.zoomcaronline.net/api/download?url=" . urlencode("https://v.douyin.com/FLNGa7kXvMY/");
|
||||
$videoData = file_get_contents($url);
|
||||
file_put_contents("douyin_video.mp4", $videoData);
|
||||
?>
|
||||
```
|
||||
|
||||
#### 响应信息
|
||||
|
||||
- **Content-Type**: `video/mp4`
|
||||
- **响应体**: 视频文件的二进制数据
|
||||
- **文件格式**: MP4
|
||||
- **特点**: 无水印
|
||||
|
||||
---
|
||||
|
||||
## 完整使用流程
|
||||
|
||||
### 方式一:两步获取(推荐用于需要视频信息的场景)
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
# 步骤 1: 提取视频 ID
|
||||
share_url = "https://v.douyin.com/FLNGa7kXvMY/"
|
||||
response = requests.get(
|
||||
"https://dy.zoomcaronline.net/api/douyin/web/get_aweme_id",
|
||||
params={"url": share_url}
|
||||
)
|
||||
aweme_id = response.json()["data"]
|
||||
|
||||
# 步骤 2: 获取视频详细信息
|
||||
response = requests.get(
|
||||
"https://dy.zoomcaronline.net/api/douyin/web/fetch_one_video",
|
||||
params={"aweme_id": aweme_id}
|
||||
)
|
||||
video_info = response.json()
|
||||
|
||||
# 提取关键信息
|
||||
author_name = video_info["data"]["aweme_detail"]["author"]["nickname"]
|
||||
video_desc = video_info["data"]["aweme_detail"]["desc"]
|
||||
cover_url = video_info["data"]["aweme_detail"]["video"]["cover_original_scale"]["url_list"][0]
|
||||
video_url = video_info["data"]["aweme_detail"]["video"]["play_addr"]["url_list"][0]
|
||||
|
||||
print(f"作者: {author_name}")
|
||||
print(f"描述: {video_desc}")
|
||||
print(f"封面: {cover_url}")
|
||||
print(f"视频: {video_url}")
|
||||
```
|
||||
|
||||
### 方式二:直接下载(推荐用于只需要视频文件的场景)
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
# 直接下载视频
|
||||
share_url = "https://v.douyin.com/FLNGa7kXvMY/"
|
||||
response = requests.get(
|
||||
"https://dy.zoomcaronline.net/api/download",
|
||||
params={"url": share_url}
|
||||
)
|
||||
|
||||
# 保存视频
|
||||
with open("douyin_video.mp4", "wb") as f:
|
||||
f.write(response.content)
|
||||
|
||||
print("视频下载完成")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 抖音分享链接格式
|
||||
|
||||
抖音分享链接通常有以下几种格式:
|
||||
|
||||
1. **短链接格式**(最常见):
|
||||
```
|
||||
https://v.douyin.com/FLNGa7kXvMY/
|
||||
```
|
||||
|
||||
2. **完整链接格式**:
|
||||
```
|
||||
https://www.douyin.com/video/7576474555553706981
|
||||
```
|
||||
|
||||
3. **分享文本格式**(包含额外文字):
|
||||
```
|
||||
2.05 10/31 F@H.VY 错也行 错过也行 过去就行 # 明日方舟 https://v.douyin.com/FLNGa7kXvMY/ 复制此链接,打开Dou音搜索,直接观看视频!
|
||||
```
|
||||
|
||||
**提取建议**: 使用正则表达式提取链接部分:
|
||||
```python
|
||||
import re
|
||||
|
||||
text = "2.05 10/31 F@H.VY https://v.douyin.com/FLNGa7kXvMY/ 复制此链接"
|
||||
pattern = r'https?://v\.douyin\.com/[A-Za-z0-9]+'
|
||||
match = re.search(pattern, text)
|
||||
if match:
|
||||
url = match.group(0)
|
||||
print(url) # https://v.douyin.com/FLNGa7kXvMY/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 错误处理
|
||||
|
||||
### 常见错误码
|
||||
|
||||
| 错误码 | 说明 | 解决方案 |
|
||||
|--------|------|----------|
|
||||
| 200 | 成功 | - |
|
||||
| 400 | 请求参数错误 | 检查 URL 参数是否正确 |
|
||||
| 404 | 视频不存在 | 视频可能已被删除或链接无效 |
|
||||
| 500 | 服务器错误 | 稍后重试 |
|
||||
|
||||
### 错误处理示例
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
def get_douyin_video_info(share_url):
|
||||
try:
|
||||
# 提取视频 ID
|
||||
response = requests.get(
|
||||
"https://dy.zoomcaronline.net/api/douyin/web/get_aweme_id",
|
||||
params={"url": share_url},
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
return {"error": f"HTTP {response.status_code}"}
|
||||
|
||||
result = response.json()
|
||||
if result.get("code") != 200:
|
||||
return {"error": result.get("msg", "未知错误")}
|
||||
|
||||
aweme_id = result.get("data")
|
||||
if not aweme_id:
|
||||
return {"error": "未找到视频 ID"}
|
||||
|
||||
# 获取视频信息
|
||||
response = requests.get(
|
||||
"https://dy.zoomcaronline.net/api/douyin/web/fetch_one_video",
|
||||
params={"aweme_id": aweme_id},
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
return {"error": f"HTTP {response.status_code}"}
|
||||
|
||||
return response.json()
|
||||
|
||||
except requests.Timeout:
|
||||
return {"error": "请求超时"}
|
||||
except requests.RequestException as e:
|
||||
return {"error": f"网络错误: {str(e)}"}
|
||||
except Exception as e:
|
||||
return {"error": f"未知错误: {str(e)}"}
|
||||
|
||||
# 使用示例
|
||||
result = get_douyin_video_info("https://v.douyin.com/FLNGa7kXvMY/")
|
||||
if "error" in result:
|
||||
print(f"错误: {result['error']}")
|
||||
else:
|
||||
print("成功获取视频信息")
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **请求频率限制**: 建议控制请求频率,避免频繁请求导致 IP 被封禁
|
||||
2. **超时设置**: 下载视频时建议设置较长的超时时间(建议 60-600 秒)
|
||||
3. **视频大小**: 下载的视频文件大小通常在 500KB - 50MB 之间
|
||||
4. **链接有效期**: 从 `play_addr.url_list` 获取的视频链接可能有时效性
|
||||
5. **无水印**: 通过 `/api/download` 接口下载的视频为无水印版本
|
||||
6. **SSL 证书**: 如果遇到 SSL 证书验证问题,可以临时禁用验证(不推荐生产环境)
|
||||
|
||||
---
|
||||
|
||||
## 应用场景
|
||||
|
||||
1. **视频下载工具**: 开发抖音视频下载器
|
||||
2. **内容聚合平台**: 聚合抖音视频内容
|
||||
3. **数据分析**: 分析视频数据、作者信息等
|
||||
4. **自动化机器人**: 微信/QQ 机器人自动解析抖音链接
|
||||
5. **视频备份**: 批量备份抖音视频
|
||||
6. **内容审核**: 获取视频信息进行内容审核
|
||||
|
||||
---
|
||||
|
||||
## 技术支持
|
||||
|
||||
- **API 地址**: `https://dy.zoomcaronline.net`
|
||||
- **更新日期**: 2025-11-26
|
||||
- **版本**: v1.0
|
||||
|
||||
---
|
||||
|
||||
## 附录:完整代码示例
|
||||
|
||||
### Node.js 示例
|
||||
|
||||
```javascript
|
||||
const axios = require('axios');
|
||||
const fs = require('fs');
|
||||
|
||||
async function downloadDouyinVideo(shareUrl) {
|
||||
try {
|
||||
// 1. 提取视频 ID
|
||||
const idResponse = await axios.get('https://dy.zoomcaronline.net/api/douyin/web/get_aweme_id', {
|
||||
params: { url: shareUrl }
|
||||
});
|
||||
|
||||
const awemeId = idResponse.data.data;
|
||||
console.log('视频 ID:', awemeId);
|
||||
|
||||
// 2. 获取视频信息
|
||||
const infoResponse = await axios.get('https://dy.zoomcaronline.net/api/douyin/web/fetch_one_video', {
|
||||
params: { aweme_id: awemeId }
|
||||
});
|
||||
|
||||
const videoInfo = infoResponse.data.data.aweme_detail;
|
||||
console.log('作者:', videoInfo.author.nickname);
|
||||
console.log('描述:', videoInfo.desc);
|
||||
|
||||
// 3. 下载视频
|
||||
const videoResponse = await axios.get('https://dy.zoomcaronline.net/api/download', {
|
||||
params: { url: shareUrl },
|
||||
responseType: 'arraybuffer'
|
||||
});
|
||||
|
||||
fs.writeFileSync('douyin_video.mp4', videoResponse.data);
|
||||
console.log('视频下载完成');
|
||||
|
||||
} catch (error) {
|
||||
console.error('错误:', error.message);
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
downloadDouyinVideo('https://v.douyin.com/FLNGa7kXvMY/');
|
||||
```
|
||||
|
||||
### Java 示例
|
||||
|
||||
```java
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import org.json.*;
|
||||
|
||||
public class DouyinDownloader {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String shareUrl = "https://v.douyin.com/FLNGa7kXvMY/";
|
||||
downloadVideo(shareUrl);
|
||||
}
|
||||
|
||||
public static void downloadVideo(String shareUrl) throws Exception {
|
||||
// 1. 提取视频 ID
|
||||
String idUrl = "https://dy.zoomcaronline.net/api/douyin/web/get_aweme_id?url=" +
|
||||
URLEncoder.encode(shareUrl, "UTF-8");
|
||||
String idResponse = sendGetRequest(idUrl);
|
||||
JSONObject idJson = new JSONObject(idResponse);
|
||||
String awemeId = idJson.getString("data");
|
||||
|
||||
System.out.println("视频 ID: " + awemeId);
|
||||
|
||||
// 2. 获取视频信息
|
||||
String infoUrl = "https://dy.zoomcaronline.net/api/douyin/web/fetch_one_video?aweme_id=" + awemeId;
|
||||
String infoResponse = sendGetRequest(infoUrl);
|
||||
JSONObject infoJson = new JSONObject(infoResponse);
|
||||
JSONObject videoInfo = infoJson.getJSONObject("data").getJSONObject("aweme_detail");
|
||||
|
||||
System.out.println("作者: " + videoInfo.getJSONObject("author").getString("nickname"));
|
||||
System.out.println("描述: " + videoInfo.getString("desc"));
|
||||
|
||||
// 3. 下载视频
|
||||
String downloadUrl = "https://dy.zoomcaronline.net/api/download?url=" +
|
||||
URLEncoder.encode(shareUrl, "UTF-8");
|
||||
downloadFile(downloadUrl, "douyin_video.mp4");
|
||||
|
||||
System.out.println("视频下载完成");
|
||||
}
|
||||
|
||||
private static String sendGetRequest(String urlString) throws Exception {
|
||||
URL url = new URL(urlString);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
|
||||
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String inputLine;
|
||||
StringBuilder response = new StringBuilder();
|
||||
|
||||
while ((inputLine = in.readLine()) != null) {
|
||||
response.append(inputLine);
|
||||
}
|
||||
in.close();
|
||||
|
||||
return response.toString();
|
||||
}
|
||||
|
||||
private static void downloadFile(String urlString, String fileName) throws Exception {
|
||||
URL url = new URL(urlString);
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
|
||||
InputStream in = conn.getInputStream();
|
||||
FileOutputStream out = new FileOutputStream(fileName);
|
||||
|
||||
byte[] buffer = new byte[4096];
|
||||
int bytesRead;
|
||||
while ((bytesRead = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, bytesRead);
|
||||
}
|
||||
|
||||
out.close();
|
||||
in.close();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: v1.0
|
||||
**最后更新**: 2025-11-26
|
||||
**维护者**: ShiHao
|
||||
181
开发文档/自部署解析.postman_collection.json
Normal file
181
开发文档/自部署解析.postman_collection.json
Normal file
@@ -0,0 +1,181 @@
|
||||
{
|
||||
"info": {
|
||||
"_postman_id": "19126577-9e30-48ce-ad50-bea77c5f7266",
|
||||
"name": "自部署解析",
|
||||
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
|
||||
"_exporter_id": "49242368",
|
||||
"_collection_link": "https://lixin0229-2646365.postman.co/workspace/shihao's-Workspace~249f47cc-12a0-4152-8c64-d21cf5552a6c/collection/49242368-19126577-9e30-48ce-ad50-bea77c5f7266?action=share&source=collection_link&creator=49242368"
|
||||
},
|
||||
"item": [
|
||||
{
|
||||
"name": "抖音自部署提取视频ID",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://dy.zoomcaronline.net/api/douyin/web/get_aweme_id?url=https://v.douyin.com/KOxslyaGzCY/ 07/10 ZZz:/ L@j.CH",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"dy",
|
||||
"zoomcaronline",
|
||||
"net"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"douyin",
|
||||
"web",
|
||||
"get_aweme_id"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "url",
|
||||
"value": "https://v.douyin.com/KOxslyaGzCY/ 07/10 ZZz:/ L@j.CH"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "抖音自部署获取视频数据",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://dy.zoomcaronline.net/api/douyin/web/fetch_one_video?aweme_id=7576474555553706981",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"dy",
|
||||
"zoomcaronline",
|
||||
"net"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"douyin",
|
||||
"web",
|
||||
"fetch_one_video"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "aweme_id",
|
||||
"value": "7576474555553706981"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "抖音自部署视频下载",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://dy.zoomcaronline.net/api/download?url=https://v.douyin.com/KOxslyaGzCY/ 07/10 ZZz:/ L@j.CH",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"dy",
|
||||
"zoomcaronline",
|
||||
"net"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"download"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "url",
|
||||
"value": "https://v.douyin.com/KOxslyaGzCY/ 07/10 ZZz:/ L@j.CH"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "tiktok自部署提取视频ID",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://dy.zoomcaronline.net/api/tiktok/web/get_aweme_id?url",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"dy",
|
||||
"zoomcaronline",
|
||||
"net"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"tiktok",
|
||||
"web",
|
||||
"get_aweme_id"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "url",
|
||||
"value": null
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "tiktok自部署获取视频数据",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://dy.zoomcaronline.net/api/tiktok/app/fetch_one_video?aweme_id=7556964678446959879",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"dy",
|
||||
"zoomcaronline",
|
||||
"net"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"tiktok",
|
||||
"app",
|
||||
"fetch_one_video"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "aweme_id",
|
||||
"value": "7556964678446959879"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
},
|
||||
{
|
||||
"name": "tiktok自部署视频下载",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [],
|
||||
"url": {
|
||||
"raw": "https://dy.zoomcaronline.net/api/download?url=https://www.tiktok.com/@janice_yoong/video/7556964678446959879?is_from_webapp=1%26sender_device=pc",
|
||||
"protocol": "https",
|
||||
"host": [
|
||||
"dy",
|
||||
"zoomcaronline",
|
||||
"net"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"download"
|
||||
],
|
||||
"query": [
|
||||
{
|
||||
"key": "url",
|
||||
"value": "https://www.tiktok.com/@janice_yoong/video/7556964678446959879?is_from_webapp=1&sender_device=pc"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"response": []
|
||||
}
|
||||
]
|
||||
}
|
||||
4
开发文档/默认SMPT.md
Normal file
4
开发文档/默认SMPT.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Host: smtp.resend.com
|
||||
# Port: 25, 465, 587, 2465, or 2587
|
||||
# Username: resend
|
||||
# Password: re_TSgVYFuT_HG9g3Mu6P4i6LEdYgqVpW6S5
|
||||
Reference in New Issue
Block a user