forked from 77media/video-flow
15 KiB
15 KiB
🎬 Video Edit API 完整规范文档
📋 概述
本文档为Video-Flow视频编辑功能的后端API提供完整的实现规范,包括RESTful API设计、数据结构定义、认证机制、数据库设计等,为后端开发团队提供详细的实现指南。
🏗️ 系统架构
技术栈建议
- 后端框架: FastAPI (Python) / Express.js (Node.js) / Spring Boot (Java)
- 数据库: PostgreSQL (主数据库) + Redis (缓存)
- 认证: JWT Token
- 文件存储: AWS S3 / 阿里云OSS
- 消息队列: Redis / RabbitMQ (用于异步处理)
服务架构
Frontend (React)
↓ HTTP/HTTPS
API Gateway
↓
Video Edit Service
↓
Database (PostgreSQL) + Cache (Redis)
🗄️ 数据库设计
1. 编辑点表 (edit_points)
CREATE TABLE edit_points (
id VARCHAR(50) PRIMARY KEY,
video_id VARCHAR(100) NOT NULL,
project_id VARCHAR(100) NOT NULL,
user_id INTEGER NOT NULL,
position_x FLOAT NOT NULL CHECK (position_x >= 0 AND position_x <= 100),
position_y FLOAT NOT NULL CHECK (position_y >= 0 AND position_y <= 100),
timestamp FLOAT NOT NULL CHECK (timestamp >= 0),
description TEXT DEFAULT '',
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'edited', 'processing', 'completed', 'failed')),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 索引
INDEX idx_edit_points_video_project (video_id, project_id),
INDEX idx_edit_points_user (user_id),
INDEX idx_edit_points_status (status),
INDEX idx_edit_points_created (created_at DESC),
-- 外键约束
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
);
2. 编辑历史表 (edit_point_history)
CREATE TABLE edit_point_history (
id SERIAL PRIMARY KEY,
edit_point_id VARCHAR(50) NOT NULL,
action VARCHAR(20) NOT NULL CHECK (action IN ('created', 'updated', 'deleted', 'submitted')),
old_data JSONB,
new_data JSONB,
user_id INTEGER NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 索引
INDEX idx_history_edit_point (edit_point_id),
INDEX idx_history_user (user_id),
INDEX idx_history_created (created_at DESC),
-- 外键约束
FOREIGN KEY (edit_point_id) REFERENCES edit_points(id) ON DELETE CASCADE,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
3. 编辑任务队列表 (edit_tasks)
CREATE TABLE edit_tasks (
id SERIAL PRIMARY KEY,
edit_point_id VARCHAR(50) NOT NULL,
task_type VARCHAR(20) NOT NULL DEFAULT 'edit_request',
priority INTEGER DEFAULT 0,
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'completed', 'failed')),
payload JSONB NOT NULL,
result JSONB,
error_message TEXT,
retry_count INTEGER DEFAULT 0,
max_retries INTEGER DEFAULT 3,
scheduled_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
started_at TIMESTAMP,
completed_at TIMESTAMP,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-- 索引
INDEX idx_tasks_status (status),
INDEX idx_tasks_scheduled (scheduled_at),
INDEX idx_tasks_edit_point (edit_point_id),
-- 外键约束
FOREIGN KEY (edit_point_id) REFERENCES edit_points(id) ON DELETE CASCADE
);
🔌 API 端点规范
基础配置
- Base URL:
https://api.smartvideo.py.qikongjian.com/v1 - Content-Type:
application/json - 认证方式: Bearer Token (JWT)
1. 获取编辑点列表
GET /video-edit/edit-points
查询参数:
interface GetEditPointsQuery {
video_id: string; // 必需:视频ID
project_id: string; // 必需:项目ID
offset?: number; // 可选:偏移量,默认0
limit?: number; // 可选:限制数量,默认50,最大100
status?: EditPointStatus; // 可选:状态筛选
sort?: 'created_at' | 'updated_at' | 'timestamp'; // 可选:排序字段
order?: 'asc' | 'desc'; // 可选:排序方向,默认desc
}
响应格式:
interface GetEditPointsResponse {
code: number; // 状态码,0表示成功
successful: boolean; // 是否成功
message: string; // 响应消息
data: {
edit_points: EditPoint[];
total_count: number;
has_more: boolean;
pagination: {
offset: number;
limit: number;
total: number;
};
};
}
示例请求:
curl -X GET "https://api.smartvideo.py.qikongjian.com/v1/video-edit/edit-points?video_id=video123&project_id=proj456&limit=20" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json"
2. 创建编辑点
POST /video-edit/edit-points
请求体:
interface CreateEditPointRequest {
video_id: string; // 必需:视频ID
project_id: string; // 必需:项目ID
position_x: number; // 必需:X坐标百分比 (0-100)
position_y: number; // 必需:Y坐标百分比 (0-100)
timestamp: number; // 必需:时间戳(秒)
description?: string; // 可选:编辑描述
status?: EditPointStatus; // 可选:初始状态,默认pending
}
响应格式:
interface CreateEditPointResponse {
code: number;
successful: boolean;
message: string;
data: EditPoint;
}
示例请求:
curl -X POST "https://api.smartvideo.py.qikongjian.com/v1/video-edit/edit-points" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"video_id": "video123",
"project_id": "proj456",
"position_x": 50.5,
"position_y": 30.2,
"timestamp": 15.5,
"description": "需要在这里添加特效"
}'
3. 更新编辑点
PUT /video-edit/edit-points/{edit_point_id}
路径参数:
edit_point_id: 编辑点ID
请求体:
interface UpdateEditPointRequest {
description?: string; // 可选:编辑描述
status?: EditPointStatus; // 可选:状态
position_x?: number; // 可选:X坐标百分比
position_y?: number; // 可选:Y坐标百分比
}
响应格式:
interface UpdateEditPointResponse {
code: number;
successful: boolean;
message: string;
data: EditPoint;
}
4. 删除编辑点
DELETE /video-edit/edit-points/{edit_point_id}
路径参数:
edit_point_id: 编辑点ID
响应格式:
interface DeleteEditPointResponse {
code: number;
successful: boolean;
message: string;
data: null;
}
5. 批量删除编辑点
POST /video-edit/edit-points/batch-delete
请求体:
interface BatchDeleteRequest {
edit_point_ids: string[]; // 必需:要删除的编辑点ID列表
}
6. 提交编辑请求
POST /video-edit/edit-points/{edit_point_id}/submit
路径参数:
edit_point_id: 编辑点ID
响应格式:
interface SubmitEditResponse {
code: number;
successful: boolean;
message: string;
data: {
task_id: string; // 任务ID,用于跟踪处理状态
estimated_duration: number; // 预估处理时间(秒)
};
}
7. 获取编辑统计
GET /video-edit/stats
查询参数:
interface GetStatsQuery {
project_id?: string; // 可选:项目ID筛选
video_id?: string; // 可选:视频ID筛选
date_from?: string; // 可选:开始日期 (ISO 8601)
date_to?: string; // 可选:结束日期 (ISO 8601)
}
响应格式:
interface GetStatsResponse {
code: number;
successful: boolean;
message: string;
data: {
total_edit_points: number;
status_breakdown: {
pending: number;
edited: number;
processing: number;
completed: number;
failed: number;
};
daily_stats: Array<{
date: string;
count: number;
}>;
};
}
🔐 认证和权限控制
JWT Token 结构
interface JWTPayload {
user_id: number;
username: string;
email: string;
role: 'admin' | 'user' | 'viewer';
permissions: string[];
exp: number; // 过期时间戳
iat: number; // 签发时间戳
}
权限级别
- admin: 所有操作权限
- user: 可以创建、编辑、删除自己的编辑点
- viewer: 只能查看编辑点
权限检查中间件
# FastAPI 示例
from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBearer
security = HTTPBearer()
async def verify_token(token: str = Depends(security)):
try:
payload = jwt.decode(token.credentials, SECRET_KEY, algorithms=["HS256"])
return payload
except jwt.ExpiredSignatureError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Token has expired"
)
except jwt.JWTError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid token"
)
async def check_edit_permission(
edit_point_id: str,
current_user: dict = Depends(verify_token)
):
# 检查用户是否有权限编辑该编辑点
edit_point = await get_edit_point(edit_point_id)
if not edit_point:
raise HTTPException(status_code=404, detail="Edit point not found")
if current_user["role"] != "admin" and edit_point.user_id != current_user["user_id"]:
raise HTTPException(status_code=403, detail="Permission denied")
return edit_point
📊 数据类型定义
TypeScript 接口定义
// 编辑点状态枚举
enum EditPointStatus {
PENDING = 'pending',
EDITED = 'edited',
PROCESSING = 'processing',
COMPLETED = 'completed',
FAILED = 'failed'
}
// 编辑点位置
interface EditPointPosition {
x: number; // X坐标百分比 (0-100)
y: number; // Y坐标百分比 (0-100)
}
// 编辑点主数据结构
interface EditPoint {
id: string; // 编辑点唯一ID
video_id: string; // 视频ID
project_id: string; // 项目ID
user_id: number; // 用户ID
position_x: number; // X坐标百分比
position_y: number; // Y坐标百分比
timestamp: number; // 视频时间戳(秒)
description: string; // 编辑描述
status: EditPointStatus; // 状态
created_at: string; // 创建时间 (ISO 8601)
updated_at: string; // 更新时间 (ISO 8601)
}
// API 通用响应格式
interface ApiResponse<T = any> {
code: number; // 状态码,0表示成功
successful: boolean; // 是否成功
message: string; // 响应消息
data: T; // 响应数据
timestamp?: string; // 响应时间戳
request_id?: string; // 请求ID(用于追踪)
}
// 分页信息
interface PaginationInfo {
offset: number; // 偏移量
limit: number; // 限制数量
total: number; // 总数量
has_more: boolean; // 是否有更多数据
}
// 错误详情
interface ErrorDetail {
field?: string; // 错误字段
code: string; // 错误代码
message: string; // 错误消息
}
⚠️ 错误码定义
HTTP 状态码
200: 成功201: 创建成功400: 请求参数错误401: 未认证403: 权限不足404: 资源不存在409: 资源冲突422: 数据验证失败429: 请求过于频繁500: 服务器内部错误503: 服务不可用
业务错误码
enum BusinessErrorCode {
// 通用错误 (1000-1099)
INVALID_PARAMETER = 1001,
MISSING_PARAMETER = 1002,
INVALID_FORMAT = 1003,
// 认证错误 (1100-1199)
TOKEN_EXPIRED = 1101,
TOKEN_INVALID = 1102,
PERMISSION_DENIED = 1103,
// 编辑点错误 (1200-1299)
EDIT_POINT_NOT_FOUND = 1201,
EDIT_POINT_LIMIT_EXCEEDED = 1202,
INVALID_POSITION = 1203,
INVALID_TIMESTAMP = 1204,
// 视频错误 (1300-1399)
VIDEO_NOT_FOUND = 1301,
VIDEO_NOT_ACCESSIBLE = 1302,
// 项目错误 (1400-1499)
PROJECT_NOT_FOUND = 1401,
PROJECT_NOT_ACCESSIBLE = 1402,
// 系统错误 (1500-1599)
DATABASE_ERROR = 1501,
EXTERNAL_SERVICE_ERROR = 1502,
RATE_LIMIT_EXCEEDED = 1503
}
🚀 部署和运维
环境变量配置
# 数据库配置
DATABASE_URL=postgresql://user:password@localhost:5432/video_flow
REDIS_URL=redis://localhost:6379/0
# JWT配置
JWT_SECRET_KEY=your-super-secret-key
JWT_ALGORITHM=HS256
JWT_EXPIRE_HOURS=24
# 服务配置
API_HOST=0.0.0.0
API_PORT=8000
DEBUG=false
LOG_LEVEL=INFO
# 外部服务
S3_BUCKET=video-edit-storage
S3_ACCESS_KEY=your-access-key
S3_SECRET_KEY=your-secret-key
# 限流配置
RATE_LIMIT_REQUESTS=100
RATE_LIMIT_WINDOW=60
Docker 部署
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
监控和日志
- 健康检查:
GET /health - 指标监控: Prometheus + Grafana
- 日志收集: ELK Stack
- 错误追踪: Sentry
📈 性能优化建议
数据库优化
- 索引策略: 为常用查询字段创建复合索引
- 分页优化: 使用游标分页替代偏移分页
- 连接池: 配置合适的数据库连接池大小
- 读写分离: 读操作使用只读副本
缓存策略
- Redis缓存: 缓存热点数据和查询结果
- CDN: 静态资源使用CDN加速
- 应用缓存: 内存中缓存频繁访问的数据
API优化
- 批量操作: 支持批量创建、更新、删除
- 字段选择: 支持指定返回字段减少数据传输
- 压缩: 启用gzip压缩
- 限流: 实现智能限流防止滥用
🧪 测试策略
单元测试
import pytest
from fastapi.testclient import TestClient
def test_create_edit_point():
response = client.post("/video-edit/edit-points", json={
"video_id": "test-video",
"project_id": "test-project",
"position_x": 50.0,
"position_y": 30.0,
"timestamp": 15.5,
"description": "Test edit point"
})
assert response.status_code == 201
assert response.json()["successful"] == True
集成测试
- API端点完整性测试
- 数据库事务测试
- 认证授权测试
- 错误处理测试
性能测试
- 负载测试:模拟高并发请求
- 压力测试:测试系统极限
- 稳定性测试:长时间运行测试
📝 开发指南
开发环境搭建
- 克隆代码仓库
- 安装依赖:
pip install -r requirements.txt - 配置环境变量
- 初始化数据库:
alembic upgrade head - 启动开发服务器:
uvicorn main:app --reload
代码规范
- 使用 Black 进行代码格式化
- 使用 flake8 进行代码检查
- 使用 mypy 进行类型检查
- 遵循 PEP 8 编码规范
Git 工作流
- 使用 Git Flow 分支模型
- 提交信息遵循 Conventional Commits
- 代码审查必须通过才能合并
- 自动化 CI/CD 流程
📞 技术支持
如有任何技术问题或需要进一步的实现指导,请联系开发团队。
文档版本: v1.0.0
最后更新: 2024-09-19
维护者: Video-Flow 开发团队