GPT-6 Sol、Claude Opus 5.5 已上线GPT-6 Sol 价格仅为 5.6 Sol 的一半

HappyHorse 1.1 图生视频:API 调用方法和实测片段

一个脚本上传静图、轮询任务、保存 MP4。字段、水印和配乐的意外表现,加上 2026 年 11 月 2 日跑出的 5 条片段。

Kiki, OmniaKey COO11 分钟阅读
本页内容

用 HappyHorse 1.1 图生视频,把静图作为 first_frame POST 到 https://api.omniakey.com/v1/media/tasks,模型 ID 用 happyhorse-1.1-i2v,然后轮询任务、下载 MP4。2026 年 11 月 2 日,我们跑了 5 条 5 秒 720P 的片段,每条用时 92 到 158 秒。每条都带了没要求过的音乐,默认还会加一个 "Happy Horse" 水印。

简短回答

  • 请求:模型 happyhorse-1.1-i2v,操作 image_to_video,input.media 里正好一个 first_frame。
  • 画面比例:片段跟随静图,因为没有 ratio 字段。
  • 时长和分辨率:3 到 15 秒,480P、720P 或 1080P。resolution 每次都要传,阿里云的默认值是 1080P。
  • 水印:默认开启,传 watermark: false 关闭。
  • 声音:我们 5 条片段都有音乐,阿里云的 API 没有音频开关,可以用 ffmpeg 去掉音轨。

第一次调用 HappyHorse 1.1 图生视频要准备什么?

需要三样东西:一个 key、Python 3,以及一张符合阿里云规则的静图。

  • key 放在 OMNIAKEY_API_KEY。脚本把它作为 Bearer token 发送,代码里不留明文。
  • Python 3,不用装任何东西。脚本只用标准库。
  • 静图要符合 阿里云的图生视频 API 参考:JPEG、JPG、PNG 或 WEBP;宽高至少 300 像素;不超过 20 MB;宽高比 1:2.5 到 2.5:1。阿里云没有写像素上限。

麻烦在体积:内联静图跟着请求体一起走,整个请求含 Base64 必须小于 1 MiB(OmniaKey 媒体 API 概览,2026 年 11 月 2 日核对)。脚本超过 700 KB 就停下;再大就压缩静图,或者传公开的 HTTPS 链接。我们的 2K 静图是 2,254,819 字节,下面这条 macOS 命令把它压到 92,212 字节:

bash
sips -s format jpeg -s formatOptions 85 -Z 1280 still.jpg --out still-small.jpg

请求里有哪些字段?

九个字段决定任务:顶层三个,input 里两个,parameters 里四个。

字段取值说明
modelhappyhorse-1.1-i2v1.1 图生视频的模型 ID
typevideo任务产出的文件类型
operationimage_to_video不带前缀的名字
input.prompt文本OmniaKey 要求必填,阿里云的 API 视为可选;最多 5,000 个非中文字符或 2,500 个中文字符,超出会被截断
input.media正好一个 {"type": "first_frame", "url": ...}公开的 HTTPS 链接或 data URI
parameters.resolution480P、720P 或 1080P每次都传:阿里云默认 1080P
parameters.duration整数秒,3 到 15OmniaKey 上必填
parameters.watermarktrue(默认)或 falsefalse 去掉 "Happy Horse" 文字
parameters.seed0 到 2147483647同一个 seed 也不保证同一条片段

有四个细节容易漏。

  • 没有 ratio 字段:片段保持静图的宽高比(阿里云图生视频 API 参考,2026 年 11 月 2 日核对)。
  • 阿里云的页面没有负向提示词字段。
  • 每次创建任务都要带 Idempotency-Key 请求头。同一个 body 重放会返回原来的任务,不会重复扣费;body 不同会得到 409 idempotency_key_reused(OmniaKey 的 视频 API 文档,2026 年 11 月 2 日核对)。
  • 输出尺寸会变:OmniaKey 的文档里,1200×630 的静图用 720P 生成,回来是 1324×696。

Python 脚本

下面是实际运行的完整文件,只用标准库。

