---
name: happyhorse-reference-to-video
description: 通过 Open.OspreyAI 网关使用 HappyHorse 1.0 参考视频生成 API。以 1-6 张参考图片为素材，配合文字描述，生成融合多图片元素的高清视频，720P/1080P，3-15 秒。
version: "1.0"
category: video-generation
triggers:
  - HappyHorse 参考视频
  - happyhorse r2v
  - 参考图片生成视频
  - 参考视频
  - happyhorse-1.0-r2v
  - reference to video
  - 多图视频
---

::: info 下载原始 Skill 文件
```bash
curl https://ai.ospreyai.cn/docs/raw/skills/happyhorse-reference-to-video.md -o happyhorse-reference-to-video.md
```
:::

## 对话式接入

本 Skill 文件可被 AI 助手（Claude Code、Cursor、ChatGPT 等）学习，通过自然语言对话完成参考图片视频生成。

在 AI 对话中发送以下指令即可：

```
学习：https://ai.ospreyai.cn/docs/raw/skills/happyhorse-reference-to-video.md，保存为本地的技能 skills
```

> 更多接入方式和使用示例详见 [API 文档 — AI 助手对话式接入](/api#ai-助手对话式接入)。

---

# HappyHorse 1.0 参考图片视频生成 (Reference-to-Video)

## Overview

通过 Open.OspreyAI 网关 `https://open.ospreyai.cn` 使用 HappyHorse 1.0 模型，以 1-6 张参考图片为素材，配合文字描述，生成融合多图片元素的高清视频。

**HappyHorse R2V** 是参考图片视频生成模型，可输入多张参考图片（最多 6 张），在 prompt 中通过 `[Image 1]`、`[Image 2]` 等引用对应图片元素，生成将多张图片内容融合在一起的连贯视频。采用异步任务模式：提交任务 → 轮询状态 → 下载视频。

核心特性：
- **多图融合**：支持 1-6 张参考图片，将不同图片元素融合到同一视频
- **Prompt 引用**：通过 `[Image N]` 语法精确引用对应图片内容
- **高清输出**：支持 720P、1080P 分辨率
- **多种比例**：16:9（横屏）、9:16（竖屏）、1:1（方形）
- **灵活时长**：3-15 秒可调
- **异步任务**：提交后立即返回 task_id，后台生成完成后通过 OSS 临时链接下载

**API 参考文档**：[阿里云 — HappyHorse 参考视频 API](https://help.aliyun.com/zh/model-studio/happyhorse-reference-to-video-api-reference)

与其他视频生成 Skill 的对比：

| Skill | 模型 | 输入 | 输出 | 适用场景 |
|-------|------|------|------|---------|
| [ComfyUI 视频生成](/skills/comfyui-video-generation) | Wan 2.2 I2V | 1 张起始图 | ~5s 视频 | 图生视频（开源） |
| [ComfyUI 关键帧视频](/skills/comfyui-keyframes-video-generation) | Wan 2.2 FLF2V | 6 张关键帧 | ~5s 视频 | 多关键帧过渡 |
| [ComfyUI Fun Inpaint](/skills/comfyui-fun-inpaint-video-generation) | Wan 2.2 Fun Inpaint | 首帧 + 尾帧 | ~5s 视频 | 首尾帧过渡 |
| [HappyHorse 文生视频](/skills/happyhorse-text-to-video) | HappyHorse 1.0 T2V | 文字提示词 | 1-10s 视频 | 纯文字驱动 |
| [HappyHorse 图生视频](/skills/happyhorse-image-to-video) | HappyHorse 1.0 I2V | 1 张首帧 + 文字 | 3-15s 视频 | 图片动态化 |
| **本 Skill** | HappyHorse 1.0 R2V | 1-6 张参考图 + 文字 | 3-15s 视频 | 多图融合、风格迁移 |

所有 API 均需 Bearer Token 鉴权（`Authorization: Bearer sk-xxx`）。

## Quick Start

```bash
export GW="https://open.ospreyai.cn"
export API_KEY="sk-your-api-key"

# 1. 提交参考图片视频任务
curl -s -X POST "$GW/v1/video/generations" \
  -H "X-DashScope-Async: enable" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "happyhorse-1.0-r2v",
    "prompt": "[Image 1]中的女性微笑着向镜头挥手，背景是[Image 2]中的城市风景",
    "images": [
      "https://example.com/girl.jpg",
      "https://example.com/city.jpg"
    ],
    "resolution": "720P",
    "ratio": "16:9",
    "duration": 5,
    "watermark": false
  }'

# 响应: {"task_id": "task_xxx", "status": "queued"}

# 2. 轮询任务状态
curl -s "$GW/v1/video/generations/{task_id}" \
  -H "Authorization: Bearer $API_KEY"

# 3. 下载视频（从响应中的 result_url 字段获取）
curl -sL "{result_url}" -o output.mp4
```

## Task Routing

| 场景 | 动作 |
|------|------|
| 首次生成视频 | → Route A: Submit Task |
| 需要查看任务是否完成 | → Route B: Check Status |
| 需要获取或下载视频 | → Route C: Download |
| 需要调优参数（分辨率、比例、时长） | → Route D: Tune Parameters |
| 需要排查错误 | → Route E: Troubleshoot |

## Route A: Submit Task

### 服务信息

- 网关地址: `https://open.ospreyai.cn`
- 提交接口: `POST /v1/video/generations`
- 查询接口: `GET /v1/video/generations/{task_id}`
- 鉴权方式: `Authorization: Bearer sk-xxx`
- 异步头: `X-DashScope-Async: enable`

### Step 1: 提交参考图片视频任务

```bash
curl -s -X POST "$GW/v1/video/generations" \
  -H "X-DashScope-Async: enable" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "happyhorse-1.0-r2v",
    "prompt": "[Image 1]中身着红色旗袍的女性，轻抬玉手展开[Image 2]中的折扇，[Image 3]中的流苏耳坠随头部转动轻盈摆动",
    "images": [
      "https://example.com/girl.jpg",
      "https://example.com/fan.jpg",
      "https://example.com/earrings.jpg"
    ],
    "resolution": "720P",
    "ratio": "16:9",
    "duration": 5,
    "watermark": false
  }'
```

**响应：**

```json
{
    "id": "task_xxxxxxxxxxxxxxxxxxxxxxxxx",
    "task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxxx",
    "object": "video",
    "model": "happyhorse-1.0-r2v",
    "status": "queued",
    "progress": 0,
    "created_at": 1780000000
}
```

> 记住 `task_id`，用于后续查询任务状态和获取视频。

### 请求参数

| 字段 | 类型 | 必填 | 说明 | 示例值 |
|------|------|------|------|--------|
| model | string | ✅ | 模型名称 | `"happyhorse-1.0-r2v"` |
| prompt | string | ✅ | 视频描述，用 `[Image N]` 引用图片 | `"[Image 1]中的女性..."` |
| images | array | ✅ | 图片 URL 数组，1-6 张 | `["url1", "url2"]` |
| resolution | string | ❌ | 分辨率：`720P` / `1080P` | `"720P"` |
| ratio | string | ❌ | 画面比例：`16:9` / `9:16` / `1:1` | `"16:9"` |
| duration | integer | ❌ | 视频时长（秒），3-15，默认 5 | `5` |
| watermark | boolean | ❌ | 是否添加水印，默认 `true` | `false` |
| seed | integer | ❌ | 随机种子 `[0, 2147483647]` | `42` |

### images 字段说明

`images` 是一个字符串数组，包含 1-6 个图片 URL：

```json
"images": [
  "https://example.com/photo1.jpg",
  "https://example.com/photo2.jpg",
  "https://example.com/photo3.jpg"
]
```

**图片顺序对应 prompt 中的引用**：第 1 张图片对应 `[Image 1]`，第 2 张对应 `[Image 2]`，以此类推。

支持两种格式：

1. **公网 URL**：HTTP 或 HTTPS 协议
   ```json
   "images": ["https://example.com/photo.png"]
   ```

2. **Base64 编码**：
   ```json
   "images": ["data:image/png;base64,iVBORw0KGgo..."]
   ```

### 图片要求

| 限制项 | 要求 |
|--------|------|
| 格式 | JPEG、JPG、PNG、WEBP |
| 分辨率 | 宽和高均不小于 300 像素 |
| 宽高比 | 1:2.5 ~ 2.5:1 |
| 文件大小 | 不超过 20MB |
| 数量 | 1-6 张 |

### 请求头

| Header | 说明 |
|--------|------|
| `X-DashScope-Async: enable` | 启用异步任务模式（必传） |
| `Authorization: Bearer sk-xxx` | API 鉴权 |
| `Content-Type: application/json` | JSON 请求体 |

## Route B: Check Status

### 查询任务状态

```bash
curl -s "$GW/v1/video/generations/{task_id}" \
  -H "Authorization: Bearer $API_KEY"
```

**进行中：**

```json
{
    "code": "success",
    "data": {
        "task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxxx",
        "status": "IN_PROGRESS",
        "progress": "50%",
        "submit_time": 1780000000,
        "start_time": 1780000001,
        "finish_time": 0,
        "data": {
            "output": {
                "task_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "task_status": "RUNNING"
            }
        }
    }
}
```

**已完成：**

```json
{
    "code": "success",
    "data": {
        "task_id": "task_xxxxxxxxxxxxxxxxxxxxxxxxx",
        "status": "SUCCESS",
        "progress": "100%",
        "result_url": "https://dashscope-a717.oss-accelerate.aliyuncs.com/...",
        "submit_time": 1780000000,
        "start_time": 1780000001,
        "finish_time": 1780000120,
        "data": {
            "usage": {
                "SR": 720,
                "ratio": "16:9",
                "duration": 5,
                "video_count": 1,
                "input_video_duration": 0,
                "output_video_duration": 5
            },
            "output": {
                "task_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
                "video_url": "https://dashscope-a717.oss-accelerate.aliyuncs.com/...",
                "orig_prompt": "[Image 1]中身着红色旗袍的女性...",
                "task_status": "SUCCEEDED"
            }
        }
    }
}
```

### 任务状态流转

```
queued → IN_PROGRESS (50%) → SUCCESS (100%) / FAILED
```

| 状态 | 说明 |
|------|------|
| `queued` | 任务已提交，排队等待 |
| `IN_PROGRESS` | 正在生成中 |
| `SUCCESS` | 生成成功，可下载视频 |
| `FAILED` | 生成失败，查看 `fail_reason` |

> 720P 5秒视频生成通常需要 1-3 分钟。

## Route C: Download

任务成功后，从响应中获取视频下载链接：

- **`data.result_url`**：顶层字段，直接的下载 URL
- **`data.data.output.video_url`**：嵌套字段，同上

两个 URL 相同，均为阿里云 OSS 临时链接（有效期约 24 小时）。

```bash
# 直接下载（URL 从任务状态响应中获取）
curl -sL "{result_url}" -o output.mp4
```

> ⚠️ 视频 URL 带签名参数，有效期约 24 小时（`Expires` 参数控制），过期后需重新查询任务获取新链接。

### Python 调用示例

```python
import requests
import time

GW = "https://open.ospreyai.cn"
API_KEY = "sk-your-api-key"
headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
    "X-DashScope-Async": "enable"
}

# 1. 提交参考图片视频任务
resp = requests.post(f"{GW}/v1/video/generations", headers=headers, json={
    "model": "happyhorse-1.0-r2v",
    "prompt": "[Image 1]中身着红色旗袍的女性，轻抬玉手展开[Image 2]中的折扇",
    "images": [
        "https://example.com/girl.jpg",
        "https://example.com/fan.jpg"
    ],
    "resolution": "720P",
    "ratio": "16:9",
    "duration": 5,
    "watermark": false
})
task = resp.json()
task_id = task["task_id"]
print(f"Task submitted: {task_id}")

# 2. 轮询任务状态
headers_query = {"Authorization": f"Bearer {API_KEY}"}
while True:
    resp = requests.get(f"{GW}/v1/video/generations/{task_id}", headers=headers_query)
    data = resp.json().get("data", {})
    status = data.get("status", "")
    progress = data.get("progress", "")

    if status == "SUCCESS":
        video_url = data.get("result_url") or data.get("data", {}).get("output", {}).get("video_url")
        print(f"Video ready: {video_url}")
        break
    elif status == "FAILED":
        print(f"Failed: {data.get('fail_reason')}")
        break

    print(f"Status: {status} ({progress})")
    time.sleep(5)

# 3. 下载视频
if status == "SUCCESS":
    resp = requests.get(video_url)
    with open("happyhorse_r2v_output.mp4", "wb") as f:
        f.write(resp.content)
    print(f"Downloaded: happyhorse_r2v_output.mp4 ({len(resp.content)} bytes)")
```

## Route D: Tune Parameters

### 分辨率

| 值 | 说明 | 生成时间 |
|----|------|---------|
| `720P` | 720p 标清 | 较快（~1-2 分钟） |
| `1080P` | 1080p 高清 | 较慢（~2-3 分钟） |

### 画面比例

| 值 | 适用场景 |
|----|---------|
| `16:9` | 横屏视频（适合 PC/电视） |
| `9:16` | 竖屏视频（适合手机/短视频） |
| `1:1` | 方形视频（适合社交媒体） |

> 与 I2V 不同，R2V 支持 `ratio` 参数来控制输出视频的画面比例。

### 时长

| 值 | 说明 |
|----|------|
| `3` - `15` | 视频时长（秒），整数 |
| `5` | 默认值，平衡质量和生成时间 |

> 时长越长，生成时间越久，消耗配额越多。

### 水印

| 值 | 说明 |
|----|------|
| `false` | 不添加水印（推荐，示例中默认使用） |
| `true` | 添加水印，右下角显示 "Happy Horse"（API 默认值） |

### 种子

| 值 | 说明 |
|----|------|
| `0` - `2147483647` | 固定 seed 可提高结果复现性 |
| 不传 | 系统自动生成随机种子 |

### Prompt 引用语法

R2V 的核心能力是在 prompt 中通过 `[Image N]` 引用参考图片：

- `[Image 1]` — 引用 `images` 数组中第 1 张图片
- `[Image 2]` — 引用第 2 张图片
- 以此类推，最多 `[Image 6]`

**Prompt 编写技巧：**

```
[Image 1]中身着红色旗袍的女性，镜头先以侧面中景勾勒旗袍修身剪裁，
随即切换至低角度仰拍，捕捉她轻抬玉手展开[Image 2]中的折扇的同时，
[Image 3]中的流苏耳坠随头部转动轻盈摆动
```

**建议：**
- 每个 `[Image N]` 后描述该图片元素的动作或状态变化
- 描述镜头运动（推、拉、摇、移）来控制视频节奏
- 可以只引用部分图片，未引用的图片作为风格参考

### 多图融合示例

**单图 + 简单描述：**
```json
{
  "images": ["https://example.com/product.jpg"],
  "prompt": "[Image 1]中的产品缓缓旋转，背景光影流转"
}
```

**双图 + 场景融合：**
```json
{
  "images": [
    "https://example.com/person.jpg",
    "https://example.com/beach.jpg"
  ],
  "prompt": "[Image 1]中的人物漫步在[Image 2]所示的海滩上，夕阳余晖洒满全身"
}
```

**三图 + 多元素叙事：**
```json
{
  "images": [
    "https://example.com/girl.jpg",
    "https://example.com/fan.jpg",
    "https://example.com/earrings.jpg"
  ],
  "prompt": "[Image 1]中的女性展开[Image 2]中的折扇，[Image 3]的耳坠轻轻摆动"
}
```

### 输出视频参数

- **分辨率**: 720P 或 1080P（按请求参数）
- **比例**: 16:9 / 9:16 / 1:1
- **时长**: 3-15 秒
- **格式**: MP4
- **文件大小**: 约 5-20 MB（5 秒视频）

## Route E: Troubleshoot

| 问题 | 排查方法 |
|------|---------|
| `Invalid URL` | 检查 URL 是否为 `/v1/video/generations`（不是 `/v1/services/aigc/...`） |
| `prompt is required` | `prompt` 是必填字段，必须在顶层 |
| `r2v requires at least 1 reference_image media item` | 使用了错误的图片字段名。必须用 `images`（字符串数组），不是 `media` |
| `happyhorse supports video task relay only` | 不能走 `/v1/chat/completions` 或 `/v1/images/generations`，必须走 `/v1/video/generations` |
| 401 鉴权失败 | 检查 Bearer Token 是否有效 |
| 任务长时间 IN_PROGRESS | R2V 生成可能需要 2-5 分钟，耐心等待 |
| 任务 FAILED | 检查 `fail_reason` 字段，可能是图片不合规或模型过载 |
| 视频 URL 过期 | 重新查询任务状态获取新的 `result_url` |
| 图片不符合要求 | 检查格式（JPEG/PNG/WEBP）、分辨率（≥300px）、宽高比（1:2.5~2.5:1）、大小（≤20MB） |
| `[Image N]` 引用无效 | 确保 N 在 1 到 images 数组长度范围内 |

### 请求格式对比（常见错误）

| 项目 | ❌ 错误（DashScope 原始格式） | ✅ 正确（网关适配格式） |
|------|------|------|
| URL | `/v1/services/aigc/video-generation/video-synthesis` | `/v1/video/generations` |
| prompt | `{"input": {"prompt": "..."}}` | `{"prompt": "..."}` |
| 图片 | `{"input": {"media": [{"type": "reference_image", "url": "..."}]}}` | `{"images": ["..."]}` |
| 参数 | `{"parameters": {"resolution": "720P"}}` | `{"resolution": "720P"}` |

> ⚠️ **关键差异**：网关将 DashScope 的 `input.media` 数组格式简化为 `images` 字符串数组。不再需要 `type: "reference_image"` 包装，直接传图片 URL 即可。图片顺序对应 prompt 中 `[Image 1]`、`[Image 2]` 的引用。

### 与 HappyHorse I2V 的关键差异

| 特性 | R2V（本 Skill） | I2V（图生视频） |
|------|----------------|----------------|
| 模型 | `happyhorse-1.0-r2v` | `happyhorse-1.0-i2v` |
| 输入 | 1-6 张参考图片 + 文字 | 1 张首帧图片 + 文字 |
| 图片数量 | 1-6 张 | 1 张 |
| Prompt 引用 | `[Image N]` 语法引用图片 | 直接描述动作 |
| ratio | ✅ 支持 `16:9`/`9:16`/`1:1` | 无（由图片决定） |
| 适合场景 | 多图融合、风格迁移、产品展示 | 单图动态化 |

### 与 ComfyUI 关键帧视频的对比

| 特性 | HappyHorse R2V | ComfyUI FLF2V |
|------|---------------|---------------|
| 输入 | 1-6 张参考图（非关键帧） | 6 张关键帧 |
| 分辨率 | 720P / 1080P | 640×640 / 720×720 |
| 时长 | 3-15 秒 | ~5 秒（固定） |
| 生成时间 | 1-5 分钟 | 30 秒-2 分钟 |
| 模型 | 闭源大模型 | 开源 Wan 2.2 |
| 图片角色 | 参考素材，通过 prompt 编排 | 关键帧，固定过渡节点 |
| 适合场景 | 创意融合、营销素材 | 精确控制帧间过渡 |

## Verification Checklist

- [ ] 请求 URL 为 `POST /v1/video/generations`（不是 DashScope 原始路径）
- [ ] 请求头包含 `X-DashScope-Async: enable`
- [ ] `prompt` 在顶层（必填，使用 `[Image N]` 引用图片）
- [ ] `images` 在顶层，为包含 1-6 个 URL 字符串的数组（不是 `media` 对象数组）
- [ ] 图片 URL 可公网访问，格式符合要求
- [ ] `[Image N]` 中的 N 对应 images 数组中的位置（从 1 开始）
- [ ] 提交成功，返回 `task_id` 和 `status: "queued"`
- [ ] 轮询 `GET /v1/video/generations/{task_id}` 直到 `status: "SUCCESS"`
- [ ] 从 `result_url` 获取视频下载链接
- [ ] 下载 MP4 文件并可正常播放
- [ ] 视频分辨率、比例、时长与请求参数一致
