Files
nepiedg 1b8ff310eb Add media proxy feature for resource downloading
- Introduced a new API endpoint `GET /api/v1/video/proxy` to facilitate media resource downloads, allowing users to bypass domain restrictions imposed by WeChat.
- Updated configuration to include proxy settings such as `SHORT_VIDEO_PROXY_ENABLED`, `SHORT_VIDEO_PROXY_ALLOWED_DOMAINS`, `SHORT_VIDEO_PROXY_MAX_SIZE_MB`, and `SHORT_VIDEO_PROXY_TIMEOUT_SECONDS`.
- Enhanced the `ShortVideoConfig` struct to accommodate new proxy-related fields.
- Improved error handling for proxy requests, including checks for allowed domains and file size limits.
- Updated documentation to reflect the new proxy functionality and its configuration options, ensuring clarity for users and developers.
2026-02-06 11:28:02 +00:00

225 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 去水印服务 API 说明
所有接口均位于 `/api/v1`,除登录外都需要在 Header 中携带 `Authorization: Bearer <session_key>`,其中 `<session_key>` 来自登录接口的响应。
## 1. 登录(复用已有接口)
`POST /api/v1/auth/login`
登录与认证的公共说明见:`docs/common/auth.md`
## 接口
### `POST /api/v1/auth/login`
- **说明**:接收小程序端 `wx.login` 返回的 `code`,向微信 `jscode2session` 请求 `openid` / `session_key`。若 `open_id` 不存在则创建用户,存在则更新资料并返回用户信息。
- **请求体**
```json
{
"mini_program_id": 1,
"code": "wx.login返回的code",
"nickname": "可选",
"avatar_url": "可选",
"gender": 1,
"phone": "110"
}
```
## 2. 解析短视频去水印
`POST /api/v1/video/remove_watermark`
| 项目 | 说明 |
| --- | --- |
| Header | `Authorization: Bearer <session_key>` |
| 请求体 | `{"content":"帮我解析 https://v.douyin.com/xxxx/"}` |
| 必填校验 | `content` 必须包含一个合法的 http/https 链接 |
| 响应 | `provider` 固定为 `23bt``raw` 为第三方原始 JSON`free_quota_used` 表示是否占用免费额度 |
curl 示例:
```bash
curl -X POST 'http://127.0.0.1:8080/api/v1/video/remove_watermark' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer wx-session-key' \
-d '{"content":"帮我解析 https://v.douyin.com/xxxx/"}'
```
**成功示例**
```json
{
"code": 200,
"message": "success",
"data": {
"provider": "23bt",
"raw": {
"code": 200,
"msg": "解析成功",
"data": { "...第三方原始字段..." }
},
"free_quota_used": true
}
}
```
**错误返回**
| HTTP 码 | code | message | 说明 |
| --- | --- | --- | --- |
| 400 | 400 | `请求参数错误` / `请检查分享链接是否正确` | 请求体非法或内容未包含有效链接 |
| 401 | 401 | `未登录或登录已过期` | Token 缺失/失效 |
| 403 | 403 | `今日免费次数已用完,观看广告后今天可无限制使用` | 超过每日免费额度,需要走广告解锁 |
| 502 | 502 | `解析服务异常,请稍后重试` | 第三方返回异常 |
| 503 | 503 | `服务暂不可用,请联系管理员` | 未配置 `SHORT_VIDEO_API_KEY` 等关键配置 |
| 500 | 500 | `去水印失败,请稍后重试` | 其他内部错误 |
## 3. 完成广告解锁
`POST /api/v1/video/remove_watermark/unlock`
| 项目 | 说明 |
| --- | --- |
| Header | `Authorization: Bearer <session_key>` |
| 请求体 | 空 |
| 响应 | `{"code":200,"message":"success","data":{"unlocked":true}}` |
curl 示例:
```bash
curl -X POST 'http://127.0.0.1:8080/api/v1/video/remove_watermark/unlock' \
-H 'Authorization: Bearer wx-session-key'
```
说明:调用该接口表示用户当天已经观看完广告,服务端会写入 `video_parse_unlocks`,当天余下时间不再校验免费额度。
## 4. 数据落地
- 每次解析调用都会写入 `video_parse_logs`,其中包含 `request_content``parsed_url`、第三方响应、调用耗时等字段,便于审计和配额统计。
- 第三方返回的 JSON 直接保存在 `video_parse_logs.third_party_payload` 字段,可通过 SQL 查询和脱敏。
- SQL DDL 位于 `docs/sql/remove_watermark.sql`,部署数据库时执行即可。
## 5. 下载失败上报
`POST /api/v1/video/remove_watermark/report_failure`
| 项目 | 说明 |
| --- | --- |
| Header | 可为空(供内部服务调用),也可附加 `Content-Type: application/json` |
| 请求体 | `{ "domain": "example.com", "failedUrl": "https://example.com/video.mp4", "errorMessage": "403 from CDN", "timestamp": 1728034710000, "userAgent": "miniprogram" }` |
| 响应 | `{"code":200,"message":"success","data":{"reported":true}}` |
字段说明:
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `domain` | string,可选 | 失败 URL 所属域名,若缺失会自动从 `failedUrl` 解析 |
| `failedUrl` | string,必填 | 下载失败的完整地址 |
| `errorMessage` | string,可选 | 失败原因描述,建议包含第三方响应 |
| `timestamp` | number,可选 | 失败发生时间,毫秒级 Unix 时间戳。默认使用服务端接收时间。 |
| `userAgent` | string,可选 | 报告端的 UA,默认取 HTTP 头 |
服务端会额外记录请求来源 IP`client_ip`),并存入 `video_download_failures` 表,便于后续排查白名单或 CDN 问题。
## 6. 媒体代理下载
`GET /api/v1/video/proxy`
该接口用于代理媒体资源(视频/图片等)的下载,使小程序可以通过当前服务域名下载资源,避免微信对第三方域名的限制。
| 项目 | 说明 |
| --- | --- |
| Header | 无需鉴权 |
| Query 参数 | `url` - 需要代理的原始媒体地址(必填,需 URL 编码) |
| 响应 | 流式返回原始媒体内容,Content-Type 与源文件一致 |
curl 示例:
```bash
# 代理视频下载
curl -L 'http://127.0.0.1:8080/api/v1/video/proxy?url=https%3A%2F%2Fexample.com%2Fvideo.mp4' \
-o video.mp4
# 代理图片下载
curl -L 'http://127.0.0.1:8080/api/v1/video/proxy?url=https%3A%2F%2Fexample.com%2Fcover.jpg' \
-o cover.jpg
```
小程序端使用示例:
```javascript
// 使用 wx.downloadFile 下载
const proxyUrl = 'https://your-domain.com/api/v1/video/proxy';
const originalUrl = 'https://cdn.example.com/video.mp4';
wx.downloadFile({
url: `${proxyUrl}?url=${encodeURIComponent(originalUrl)}`,
success(res) {
if (res.statusCode === 200) {
// 下载成功,res.tempFilePath 为临时文件路径
wx.saveVideoToPhotosAlbum({
filePath: res.tempFilePath,
success() {
wx.showToast({ title: '保存成功' });
}
});
}
},
fail(err) {
console.error('下载失败', err);
}
});
```
**成功响应**
- HTTP 状态码:200
- Content-Type:与源文件一致(如 `video/mp4``image/jpeg`
- Body:媒体文件二进制流
**错误返回**
| HTTP 码 | code | message | 说明 |
| --- | --- | --- | --- |
| 400 | 400 | `请求参数错误,缺少 url 参数` | 未传 `url` 参数 |
| 400 | 400 | `无效的代理地址` | URL 格式不正确或协议不支持 |
| 403 | 403 | `该域名不在允许列表中` | 目标域名未在白名单内 |
| 413 | 413 | `文件过大,超出限制` | 文件大小超过配置的最大值 |
| 502 | 502 | `上游服务返回错误` | 源服务器返回非 2xx 状态码 |
| 503 | 503 | `代理服务未启用` | 代理功能被禁用 |
| 500 | 500 | `代理请求失败` | 其他内部错误 |
**配置项**
可通过环境变量配置代理行为:
| 环境变量 | 默认值 | 说明 |
| --- | --- | --- |
| `SHORT_VIDEO_PROXY_ENABLED` | `true` | 是否启用代理功能 |
| `SHORT_VIDEO_PROXY_ALLOWED_DOMAINS` | 空(允许所有) | 允许代理的域名白名单,多个用逗号分隔 |
| `SHORT_VIDEO_PROXY_MAX_SIZE_MB` | `100` | 代理文件最大大小(MB |
| `SHORT_VIDEO_PROXY_TIMEOUT_SECONDS` | `60` | 代理请求超时时间(秒) |
配置示例(`.env`):
```bash
# 启用代理
SHORT_VIDEO_PROXY_ENABLED=true
# 限制只能代理特定域名(安全推荐)
SHORT_VIDEO_PROXY_ALLOWED_DOMAINS=cdn.example.com,video.example.com,aweme.snssdk.com
# 最大文件 200MB
SHORT_VIDEO_PROXY_MAX_SIZE_MB=200
# 超时 120 秒
SHORT_VIDEO_PROXY_TIMEOUT_SECONDS=120
```
**安全建议**
1. **配置域名白名单**:强烈建议配置 `SHORT_VIDEO_PROXY_ALLOWED_DOMAINS`,只允许代理已知的 CDN 域名,防止被滥用为开放代理。
2. **设置合理的文件大小限制**:根据实际需求设置 `SHORT_VIDEO_PROXY_MAX_SIZE_MB`,避免服务器带宽被大文件消耗。
3. **监控带宽使用**:代理功能会消耗服务器带宽,建议监控流量并设置告警。