python
"""Animate one still with HappyHorse 1.1 image-to-video through the OmniaKey media API.

Usage:
    export OMNIAKEY_API_KEY="your-omniakey-api-key"
    python3 hh_i2v.py still.jpg "The camera slowly orbits the headphones." clip.mp4

The still can be a local JPEG or PNG (sent inline as a data URL) or a public https:// URL.
"""
import base64
import json
import mimetypes
import os
import sys
import time
import urllib.error
import urllib.request
import uuid

API = "https://api.omniakey.com/v1/media/tasks"
HEADERS = {
    "Authorization": "Bearer " + os.environ["OMNIAKEY_API_KEY"],
    "Content-Type": "application/json",
    "User-Agent": "happyhorse-i2v-example/1.0",
}
POLL_SECONDS = 10
GIVE_UP_AFTER = 15 * 60  # most clips finish in 1-5 minutes


def call(method, url, body=None, extra_headers=None):
    data = json.dumps(body).encode() if body is not None else None
    req = urllib.request.Request(url, data=data, method=method, headers={**HEADERS, **(extra_headers or {})})
    for attempt in range(3):
        try:
            with urllib.request.urlopen(req, timeout=60) as resp:
                return json.load(resp)
        except urllib.error.HTTPError as err:
            sys.exit(f"HTTP {err.code}: {err.read().decode(errors='replace')}")
        except (urllib.error.URLError, TimeoutError, ConnectionError) as err:
            if attempt == 2:
                raise
            print("network error, retrying:", err)  # a retried POST keeps its Idempotency-Key
            time.sleep(5)


def first_frame_url(image):
    if image.startswith("https://"):
        return image
    raw = open(image, "rb").read()
    if len(raw) > 700_000:  # Base64 adds a third, and the whole request must stay under 1 MiB
        sys.exit("The still is over 700 KB. Resize it or pass a public https:// URL instead.")
    mime = mimetypes.guess_type(image)[0] or "image/jpeg"
    return f"data:{mime};base64,{base64.b64encode(raw).decode()}"


def main(image, prompt, out_path):
    task = call("POST", API, {
        "model": "happyhorse-1.1-i2v",
        "type": "video",
        "operation": "image_to_video",
        "input": {"prompt": prompt, "media": [{"type": "first_frame", "url": first_frame_url(image)}]},
        "parameters": {"resolution": "720P", "duration": 5, "watermark": False},  # watermark is on by default
    }, {"Idempotency-Key": str(uuid.uuid4())})
    print("task", task["id"], task["status"])

    start = time.time()
    while task["status"] in ("queued", "processing"):
        if time.time() - start > GIVE_UP_AFTER:
            sys.exit(f"Still {task['status']} after 15 minutes. Do not submit it again; "
                     f"check it later with GET {API}/{task['id']}")
        time.sleep(POLL_SECONDS)
        task = call("GET", f"{API}/{task['id']}")
    print(task["status"], "after", round(time.time() - start), "s")
    if task["status"] != "succeeded":
        sys.exit(json.dumps(task.get("error") or task))

    # The signed download URL is short-lived, so save the file right away.
    req = urllib.request.Request(task["assets"][0]["url"], headers={"User-Agent": HEADERS["User-Agent"]})
    with urllib.request.urlopen(req, timeout=300) as resp, open(out_path, "wb") as f:
        f.write(resp.read())
    print("saved", out_path)


if __name__ == "__main__":
    main(*sys.argv[1:4])

保存为 hh_i2v.py,然后运行:

bash
export OMNIAKEY_API_KEY="your-omniakey-api-key"
python3 hh_i2v.py still.jpg "The camera slowly orbits the headphones." clip.mp4

我们那次 watermark: false 的运行打印了这些:

text
task task_QqK3ZdAd72vmK1DSOuOxXSytBSaJ244v queued
succeeded after 91 s
saved data/clips/c5-orbit-nowm.mp4

脚本里有五处值得注意。

  • 每 10 秒轮询一次。
  • 15 分钟后放弃,并提示不要再提交。
  • 网络错误会重试。重试的创建请求保留 Idempotency-Key,拿回原来的任务,不会多扣一次费。
  • 任务成功后马上保存文件,因为签名下载链接的有效期很短。
  • 每个请求都带 User-Agent:2026 年 10 月 29 日我们测 Kling 3.0 API 时,Python 默认的 User-Agent 被 Cloudflare 以 error code: 1010 返回 HTTP 403。

