$npx -y skills add cinience/alicloud-skills --skill aliyun-happyhorse-r2vUse when generating videos that fuse 1-9 reference images with DashScope HappyHorse 1.0 reference-to-video model (happyhorse-1.0-r2v). Use when implementing multi-subject reference-to-video synthesis where prompts cite the input images as character1..N via the video-synthesis asy
| 1 | # HappyHorse 1.0 Reference-to-Video |
| 2 | |
| 3 | ## Validation |
| 4 | |
| 5 | ```bash |
| 6 | mkdir -p output/aliyun-happyhorse-r2v |
| 7 | python -m py_compile skills/ai/video/aliyun-happyhorse-r2v/scripts/r2v_happyhorse.py && echo "py_compile_ok" > output/aliyun-happyhorse-r2v/validate.txt |
| 8 | ``` |
| 9 | |
| 10 | Pass criteria: command exits 0 and `output/aliyun-happyhorse-r2v/validate.txt` is generated. |
| 11 | |
| 12 | ## Output And Evidence |
| 13 | |
| 14 | - Save task IDs, polling responses, and final video URLs to `output/aliyun-happyhorse-r2v/`. |
| 15 | - Keep at least one end-to-end run log for troubleshooting. |
| 16 | |
| 17 | ## Prerequisites |
| 18 | |
| 19 | - Install dependencies (recommended in a venv): |
| 20 | |
| 21 | ```bash |
| 22 | python3 -m venv .venv |
| 23 | . .venv/bin/activate |
| 24 | python -m pip install requests |
| 25 | ``` |
| 26 | - Set `DASHSCOPE_API_KEY` in your environment, or add `dashscope_api_key` to `~/.alibabacloud/credentials`. |
| 27 | |
| 28 | ## Critical model names |
| 29 | |
| 30 | - `happyhorse-1.0-r2v` — reference-to-video; 1-9 reference images fused into a single video, with `character1..N` references in the prompt |
| 31 | |
| 32 | ## Capabilities |
| 33 | |
| 34 | | Capability | Description | Required media | |
| 35 | |---|---|---| |
| 36 | | Reference-to-video | Generate a video by fusing multiple subject/object reference images, guided by a prompt that references them as `character1`, `character2`, ... in input order | 1-9 `reference_image` entries | |
| 37 | |
| 38 | ## API endpoint (async only) |
| 39 | |
| 40 | ``` |
| 41 | POST https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis |
| 42 | ``` |
| 43 | |
| 44 | Required headers: |
| 45 | - `Authorization: Bearer $DASHSCOPE_API_KEY` |
| 46 | - `Content-Type: application/json` |
| 47 | - `X-DashScope-Async: enable` |
| 48 | |
| 49 | Singapore endpoint: replace `dashscope.aliyuncs.com` with `dashscope-intl.aliyuncs.com`. |
| 50 | |
| 51 | Polling endpoint: `GET https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}` — recommended interval 15s. |
| 52 | |
| 53 | ## Normalized interface |
| 54 | |
| 55 | ### Request |
| 56 | - `model` (string, required) — fixed `happyhorse-1.0-r2v` |
| 57 | - `input.prompt` (string, required) — up to 5000 non-CJK / 2500 CJK characters; reference subjects via `character1`, `character2`, ... matching `media` array order |
| 58 | - `input.media` (array, required) — 1 to 9 elements, each: |
| 59 | - `type`: `reference_image` |
| 60 | - `url`: public HTTP/HTTPS URL of a reference image |
| 61 | - `parameters.resolution` (string, optional) — `720P` or `1080P` (default: `1080P`) |
| 62 | - `parameters.ratio` (string, optional) — `16:9` (default), `9:16`, `1:1`, `4:3`, `3:4` |
| 63 | - `parameters.duration` (integer, optional) — video length in seconds, range [3, 15] (default: 5) |
| 64 | - `parameters.watermark` (boolean, optional) — bottom-right "Happy Horse" watermark (default: `true`) |
| 65 | - `parameters.seed` (integer, optional) — range [0, 2147483647] |
| 66 | |
| 67 | ### Media input limits |
| 68 | |
| 69 | **Reference image** (`type=reference_image`): |
| 70 | - Formats: JPEG, JPG, PNG, WEBP |
| 71 | - Resolution: short side ≥ 400 pixels (720P or higher recommended) |
| 72 | - Max size: 10 MB per image |
| 73 | - Avoid blurry, over-compressed, or very small images |
| 74 | |
| 75 | ### Character indexing rule |
| 76 | |
| 77 | The first `reference_image` in the `media` array maps to `character1`, the second to `character2`, and so on up to `character9`. Reorder the array if you want a specific reference to bind to a specific `characterN`. |
| 78 | |
| 79 | ### Response (task creation) |
| 80 | - `output.task_id` (string) — valid 24 hours |
| 81 | - `output.task_status` (string) — `PENDING` | `RUNNING` | `SUCCEEDED` | `FAILED` | `CANCELED` | `UNKNOWN` |
| 82 | - `request_id` (string) |
| 83 | |
| 84 | ### Response (task result, on SUCCEEDED) |
| 85 | - `output.video_url` (string) — generated MP4 (H.264) URL, valid 24 hours |
| 86 | - `output.orig_prompt` (string) |
| 87 | - `output.submit_time` / `output.scheduled_time` / `output.end_time` (string) |
| 88 | - `usage.duration` (integer) — billable duration in seconds |
| 89 | - `usage.output_video_duration` (integer) |
| 90 | - `usage.input_video_duration` (integer) — fixed 0 for r2v |
| 91 | - `usage.SR` (integer) — output resolution tier |
| 92 | - `usage.ratio` (string) |
| 93 | - `usage.video_count` (integer) — fixed 1 |
| 94 | |
| 95 | ## Quick start (Python + HTTP) |
| 96 | |
| 97 | ```python |
| 98 | import os |
| 99 | import time |
| 100 | import requests |
| 101 | |
| 102 | API_KEY = os.getenv("DASHSCOPE_API_KEY") |
| 103 | BASE_URL = "https://dashscope.aliyuncs.com/api/v1" |
| 104 | |
| 105 | |
| 106 | def create_r2v_task(req: dict) -> str: |
| 107 | """Create a reference-to-video task and return task_id.""" |
| 108 | refs = req["reference_images"] |
| 109 | if not 1 <= len(refs) <= 9: |
| 110 | raise ValueError("Need 1-9 reference images") |
| 111 | payload = { |
| 112 | "model": "happyhorse-1.0-r2v", |
| 113 | "input": { |
| 114 | "prompt": req["prompt"], |
| 115 | "media": [{"type": "reference_image", "url": u} for u in refs], |
| 116 | }, |
| 117 | "parameters": { |
| 118 | "resolution": req.get("resolution", "1080P"), |
| 119 | "ratio": req.get("ratio", "16:9"), |
| 120 | "duration": req.get("duration", 5), |
| 121 | "watermark": req.get("watermark", True), |
| 122 | }, |
| 123 | } |
| 124 | if req.get("seed") is not None: |
| 125 | payload["parameters"]["seed |