Files
WeChat-Channels-Video-File-…/api-service/README.md
T
2025-10-17 03:19:05 -07:00

581 lines
15 KiB
Markdown

# WeChat Channels Video Decryption API Service
基于 Playwright 浏览器自动化的 WeChat 视频解密 API 服务
## 概述
本项目提供 RESTful API 接口,用于解密 WeChat Channels 加密视频文件。通过 Playwright 在真实浏览器环境中执行微信官方 WASM 模块,实现 **100% 兼容性**
### 核心特性
- **完美兼容**: 在真实 Chromium 浏览器中执行微信官方 WASM v1.2.46
- **RPC 架构**: Node.js 通过 Playwright 调用浏览器环境中的解密函数
- **RESTful API**: 标准的 HTTP 接口,易于集成
- **Docker 支持**: 开箱即用的容器化部署
- **健康检查**: 内置服务健康监控
- **大文件支持**: 最大支持 500MB 视频文件
## 架构说明
```
┌─────────────────────────────────────────────────────┐
│ Client Request │
└───────────────────┬─────────────────────────────────┘
┌─────────────────────────────────────────────────────┐
│ Express.js API Server │
│ (Node.js + Multer + CORS) │
└───────────────────┬─────────────────────────────────┘
│ RPC Call via page.evaluate()
┌─────────────────────────────────────────────────────┐
│ Playwright Chromium Browser │
│ ┌───────────────────────────────────────────┐ │
│ │ worker.html │ │
│ │ ┌─────────────────────────────────┐ │ │
│ │ │ WeChat WASM Module v1.2.46 │ │ │
│ │ │ (Isaac64 PRNG Algorithm) │ │ │
│ │ └─────────────────────────────────┘ │ │
│ │ │ │
│ │ RPC Functions: │ │
│ │ - generateKeystream(decodeKey) │ │
│ │ - decryptVideo(encrypted, keystream) │ │
│ │ - checkWasmStatus() │ │
│ └───────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
```
### 为什么选择 Playwright?
WeChat 的 WASM 模块依赖浏览器特定的 API (`fetch`, `self`, `window` 等),无法直接在 Node.js 环境中运行。Playwright 方案的优势:
1. **完美兼容**: 在真实浏览器中运行,避免环境模拟的兼容性问题
2. **本地优先**: 内置 WASM 文件,优先使用本地加载(速度更快,离线可用)
3. **智能降级**: 本地文件加载失败时自动切换到微信 CDN
4. **可维护性**: 微信更新 WASM 版本时,更新 wechat_files 文件夹即可
5. **稳定性**: 浏览器环境确保 WASM 按预期运行
性能权衡: 虽然通过浏览器调用会增加一些开销,但换来的是完美的兼容性和稳定性。
## 📖 API 文档页面
启动服务后,访问 **http://localhost:3000** 可查看完整的交互式 API 文档,包含:
- 📊 **实时服务状态** - WASM 模块健康检查和服务信息
- 🔌 **完整 API 端点** - 所有接口的详细说明和参数
- 💡 **代码示例** - Python、JavaScript/Node.js 等多种语言
- 🎨 **美观界面** - 渐变色设计、代码高亮、响应式布局
**或使用 JSON 格式查看服务信息:**
```bash
curl http://localhost:3000/api/info
```
## 快速开始
### 方式 1: Docker 部署 (推荐)
```bash
# 1. 构建并启动服务
docker-compose up -d
# 2. 查看日志
docker-compose logs -f
# 3. 健康检查
curl http://localhost:3000/health
# 4. 停止服务
docker-compose down
```
### 方式 2: 本地开发
#### 前置要求
- Node.js >= 16.0.0
- npm >= 7.0.0
#### 安装步骤
```bash
# 1. 安装依赖
npm install
# 2. 安装 Playwright 浏览器
npm run install-browsers
# 3. 启动服务
npm start
# 开发模式 (热重载)
npm run dev
```
服务将在 `http://localhost:3000` 启动。
## API 文档
### 1. 服务信息
```http
GET /
```
返回服务的基本信息和可用端点列表。
**响应示例:**
```json
{
"service": "WeChat Channels Video Decryption API",
"version": "2.0.0",
"engine": "Playwright + Chromium",
"author": "Evil0ctal",
"endpoints": {
"health": "GET /health",
"decrypt": "POST /api/decrypt",
"keystream": "POST /api/keystream"
}
}
```
### 2. 健康检查
```http
GET /health
```
检查服务和 WASM 模块的状态。
**响应示例:**
```json
{
"status": "ok",
"service": "wechat-decrypt-api",
"version": "2.0.0",
"engine": "playwright",
"wasm": {
"loaded": true,
"timestamp": "2024-01-15T10:30:00.000Z"
},
"timestamp": "2024-01-15T10:30:00.000Z"
}
```
### 3. 生成密钥流
```http
POST /api/keystream
Content-Type: application/json
```
**请求体:**
```json
{
"decode_key": "123456789",
"format": "hex"
}
```
**参数说明:**
- `decode_key` (必需): 解密密钥,字符串或数字
- `format` (可选): 输出格式,`hex``base64`,默认 `hex`
**响应示例:**
```json
{
"decode_key": "123456789",
"keystream": "a1b2c3d4e5f6...",
"format": "hex",
"size": 131072,
"duration_ms": 45,
"timestamp": "2024-01-15T10:30:00.000Z"
}
```
**cURL 示例:**
```bash
curl -X POST http://localhost:3000/api/keystream \
-H "Content-Type: application/json" \
-d '{"decode_key": "123456789", "format": "hex"}'
```
### 4. 解密视频
```http
POST /api/decrypt
Content-Type: multipart/form-data
```
**表单参数:**
- `decode_key`: 解密密钥 (form field)
- `video`: 加密的视频文件 (file upload)
**响应:**
- Content-Type: `video/mp4`
- 返回解密后的 MP4 视频文件
**cURL 示例:**
```bash
curl -X POST http://localhost:3000/api/decrypt \
-F "decode_key=123456789" \
-F "video=@encrypted_video.mp4" \
-o decrypted_video.mp4
```
**响应头:**
```
Content-Type: video/mp4
Content-Length: 12345678
Content-Disposition: attachment; filename="decrypted_1705315800000.mp4"
X-Decrypt-Duration: 1234
```
**错误响应:**
```json
{
"error": "解密失败:未找到 MP4 ftyp 签名,请检查 decode_key"
}
```
## 使用示例
### Python 示例
```python
import requests
# 解密视频
with open('encrypted_video.mp4', 'rb') as f:
files = {'video': f}
data = {'decode_key': '123456789'}
response = requests.post(
'http://localhost:3000/api/decrypt',
files=files,
data=data
)
if response.status_code == 200:
with open('decrypted.mp4', 'wb') as out:
out.write(response.content)
print('解密成功!')
else:
print(f'解密失败: {response.json()}')
# 生成密钥流
response = requests.post(
'http://localhost:3000/api/keystream',
json={'decode_key': '123456789', 'format': 'hex'}
)
print(response.json())
```
### JavaScript/Node.js 示例
```javascript
const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');
// 解密视频
async function decryptVideo() {
const form = new FormData();
form.append('decode_key', '123456789');
form.append('video', fs.createReadStream('encrypted_video.mp4'));
const response = await axios.post(
'http://localhost:3000/api/decrypt',
form,
{
headers: form.getHeaders(),
responseType: 'stream'
}
);
response.data.pipe(fs.createWriteStream('decrypted.mp4'));
}
// 生成密钥流
async function generateKeystream() {
const response = await axios.post(
'http://localhost:3000/api/keystream',
{
decode_key: '123456789',
format: 'hex'
}
);
console.log(response.data);
}
```
## Docker 配置
### 资源限制
`docker-compose.yml` 中配置的默认资源限制:
```yaml
deploy:
resources:
limits:
cpus: '2'
memory: 2G
reservations:
cpus: '1'
memory: 512M
```
### 环境变量
| 变量 | 说明 | 默认值 |
|------|------|--------|
| `PORT` | 服务监听端口 | `3000` |
| `NODE_ENV` | Node.js 环境 | `production` |
### 共享内存
Chromium 需要足够的共享内存,已在 docker-compose.yml 中配置:
```yaml
shm_size: '2gb'
```
## 技术栈
- **Node.js**: JavaScript 运行时
- **Express**: Web 框架
- **Playwright**: 浏览器自动化
- **Multer**: 文件上传处理
- **CORS**: 跨域资源共享
- **Docker**: 容器化部署
## 文件结构
```
api-service/
├── server.js # Express API 服务器
├── worker.html # RPC Worker 页面 (包含 WASM)
├── docs.html # 交互式 API 文档页面
├── package.json # 项目依赖
├── Dockerfile # Docker 镜像构建
├── docker-compose.yml # Docker Compose 配置
├── .dockerignore # Docker 忽略文件
├── .gitignore # Git 忽略文件
└── README.md # 本文档
```
## 工作原理
### 1. WASM 模块加载 (本地优先 + CDN 降级)
`worker.html` 实现了智能的双重加载机制:
```html
<script>
// 优先使用本地文件
window.VTS_WASM_URL = 'wechat_files/wasm_video_decode.wasm';
// CDN 备份
window.VTS_WASM_CDN_URL = "https://aladin.wxqcloud.qq.com/aladin/ffmepeg/video-decode/1.2.46/wasm_video_decode.wasm";
// 错误处理:本地加载失败时自动切换到 CDN
function handleWasmScriptError() {
console.warn('本地 WASM JS 加载失败,切换到微信 CDN...');
window.WASM_USING_CDN = true;
// ... 动态加载 CDN 脚本
}
</script>
<!-- 优先尝试本地文件 -->
<script src="wechat_files/wasm_video_decode.js" onerror="handleWasmScriptError()"></script>
```
**优点:**
- ⚡ 本地加载速度更快(无网络延迟)
- 🔒 离线环境也能工作
- 🛡️ 降低对外部 CDN 的依赖
- ♻️ 自动降级保证可用性
### 2. HTTP 服务与 RPC 调用
Express 服务器提供三个关键端点:
```javascript
// 1. 静态文件服务 - 提供 WASM 文件
app.use('/wechat_files', express.static(path.join(__dirname, 'wechat_files')));
// 2. Worker HTML 页面
app.get('/worker.html', (req, res) => {
res.sendFile(path.join(__dirname, 'worker.html'));
});
// 3. Playwright 通过 HTTP 加载 worker(支持本地文件加载)
const workerUrl = `http://localhost:${PORT}/worker.html`;
await page.goto(workerUrl);
```
RPC 调用浏览器函数:
```javascript
// 在 Node.js 中调用浏览器中的函数
const keystreamBase64 = await page.evaluate(async (key) => {
return await window.generateKeystream(key);
}, decode_key);
```
**关键**: 使用 `http://` 而非 `file://` 协议,避免浏览器 CORS 限制,使本地 WASM 文件加载成功。
### 3. 数据传输
使用 Base64 编码在 Node.js 和浏览器之间传输二进制数据:
```javascript
// Node.js → Browser
const encryptedBase64 = videoFile.buffer.toString('base64');
// Browser → Node.js
const decryptedBase64 = await page.evaluate(...);
const decrypted = Buffer.from(decryptedBase64, 'base64');
```
### 4. Isaac64 密钥流生成
WASM 模块实现了微信魔改的 Isaac64 算法:
```javascript
window.wasm_isaac_generate = function(ptr, size) {
keystreamData = new Uint8Array(size);
const wasmArray = new Uint8Array(Module.HEAPU8.buffer, ptr, size);
keystreamData.set(Array.from(wasmArray).reverse()); // 必须反转!
};
```
**重要**: 密钥流必须反转 (`reverse()`) 才能正确解密,这是微信特有的实现细节。
### 5. XOR 解密
前 128KB 数据通过 XOR 操作解密:
```javascript
for (let i = 0; i < 131072 && i < encrypted.length; i++) {
decrypted[i] = encrypted[i] ^ keystream[i];
}
```
## 故障排除
### 问题: WASM 模块加载超时
**症状**:
```json
{"status": "error", "error": "WASM 模块加载超时"}
```
**解决方案**:
1. 检查网络连接,确保能访问微信 CDN
2. 增加超时时间 (server.js:58)
3. 检查 Playwright 浏览器是否正确安装
### 问题: Docker 容器启动失败
**症状**: 容器持续重启
**解决方案**:
```bash
# 查看详细日志
docker-compose logs -f
# 检查浏览器安装
docker-compose exec wechat-decrypt-api npx playwright --version
# 重新构建镜像
docker-compose build --no-cache
```
### 问题: 解密后的视频无法播放
**症状**: API 返回文件但无法播放
**原因**: `decode_key` 不正确
**解决方案**:
1. 确认 decode_key 与加密视频匹配
2. 检查 API 响应中的错误信息
3. 验证解密文件的前 12 字节应为: `00 00 00 XX 66 74 79 70` (MP4 签名)
### 问题: 文件上传失败 (413 错误)
**症状**:
```json
{"error": "文件过大", "limit": "500MB"}
```
**解决方案**:
修改 server.js:23 中的文件大小限制:
```javascript
limits: { fileSize: 500 * 1024 * 1024 } // 500MB
```
## 性能优化建议
### 1. 复用浏览器实例
当前实现已自动复用浏览器实例,避免每次请求都启动新浏览器。
### 2. 调整资源限制
根据服务器配置调整 docker-compose.yml 中的资源限制:
```yaml
deploy:
resources:
limits:
cpus: '4' # 增加 CPU 限制
memory: 4G # 增加内存限制
```
### 3. 启用请求缓存
对于相同的 decode_key,可以缓存生成的密钥流以提高性能。
### 4. 负载均衡
对于高并发场景,可部署多个服务实例并使用负载均衡器。
## 安全建议
1. **API 认证**: 在生产环境中添加 API 密钥认证
2. **速率限制**: 使用 express-rate-limit 限制请求频率
3. **HTTPS**: 使用反向代理 (Nginx/Caddy) 提供 HTTPS 支持
4. **文件验证**: 验证上传文件的类型和内容
5. **日志审计**: 记录所有 API 请求用于审计
## 许可证
MIT License - 详见项目根目录 LICENSE 文件
## 作者
Evil0ctal - evil0ctal1985@gmail.com
## 相关链接
- GitHub: https://github.com/Evil0ctal/WeChat-Channels-Video-File-Decryption
- Playwright: https://playwright.dev/
- WeChat WASM: https://aladin.wxqcloud.qq.com/aladin/ffmepeg/video-decode/1.2.46/
## 更新日志
### v2.0.0 (2025-10-17)
- 采用 Playwright + RPC 架构
- 100% 兼容微信官方 WASM v1.2.46
- **内置 WASM 文件**: 本地优先加载,CDN 智能降级
- **HTTP 服务架构**: 避免 file:// 协议的 CORS 限制
- Docker 容器化支持(包含完整 WASM 文件)
- 健康检查和监控(显示 WASM 加载源)
- 交互式 API 文档页面
- 完整的错误处理和降级机制