我们跑的五条片段

我们用 Nano Banana 2.1 生成了四张静图,又把耳机那张跑了两次来测水印。2026 年 11 月 2 日一共得到五条片段,都是 5 秒、720P。人像、湖面和狐狸三条用了默认设置,所以画面里带水印。

耳机环绕

prompt
The camera slowly orbits about 90 degrees to the right around the headphones while a soft band of light sweeps across the ear cups. The headphones stay perfectly still on the pedestal. Smooth, steady product-commercial camera move.
八帧画面:黑色耳机放在石台上。镜头从耳机一侧转到另一侧,中间几帧里耳机后面出现一道弧形背景边缘。
环绕片段按时间顺序的八帧,0.0 到 4.85 秒,水印设为 false。HappyHorse 1.1 经 OmniaKey API 图生视频,5 秒,720P,2026 年 11 月 2 日生成。

镜头从耳机一侧转到另一侧,耳机始终留在石台上。中间几帧里,耳机后面出现静图中没有的弧形背景边缘;提示词要的那道光带很难看出来。

同一张静图、同一段提示词,我们跑了两次:一次默认设置,一次 watermark: false。右下角能看到差别。

两条片段右下角的对比。上面一条有白色 Happy Horse 文字,下面一条把 watermark 设为 false,是干净的。
两条环绕片段最后一帧的右下角,已放大。上面:默认设置。下面:水印设为 false。HappyHorse 1.1 经 OmniaKey API 图生视频,5 秒,720P,2026 年 11 月 2 日生成。

雨中人像

prompt
She slowly turns her head toward the camera and gives a small smile while light rain keeps falling. The neon signs behind her flicker softly and the camera pushes in a little.
四帧画面:穿黄色雨衣的女人站在湿漉漉的霓虹街上。她从向左看转为面向镜头并微笑,镜头从半身推到特写。
雨中人像片段按时间顺序的四帧,0.0 到 4.85 秒,带默认水印。HappyHorse 1.1 经 OmniaKey API 图生视频,5 秒,720P,2026 年 11 月 2 日生成。

她从向左看转为面向镜头并微笑,顺序和提示词一致,每一帧都带水印。提示词要求轻微推进,画面从半身变成脸部特写。

湖面推进

prompt
Slow aerial push-in over the water toward the rowboat. Mist drifts across the lake, the boat rocks gently and small ripples spread from its hull, and the golden light grows a little brighter.
八帧画面:日出时雾蒙蒙的湖面上一艘木船。镜头不断推进,直到小船占满大部分画面,船身周围散开水波。
湖面片段按时间顺序的八帧,0.0 到 4.85 秒,带默认水印。HappyHorse 1.1 经 OmniaKey API 图生视频,5 秒,720P,2026 年 11 月 2 日生成。

镜头向小船推进,和提示词一致。到结尾时小船占了大部分画面,船身周围散开水波。

狐狸插画

prompt
The fox turns a page of the book with its paw and its ears twitch. A few orange leaves drift down from the tree and the branches sway gently. Keep the flat illustration style.
四帧扁平插画:一只狐狸在秋天的树下看书。橙色叶子飘落,镜头从整棵树推近到狐狸。
狐狸片段按时间顺序的四帧,0.0 到 4.85 秒,带默认水印。HappyHorse 1.1 经 OmniaKey API 图生视频,5 秒,720P,2026 年 11 月 2 日生成。

从第一帧到最后一帧,扁平插画风格都保持住了,橙色叶子不断飘落。镜头从整棵树推近到狐狸特写,这一点提示词没有要求;书页翘了起来,不过画面不能确认爪子翻了页。

左:我们发出去的狐狸静图,能看到整棵树。右:片段最后一帧,镜头近得多,狐狸和打开的书清楚可见,还是同样的扁平风格,右下角有 Happy Horse 水印。
左:作为第一帧发出去的静图。右:狐狸片段最后一帧。HappyHorse 1.1 经 OmniaKey API 图生视频,5 秒,720P,2026 年 11 月 2 日生成。

