# 去水印服务 API 说明 所有接口均位于 `/api/v1`,除登录外都需要在 Header 中携带 `Authorization: Bearer `,其中 `` 来自登录接口的响应。 ## 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 ` | | 请求体 | `{"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 ` | | 请求体 | 空 | | 响应 | `{"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. **监控带宽使用**:代理功能会消耗服务器带宽,建议监控流量并设置告警。