# 视频导出流式接口 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<string, string>; // 视频文件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 数据完整性
- 视频分辨率、帧率、时长
- 导出选项有效性
- 返回详细的验证错误信息