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

15 KiB
Raw Blame History

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 格式查看服务信息:

curl http://localhost:3000/api/info

快速开始

方式 1: Docker 部署 (推荐)

# 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

安装步骤

# 1. 安装依赖
npm install

# 2. 安装 Playwright 浏览器
npm run install-browsers

# 3. 启动服务
npm start

# 开发模式 (热重载)
npm run dev

服务将在 http://localhost:3000 启动。

API 文档

1. 服务信息

GET /

返回服务的基本信息和可用端点列表。

响应示例:

{
  "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. 健康检查

GET /health

检查服务和 WASM 模块的状态。

响应示例:

{
  "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. 生成密钥流

POST /api/keystream
Content-Type: application/json

请求体:

{
  "decode_key": "123456789",
  "format": "hex"
}

参数说明:

  • decode_key (必需): 解密密钥,字符串或数字
  • format (可选): 输出格式,hexbase64,默认 hex

响应示例:

{
  "decode_key": "123456789",
  "keystream": "a1b2c3d4e5f6...",
  "format": "hex",
  "size": 131072,
  "duration_ms": 45,
  "timestamp": "2024-01-15T10:30:00.000Z"
}

cURL 示例:

curl -X POST http://localhost:3000/api/keystream \
  -H "Content-Type: application/json" \
  -d '{"decode_key": "123456789", "format": "hex"}'

4. 解密视频

POST /api/decrypt
Content-Type: multipart/form-data

表单参数:

  • decode_key: 解密密钥 (form field)
  • video: 加密的视频文件 (file upload)

响应:

  • Content-Type: video/mp4
  • 返回解密后的 MP4 视频文件

cURL 示例:

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

错误响应:

{
  "error": "解密失败:未找到 MP4 ftyp 签名,请检查 decode_key"
}

使用示例

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 示例

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 中配置的默认资源限制:

deploy:
  resources:
    limits:
      cpus: '2'
      memory: 2G
    reservations:
      cpus: '1'
      memory: 512M

环境变量

变量 说明 默认值
PORT 服务监听端口 3000
NODE_ENV Node.js 环境 production

共享内存

Chromium 需要足够的共享内存,已在 docker-compose.yml 中配置:

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 实现了智能的双重加载机制:

<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 服务器提供三个关键端点:

// 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 调用浏览器函数:

// 在 Node.js 中调用浏览器中的函数
const keystreamBase64 = await page.evaluate(async (key) => {
    return await window.generateKeystream(key);
}, decode_key);

关键: 使用 http:// 而非 file:// 协议,避免浏览器 CORS 限制,使本地 WASM 文件加载成功。

3. 数据传输

使用 Base64 编码在 Node.js 和浏览器之间传输二进制数据:

// 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 算法:

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 操作解密:

for (let i = 0; i < 131072 && i < encrypted.length; i++) {
    decrypted[i] = encrypted[i] ^ keystream[i];
}

故障排除

问题: WASM 模块加载超时

症状:

{"status": "error", "error": "WASM 模块加载超时"}

解决方案:

  1. 检查网络连接,确保能访问微信 CDN
  2. 增加超时时间 (server.js:58)
  3. 检查 Playwright 浏览器是否正确安装

问题: Docker 容器启动失败

症状: 容器持续重启

解决方案:

# 查看详细日志
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 错误)

症状:

{"error": "文件过大", "limit": "500MB"}

解决方案: 修改 server.js:23 中的文件大小限制:

limits: { fileSize: 500 * 1024 * 1024 } // 500MB

性能优化建议

1. 复用浏览器实例

当前实现已自动复用浏览器实例,避免每次请求都启动新浏览器。

2. 调整资源限制

根据服务器配置调整 docker-compose.yml 中的资源限制:

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

相关链接

更新日志

v2.0.0 (2025-10-17)

  • 采用 Playwright + RPC 架构
  • 100% 兼容微信官方 WASM v1.2.46
  • 内置 WASM 文件: 本地优先加载CDN 智能降级
  • HTTP 服务架构: 避免 file:// 协议的 CORS 限制
  • Docker 容器化支持(包含完整 WASM 文件)
  • 健康检查和监控(显示 WASM 加载源)
  • 交互式 API 文档页面
  • 完整的错误处理和降级机制