# 🎬 Video Edit API 完整规范文档 ## 📋 概述 本文档为video-flow-b视频编辑功能的后端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) ```sql 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) ```sql 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) ```sql 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. 获取编辑点列表 ```http GET /video-edit/edit-points ``` **查询参数:** ```typescript 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 } ``` **响应格式:** ```typescript 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; }; }; } ``` **示例请求:** ```bash 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. 创建编辑点 ```http POST /video-edit/edit-points ``` **请求体:** ```typescript 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 } ``` **响应格式:** ```typescript interface CreateEditPointResponse { code: number; successful: boolean; message: string; data: EditPoint; } ``` **示例请求:** ```bash 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. 更新编辑点 ```http PUT /video-edit/edit-points/{edit_point_id} ``` **路径参数:** - `edit_point_id`: 编辑点ID **请求体:** ```typescript interface UpdateEditPointRequest { description?: string; // 可选:编辑描述 status?: EditPointStatus; // 可选:状态 position_x?: number; // 可选:X坐标百分比 position_y?: number; // 可选:Y坐标百分比 } ``` **响应格式:** ```typescript interface UpdateEditPointResponse { code: number; successful: boolean; message: string; data: EditPoint; } ``` ### 4. 删除编辑点 ```http DELETE /video-edit/edit-points/{edit_point_id} ``` **路径参数:** - `edit_point_id`: 编辑点ID **响应格式:** ```typescript interface DeleteEditPointResponse { code: number; successful: boolean; message: string; data: null; } ``` ### 5. 批量删除编辑点 ```http POST /video-edit/edit-points/batch-delete ``` **请求体:** ```typescript interface BatchDeleteRequest { edit_point_ids: string[]; // 必需:要删除的编辑点ID列表 } ``` ### 6. 提交编辑请求 ```http POST /video-edit/edit-points/{edit_point_id}/submit ``` **路径参数:** - `edit_point_id`: 编辑点ID **响应格式:** ```typescript interface SubmitEditResponse { code: number; successful: boolean; message: string; data: { task_id: string; // 任务ID,用于跟踪处理状态 estimated_duration: number; // 预估处理时间(秒) }; } ``` ### 7. 获取编辑统计 ```http GET /video-edit/stats ``` **查询参数:** ```typescript interface GetStatsQuery { project_id?: string; // 可选:项目ID筛选 video_id?: string; // 可选:视频ID筛选 date_from?: string; // 可选:开始日期 (ISO 8601) date_to?: string; // 可选:结束日期 (ISO 8601) } ``` **响应格式:** ```typescript 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 结构 ```typescript interface JWTPayload { user_id: number; username: string; email: string; role: 'admin' | 'user' | 'viewer'; permissions: string[]; exp: number; // 过期时间戳 iat: number; // 签发时间戳 } ``` ### 权限级别 - **admin**: 所有操作权限 - **user**: 可以创建、编辑、删除自己的编辑点 - **viewer**: 只能查看编辑点 ### 权限检查中间件 ```python # 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 接口定义 ```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 { 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`: 服务不可用 ### 业务错误码 ```typescript 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 } ``` ## 🚀 部署和运维 ### 环境变量配置 ```bash # 数据库配置 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 部署 ```dockerfile 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 ## 📈 性能优化建议 ### 数据库优化 1. **索引策略**: 为常用查询字段创建复合索引 2. **分页优化**: 使用游标分页替代偏移分页 3. **连接池**: 配置合适的数据库连接池大小 4. **读写分离**: 读操作使用只读副本 ### 缓存策略 1. **Redis缓存**: 缓存热点数据和查询结果 2. **CDN**: 静态资源使用CDN加速 3. **应用缓存**: 内存中缓存频繁访问的数据 ### API优化 1. **批量操作**: 支持批量创建、更新、删除 2. **字段选择**: 支持指定返回字段减少数据传输 3. **压缩**: 启用gzip压缩 4. **限流**: 实现智能限流防止滥用 ## 🧪 测试策略 ### 单元测试 ```python 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端点完整性测试 - 数据库事务测试 - 认证授权测试 - 错误处理测试 ### 性能测试 - 负载测试:模拟高并发请求 - 压力测试:测试系统极限 - 稳定性测试:长时间运行测试 ## 📝 开发指南 ### 开发环境搭建 1. 克隆代码仓库 2. 安装依赖:`pip install -r requirements.txt` 3. 配置环境变量 4. 初始化数据库:`alembic upgrade head` 5. 启动开发服务器:`uvicorn main:app --reload` ### 代码规范 - 使用 Black 进行代码格式化 - 使用 flake8 进行代码检查 - 使用 mypy 进行类型检查 - 遵循 PEP 8 编码规范 ### Git 工作流 - 使用 Git Flow 分支模型 - 提交信息遵循 Conventional Commits - 代码审查必须通过才能合并 - 自动化 CI/CD 流程 --- ## 📞 技术支持 如有任何技术问题或需要进一步的实现指导,请联系开发团队。 **文档版本**: v1.0.0 **最后更新**: 2024-09-19 **维护者**: video-flow-b 开发团队