我们 4 段提示词里有 2 段,镜头动得比要求的多,所以先跑一条短片确认取景。文档里最短、最低的一档是 3 秒 480P(阿里云图生视频 API 参考,2026 年 11 月 2 日核对)。

文件实测数据

片段比例像素帧数耗时字节
环绕,默认16:91286×716123128 秒1,486,548
环绕,watermark: false16:91286×71612198 秒1,320,527
雨中人像9:16716×1286123158 秒2,108,577
湖面16:91286×716123131 秒2,691,558
狐狸1:1960×96012392 秒2,405,557

每个文件标的时长都是 5.16 秒,虽然我们要的是 5 秒:那是音频流的长度,视频流 123 帧时是 5.13 秒,121 帧时是 5.04 秒。五条都是 24 fps 的 H.264,带一条双声道 AAC 音轨,切镜检测脚本没有发现任何剪切点。

我们的片段从提交到下载用了 92 到 158 秒。阿里云文档给图生视频任务的时间是 1 到 5 分钟(阿里云图生视频 API 参考,2026 年 11 月 2 日核对)。我们没有测试 480P、1080P、其它时长、seed、公开图片链接、HappyHorse 1.0,以及阿里云自己的接口地址。要比较模型,看 HappyHorse 1.1 对比 Seedance 2.0 和 HappyHorse 1.1 对比 Kling 3.0。不想写代码,也可以在 AI 视频生成器 里直接用 HappyHorse 1.1 重跑。

为什么片段里有声音?

HappyHorse 1.1 给五条片段都加了配乐,虽然我们的提示词都没要求。没有人试听:我们通过 OmniaKey API 让 Gemini 3.8 Flash 描述每条音轨。

片段模型的描述平均响度
环绕,默认“有节奏的嘻哈鼓点,带切分打击乐、拍手和柔和的合成器和弦。”−19.5 dB
环绕,watermark: false“舒缓而有节奏的电子音乐,稳定的节拍和旋律化的合成器音色”−20.5 dB
雨中人像“缓慢、忧郁而轻柔的钢琴旋律,配柔和的环境氛围声”−22.6 dB
湖面“缓慢、轻柔而抒情的钢琴旋律”−20.2 dB
狐狸“用柔和铃音演奏的平静环境旋律”,加上“砾石上的脚步声”−27.4 dB

Gemini 3.8 Flash 在五条音轨里都没有报告人声。同样的提示词和静图跑两次,得到两条不同的音轨。

阿里云的图生视频参考里没有音频字段,也没有静音选项,不过 1.1 的发布说明提到音画同步(阿里云的新发布模型页面,2026 年 11 月 2 日核对)。要得到无声文件,下载后去掉音轨:

bash
ffmpeg -i clip.mp4 -an -c:v copy silent.mp4

我们在 watermark: false 那条上跑了这条命令,结果有视频流、没有音频流。画面完全不变,因为 -c:v copy 直接复制视频流,不重新编码。

结果能保留多久?

在 OmniaKey 上,MP4 的签名链接大约有效 1 小时,任务记录保留 24 小时;再轮询一次任务就能拿到新链接(OmniaKey 媒体 API 概览,2026 年 11 月 2 日核对)。在阿里云自己的 API 上,视频链接和任务 ID 都保留 24 小时,之后查询返回 UNKNOWN,文件已经删除。任务成功就尽快下载。

会遇到哪些错误?

我们五次运行都没有失败,所以这份列表来自 OmniaKey 的视频 API 文档,2026 年 11 月 2 日核对。

状态含义处理
400 invalid_request请求体格式不对,或者任务没有 input.prompt对照上面的请求结构检查
400 model_price_error时长超出模型范围,或者分辨率没有定价换支持的时长和分辨率
403 model_not_allowedkey 或分组没有这个模型检查 key 的模型权限
409 idempotency_key_reused同一个键已经用不同的 body 发过只在完全相同的重试里复用键
503 no_available_channel当前没有渠道提供这个模型或操作稍后再试,或者看控制台

任务以 failed 结束时自动退款,所以失败的渲染不花钱,只耽误时间(OmniaKey 媒体 API 概览,2026 年 11 月 2 日核对)。

