1b8ff310eb
- 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.
7.6 KiB
7.6 KiB
去水印服务 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不存在则创建用户,存在则更新资料并返回用户信息。 - 请求体
{
"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 示例:
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/"}'
成功示例
{
"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 示例:
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 示例:
# 代理视频下载
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
小程序端使用示例:
// 使用 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):
# 启用代理
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
安全建议
- 配置域名白名单:强烈建议配置
SHORT_VIDEO_PROXY_ALLOWED_DOMAINS,只允许代理已知的 CDN 域名,防止被滥用为开放代理。 - 设置合理的文件大小限制:根据实际需求设置
SHORT_VIDEO_PROXY_MAX_SIZE_MB,避免服务器带宽被大文件消耗。 - 监控带宽使用:代理功能会消耗服务器带宽,建议监控流量并设置告警。