# 视频导出流式接口 API 规范 ## 接口概述 **接口地址**: `POST /api/export/stream` **接口类型**: Server-Sent Events (SSE) 流式接口 **功能描述**: 实时流式视频导出,支持进度推送和高质量流复制模式 ## 请求参数 ### 请求头 ```http Content-Type: application/json Accept: text/event-stream ``` ### 请求体结构 ```typescript interface ExportRequest { project_id?: string; // 项目ID(可选) ir: IRData; // 时间轴中间表示数据(必需) options?: ExportOptions; // 导出选项(可选) videoFiles?: Record; // 视频文件base64数据(可选) } ``` ## 详细参数说明 ### 1. project_id (可选) - **类型**: `string` - **描述**: 项目唯一标识符 - **默认值**: 如果未提供,系统会生成 `default_project_{task_id前8位}` - **示例**: `"project_12345"` ### 2. ir (必需) - 时间轴中间表示数据 ```typescript interface IRData { width: number; // 视频宽度(必需) height: number; // 视频高度(必需) fps: number; // 帧率(必需) duration: number; // 总时长,单位毫秒(必需) video: VideoElement[]; // 视频轨道数据(必需) texts?: TextElement[]; // 字幕轨道数据(可选) audio?: AudioElement[]; // 音频轨道数据(可选) transitions?: TransitionElement[]; // 转场效果(可选) } ``` #### VideoElement 结构 ```typescript interface VideoElement { id: string; // 视频元素唯一ID src: string; // 视频源路径/URL/blob URL start: number; // 在时间轴上的开始时间(毫秒) end?: number; // 在时间轴上的结束时间(毫秒) in: number; // 视频内部开始时间(毫秒) out: number; // 视频内部结束时间(毫秒) _source_type?: 'local' | 'remote_url' | 'blob'; // 源类型标识 } ``` #### TextElement 结构 ```typescript interface TextElement { id: string; // 字幕元素唯一ID text: string; // 字幕内容 start: number; // 开始时间(毫秒) end: number; // 结束时间(毫秒) style?: TextStyle; // 字幕样式 } interface TextStyle { fontFamily?: string; // 字体,默认 'Arial' fontSize?: number; // 字体大小,默认 40 color?: string; // 字体颜色,默认 '#FFFFFF' backgroundColor?: string; // 背景色,默认 'transparent' fontWeight?: 'normal' | 'bold'; // 字体粗细 fontStyle?: 'normal' | 'italic'; // 字体样式 align?: 'left' | 'center' | 'right'; // 对齐方式 shadow?: boolean; // 是否显示阴影 rotation?: number; // 旋转角度 } ``` ### 3. options (可选) - 导出选项 ```typescript interface ExportOptions { quality?: 'preview' | 'standard' | 'professional'; // 质量等级 codec?: string; // 编码器,默认 'libx264' subtitleMode?: 'hard' | 'soft'; // 字幕模式,默认 'hard' bitrate?: string; // 比特率,如 '5000k' preset?: string; // 编码预设,如 'medium' } ``` **默认值**: ```json { "quality": "standard", "codec": "libx264", "subtitleMode": "hard" } ``` ### 4. videoFiles (可选) - Base64视频数据 ```typescript interface VideoFiles { [blobId: string]: string; // blobId -> base64编码的视频数据 } ``` **使用场景**: 当 `VideoElement.src` 为 blob URL 时,需要提供对应的 base64 数据 ## 完整请求示例 ### 基础示例 ```json { "project_id": "demo_project_001", "ir": { "width": 1920, "height": 1080, "fps": 30, "duration": 15000, "video": [ { "id": "video_1", "src": "https://example.com/video1.mp4", "start": 0, "end": 10000, "in": 2000, "out": 12000, "_source_type": "remote_url" }, { "id": "video_2", "src": "blob:http://localhost:3000/abc-123", "start": 10000, "end": 15000, "in": 0, "out": 5000, "_source_type": "blob" } ], "texts": [ { "id": "subtitle_1", "text": "欢迎观看演示视频", "start": 1000, "end": 4000, "style": { "fontSize": 48, "color": "#FFFFFF", "fontFamily": "Arial", "align": "center" } } ] }, "options": { "quality": "professional", "codec": "libx264", "subtitleMode": "hard" }, "videoFiles": { "abc-123": "data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28y..." } } ``` ## 响应格式 (SSE) 接口返回 Server-Sent Events 流,每个事件包含以下格式: ``` data: {"type": "progress", "message": "处理中...", "progress": 0.5} ``` ### 事件类型 #### 1. start - 开始事件 ```json { "type": "start", "message": "开始导出...", "timestamp": "2024-01-01T12:00:00.000Z" } ``` #### 2. progress - 进度事件 ```json { "type": "progress", "stage": "preparing|stream_copy|uploading", "message": "当前阶段描述", "progress": 0.65, "timestamp": "2024-01-01T12:00:30.000Z" } ``` #### 3. complete - 完成事件 ```json { "type": "complete", "message": "🎬 高清视频导出完成", "timestamp": "2024-01-01T12:01:00.000Z", "file_size": 52428800, "export_id": "export_abc123", "quality_mode": "stream_copy", "download_url": "https://cdn.example.com/video.mp4", "cloud_storage": true } ``` #### 4. error - 错误事件 ```json { "type": "error", "message": "导出失败: 文件不存在", "timestamp": "2024-01-01T12:00:45.000Z" } ``` ## 前端集成示例 ### JavaScript/TypeScript ```typescript async function exportVideo(exportRequest: ExportRequest) { const response = await fetch('/api/export/stream', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Accept': 'text/event-stream' }, body: JSON.stringify(exportRequest) }); const reader = response.body?.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader!.read(); if (done) break; const chunk = decoder.decode(value); const lines = chunk.split('\n'); for (const line of lines) { if (line.startsWith('data: ')) { const data = JSON.parse(line.slice(6)); handleProgressEvent(data); } } } } function handleProgressEvent(event: any) { switch (event.type) { case 'start': console.log('导出开始'); break; case 'progress': console.log(`进度: ${event.progress * 100}% - ${event.message}`); break; case 'complete': console.log('导出完成:', event.download_url); break; case 'error': console.error('导出失败:', event.message); break; } } ``` ## 重要注意事项 ### 1. 视频源处理优先级 1. **本地文件路径** - 直接使用 2. **HTTP/HTTPS URL** - 自动下载 3. **Blob URL** - 需要提供 `videoFiles` 中的 base64 数据 ### 2. 高质量流复制模式 - 系统默认启用流复制模式,保持原始视频质量 - 处理速度提升 10-20 倍 - 零质量损失 ### 3. 音频兼容性 - 自动检测混合音频情况 - 智能处理有音频/无音频片段的兼容性 ### 4. 错误处理 - 无效视频源会被自动跳过 - 详细的错误信息通过 SSE 实时推送 ### 5. 云存储集成 - 支持七牛云自动上传 - 上传失败时提供本地下载链接 ## 验证接口 在正式导出前,建议先调用验证接口: ```http POST /api/export/validate Content-Type: application/json { "ir": { /* 同导出接口的ir参数 */ }, "options": { /* 同导出接口的options参数 */ } } ``` 验证接口会检查: - IR 数据完整性 - 视频分辨率、帧率、时长 - 导出选项有效性 - 返回详细的验证错误信息