别把自己这边的超时当成任务失败。继续轮询同一个任务 ID;重新提交会开第二个任务,也会再扣一次费。如果确实要重发,保持同一个 Idempotency-Key 和同样的 body,就能拿回原来的任务。

一条 HappyHorse 1.1 片段多少钱?

一条 5 秒 720P 片段按阿里云新加坡的标价是 $0.70。下面是阿里云的每秒价格,来自它的价格页,2026 年 11 月 2 日核对:

分辨率新加坡北京和 Global
480P$0.07$0.0618845
720P$0.14$0.123769
1080P$0.18$0.165026

账单是每秒价格乘以输出秒数。失败的请求不计费。新加坡还有 10 秒的免费额度,有效期 90 天。价格页里,Global 价格适用于法兰克福、弗吉尼亚和东京。

OmniaKey 按渲染输出的秒数计费,创建任务时预扣,失败或取消的任务自动退款;当前价格见 HappyHorse 1.1 页面。

能直接调用阿里云吗?

可以。HappyHorse 在阿里云 Model Studio 上提供服务,新加坡、美国(弗吉尼亚)、北京、法兰克福和东京都有区域接口地址(阿里云图生视频 API 参考,2026 年 11 月 2 日核对)。我们的运行都走 OmniaKey 的 API,下面的内容来自阿里云的文档。

  • 新加坡用 POST https://{WorkspaceId}.ap-southeast-1.maas.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis 创建。
  • 带上 X-DashScope-Async: enable 请求头,否则请求会以 "current user api does not support synchronous calls" 失败。
  • 每 15 秒左右轮询 GET .../api/v1/tasks/{task_id};状态依次是 PENDING、RUNNING、SUCCEEDED、FAILED、CANCELED、UNKNOWN。
  • 模型、接口地址和 key 放在同一个区域,跨区域调用会失败。
  • 一个 key 每秒 5 个请求、5 个并发任务(阿里云的限流页面,2026 年 11 月 2 日核对)。

价格页列出了东京,限流页没有东京的 1.1 图生视频条目,所以东京这一项还没有确认。

国内怎么用

OmniaKey 支持人民币直充(支付宝、微信支付),一个 key 就能调用多家模型,包括 HappyHorse 1.1 和我们用来生成静图的 Nano Banana 2.1,不用自己再去申请阿里云的账号。上面的 Python 脚本就是我们实际跑的请求,把你自己的 key 填进 OMNIAKEY_API_KEY 就能用。

常见问题

用 HappyHorse 图生视频必须写提示词吗?

在 OmniaKey 上必须写:没有 input.prompt 的任务会得到 400 invalid_request(OmniaKey 视频 API 文档,2026 年 11 月 2 日核对)。阿里云自己的 API 把提示词视为可选,只用第一帧也能生成。无论哪种,都写清动作和镜头运动,像上面几段提示词那样。

怎么去掉 Happy Horse 水印?

传 parameters.watermark: false。默认的 true 会在右下角画上白色小字 "Happy Horse";我们第二条环绕片段传了 false,回来是干净的。

怎么设置画面比例?

裁静图。图生视频没有 ratio 字段,片段跟随第一帧的形状,所以 16:9 的静图得到 16:9 的片段,竖图得到 9:16 的片段。裁切比例保持在 1:2.5 到 2.5:1 之间。

有 HappyHorse 1.5 吗?

截至 2026 年 11 月 2 日,阿里云的模型列表、价格表和生命周期页面里都没有 1.1 之后的版本。这些页面上的最新版本是 happyhorse-1.1-i2v,发布于 2026 年 6 月 16 日。有些站点用了 "Happy Horse 1.5" 这个名字。

图生视频选 HappyHorse 1.1 还是 1.0?

阿里云说 1.1 提升了画质、动态表现和片段间一致性,价格页也给 1.1 单独列了 480P 档。1.1 在 2026 年 6 月 16 日发布,1.0 在 2026 年 4 月 22 日发布。按阿里云新加坡的价格,1.1 的 1080P 每秒 $0.18,1.0 是 $0.24。

参考来源

OmniaKey 自己的文档,2026 年 11 月 2 日核对:视频 API 和 媒体 API 概览。

文中提到的模型

HappyHorse 1.1图生视频AI 视频视频 APIPython

相关文章

最新文章

热门指南