# 多平台视频发布服务

基于 [matrix](https://github.com/kebenxiaoming/matrix) 项目，使用 Python + Playwright 实现多平台视频发布功能。

## 支持平台

| 平台 | 模块 | 发布方式 | 说明 |
|------|------|----------|------|
| 抖音 | `platforms/douyin.py` | Playwright | 浏览器自动化 |
| 小红书 | `platforms/xiaohongshu.py` | API + Playwright | 优先使用 xhs SDK，更稳定 |
| 视频号 | `platforms/weixin.py` | Playwright | 需要 Chrome 浏览器 |
| 快手 | `platforms/kuaishou.py` | Playwright | 浏览器自动化 |

## 项目结构

```
server/python/
├── app.py                  # Flask 统一入口
├── requirements.txt        # 依赖文件
├── README.md              # 说明文档
├── platforms/             # 平台发布模块
│   ├── __init__.py        # 模块入口
│   ├── base.py            # 发布器基类
│   ├── douyin.py          # 抖音发布器
│   ├── xiaohongshu.py     # 小红书发布器
│   ├── weixin.py          # 视频号发布器
│   └── kuaishou.py        # 快手发布器
└── utils/                 # 工具模块
    ├── __init__.py
    └── helpers.py         # 工具函数
```

## 环境要求

- Python 3.8 或更高版本
- Windows 10+, macOS 12+, 或 Linux (Ubuntu 20.04+)

## 安装步骤

### 1. 创建虚拟环境

#### Windows (PowerShell)

```powershell
# 进入 python 目录
cd server\python

# 创建虚拟环境
python -m venv venv

# 激活虚拟环境
.\venv\Scripts\Activate.ps1

# 如果遇到执行策略问题，先运行：
# Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```

#### Windows (CMD)

```cmd
cd server\python
python -m venv venv
venv\Scripts\activate.bat
```

#### Linux / macOS

```bash
cd server/python

# 创建虚拟环境
python3 -m venv venv

# 激活虚拟环境
source venv/bin/activate
```

### 2. 安装依赖

```bash
# 确保已激活虚拟环境
pip install -r requirements.txt

# 安装 Playwright 浏览器
playwright install chromium

# 如果在 Linux 服务器上，还需要安装系统依赖
playwright install-deps chromium
```

### 3. 启动服务

```bash
# 默认启动（headless 模式，端口 5005）
python app.py

# 指定端口
python app.py --port 8080

# 显示浏览器窗口（调试用）
python app.py --headless false

# 调试模式
python app.py --debug
```

## API 接口

### 健康检查

```
GET /health

响应:
{
  "status": "ok",
  "xhs_sdk": true,
  "supported_platforms": ["douyin", "xiaohongshu", "weixin", "kuaishou"],
  "headless_mode": true
}
```

### 发布视频

```
POST /publish
Content-Type: application/json

{
  "platform": "douyin",              // douyin | xiaohongshu | weixin | kuaishou
  "cookie": "cookie字符串或JSON数组",
  "title": "视频标题",
  "description": "视频描述（可选）",
  "video_path": "E:/videos/test.mp4", // 视频绝对路径
  "cover_path": "E:/images/cover.jpg", // 封面绝对路径（可选）
  "tags": ["话题1", "话题2"],
  "post_time": "2024-01-20 12:00:00",  // 定时发布（可选）
  "location": "重庆市"                   // 位置（可选）
}

响应:
{
  "success": true,
  "platform": "douyin",
  "video_id": "xxx",
  "video_url": "xxx",
  "message": "发布成功"
}
```

### 批量发布（多平台）

```
POST /publish/batch
Content-Type: application/json

{
  "platforms": ["douyin", "xiaohongshu"],
  "cookies": {
    "douyin": "cookie字符串",
    "xiaohongshu": "cookie字符串"
  },
  "title": "视频标题",
  "video_path": "E:/videos/test.mp4",
  "tags": ["话题1", "话题2"]
}

响应:
{
  "success": true,
  "total": 2,
  "success_count": 2,
  "fail_count": 0,
  "results": [
    {"platform": "douyin", "success": true, "message": "发布成功"},
    {"platform": "xiaohongshu", "success": true, "message": "发布成功"}
  ]
}
```

### 小红书签名

```
POST /sign
Content-Type: application/json

{
  "uri": "API路径",
  "data": "请求数据",
  "a1": "a1 cookie",
  "web_session": "web_session cookie"
}

响应:
{
  "x-s": "签名值",
  "x-t": "时间戳"
}
```

### 检查 Cookie

```
POST /check_cookie
Content-Type: application/json

{
  "platform": "xiaohongshu",
  "cookie": "cookie字符串"
}

响应:
{
  "valid": true,
  "user_info": {
    "user_id": "xxx",
    "nickname": "昵称",
    "avatar": "头像URL"
  }
}
```

### 获取作品列表

```
POST /works
Content-Type: application/json

{
  "platform": "douyin",           // douyin | xiaohongshu | kuaishou | weixin
  "cookie": "cookie字符串或JSON",
  "page": 0,                      // 页码（从0开始，可选，默认0）
  "page_size": 20                 // 每页数量（可选，默认20）
}

响应:
{
  "success": true,
  "platform": "douyin",
  "works": [
    {
      "work_id": "作品ID",
      "title": "作品标题",
      "cover_url": "封面URL",
      "video_url": "视频URL",
      "duration": 60,
      "status": "published",      // published | reviewing | rejected | draft
      "publish_time": "2024-01-20 12:00:00",
      "play_count": 1000,
      "like_count": 100,
      "comment_count": 50,
      "share_count": 20,
      "collect_count": 10
    }
  ],
  "total": 100,
  "has_more": true
}
```

### 获取作品评论

```
POST /comments
Content-Type: application/json

{
  "platform": "douyin",           // douyin | xiaohongshu | kuaishou | weixin
  "cookie": "cookie字符串或JSON",
  "work_id": "作品ID",
  "cursor": ""                    // 分页游标（可选，用于翻页）
}

响应:
{
  "success": true,
  "platform": "douyin",
  "work_id": "作品ID",
  "comments": [
    {
      "comment_id": "评论ID",
      "work_id": "作品ID",
      "content": "评论内容",
      "author_id": "作者ID",
      "author_name": "作者昵称",
      "author_avatar": "作者头像",
      "like_count": 10,
      "reply_count": 5,
      "create_time": "2024-01-20 12:00:00",
      "is_author": false,
      "replies": [
        {
          "comment_id": "子评论ID",
          "content": "回复内容",
          ...
        }
      ]
    }
  ],
  "total": 50,
  "has_more": true,
  "cursor": "下一页游标"
}
```

## 扩展新平台

如需添加新平台，请按以下步骤：

1. 在 `platforms/` 目录创建新文件，如 `bilibili.py`
2. 继承 `BasePublisher` 基类
3. 实现 `publish` 方法
4. 在 `platforms/__init__.py` 中注册

示例：

```python
# platforms/bilibili.py
from .base import BasePublisher, PublishParams, PublishResult

class BilibiliPublisher(BasePublisher):
    platform_name = "bilibili"
    login_url = "https://account.bilibili.com/"
    publish_url = "https://member.bilibili.com/platform/upload/video/frame"
    cookie_domain = ".bilibili.com"
    
    async def publish(self, cookies: str, params: PublishParams) -> PublishResult:
        # 实现发布逻辑
        ...
```

```python
# platforms/__init__.py 添加
from .bilibili import BilibiliPublisher

PLATFORM_MAP = {
    ...
    'bilibili': BilibiliPublisher,
}
```

## 与 Node.js 服务集成

在 Node.js 服务中设置环境变量：

```bash
# .env 文件
PYTHON_PUBLISH_SERVICE_URL=http://localhost:5005
```

## 部署建议

### PM2 管理

```bash
pm2 start app.py --name "publish-service" --interpreter python
pm2 logs publish-service
pm2 startup && pm2 save
```

### Supervisor (Linux)

```ini
[program:publish-service]
directory=/path/to/server/python
command=/path/to/venv/bin/python app.py
autostart=true
autorestart=true
environment=HEADLESS="true"
```

### Docker

```dockerfile
FROM python:3.11-slim

WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
RUN playwright install chromium && playwright install-deps chromium

COPY . .
EXPOSE 5005
CMD ["python", "app.py"]
```

## 常见问题

### 视频号需要 Chrome 浏览器

视频号使用 Chromium 可能出现 H264 编码错误，已在代码中配置使用 Chrome：

```python
browser = await playwright.chromium.launch(headless=self.headless, channel="chrome")
```

### 小红书 SDK 安装

```bash
pip install xhs -i https://pypi.tuna.tsinghua.edu.cn/simple
```

### Cookie 格式

支持两种格式：

```json
// JSON 数组格式
[
  {"name": "sessionid", "value": "xxx", "domain": ".douyin.com"},
  {"name": "token", "value": "xxx", "domain": ".douyin.com"}
]

// 字符串格式
"sessionid=xxx; token=xxx"
```

## 参考项目

- [matrix](https://github.com/kebenxiaoming/matrix) - 视频矩阵内容分发系统
- [xhs](https://github.com/ReaJason/xhs) - 小红书 Python SDK

## License

MIT
