video

video

AI视频生成:文生视频、图生视频、视频生视频、模型选择。 用于根据提示或参考生成短视频片段(例如:雨中猫的5秒片段、动画化这张照片、重新风格化这个视频)。

19Star
10Fork
更新于 2026/7/28
SKILL.md
readonly只读
name
video
description

AI视频生成:文生视频、图生视频、视频生视频、模型选择。 用于根据提示或参考生成短视频片段(例如:雨中猫的5秒片段、动画化这张照片、重新风格化这个视频)。

version
3.4.2

video

在Starchild上,所有视频生成请求都使用此技能。

核心原则: 调用提供的脚本。不要重新实现代理/计费/上传逻辑。


1. 文生视频(最常见)

⚠️ 执行上下文——请先阅读。
下面的代码块是Python,不是shell命令。Starchild的bash工具
运行/bin/bash -c,它无法解析exec(open(...))——直接粘贴到
bash命令中会失败,报错syntax error near unexpected token 'open'
此外,python3 -c中的exec(open(...))会因NameError: __file__失败,
因为脚本使用__file__进行路径解析。

通过bash工具调用时,请使用python3 - <<'EOF'配合from exports import

python3 - <<'EOF'
import sys
sys.path.insert(0, "skills/video")
from generate_video import generate_video
result = generate_video(
    prompt="A cinematic drone shot over snowy mountains at sunrise",
    model="balanced",
    duration=5,
)
print(result)
EOF

heredoc(<<'EOF')保留所有引号和换行——无需转义。
注意:video技能没有exports.py——直接从generate_video导入。

exec(open('skills/video/generate_video.py').read())
result = generate_video(
    prompt="A cinematic drone shot over snowy mountains at sunrise",
    model="balanced",   # "budget" | "balanced" | "premium"
    duration=5,
)
# result -> {"success": True, "cost": 0.70, "video_url": "...", "local_path": "output/videos/..."}

generate_video自动执行:提交→轮询→获取结果→将mp4下载到output/videos/

向用户交付结果——重要

切勿将原始video_url(例如https://*.fal.media/.../*.mp4)交给用户。 fal使用Content-Security-Policy: sandbox; default-src 'none'提供这些文件,这意味着:

  • 在浏览器中打开链接会显示空白页面(不会触发内联播放器)。
  • 通过<video>/<iframe>嵌入会被CSP阻止。
  • 没有Content-Disposition: attachment头,因此浏览器也不会自动下载。
  • URL侧的调整(查询参数、?download=1等)无法解决此问题——只有服务器端更改头才能解决,而我们无法控制fal的CDN。

唯一可靠的面向用户的交付路径是已下载的本地文件

  1. 使用result["local_path"](例如output/videos/xxx.mp4)——generate_video成功时始终下载。
  2. 告知用户文件已保存到output/videos/<filename>,并可在工作区文件面板/文件浏览器中查看。
  3. 在Web渠道上,也将其内联嵌入,以便用户在聊天中预览:
    ![video](output/videos/<filename>.mp4)
    
    (或链接为[video](output/videos/<filename>.mp4)——工作区直接提供这些文件,并带有正确的头)。
  4. 在Telegram/微信上:通过send_to_telegram(file_path="output/videos/...", message_type="video")send_to_wechat(file_path="output/videos/...", message_type="video")发送文件。

如果下载失败(缺少local_path)——重新获取:

curl -L -o output/videos/<filename>.mp4 "<video_url>"

然后交付本地路径。仍然不要将原始fal URL作为主要交付物提供给用户。


2. 图生视频/视频生视频(参考素材)

fal.ai需要参考素材作为公共HTTPS URL。fal存储上传需要您的密钥当前没有的Serverless权限。可靠的方式是通过已发布的Starchild预览公开素材。

标准流程

  1. 使用publish_asset.py将素材放入或复制output/fal_assets/
  2. 确保名为fal-assets的预览正在运行并已发布(一次性设置,见§3)。
  3. 构建公共URL<preview_base>/<filename>
  4. 调用generate_video(... image_url=public_url)
# 步骤1:将本地图片发布到素材文件夹
exec(open('skills/video/publish_asset.py').read())
asset = publish_local('/path/to/your/photo.jpg')
# 或:publish_from_url('https://example.com/photo.jpg')

filename = asset['filename']

# 步骤2:与预览的公共基础URL结合(见§3)
public_url = f"https://community.iamstarchild.com/<user_slug>-fal-assets/{filename}"

# 步骤3:图生视频
exec(open('skills/video/generate_video.py').read())
result = generate_video(
    prompt="gentle cinematic camera push-in",
    model="balanced",
    duration=5,
    image_url=public_url,
)

当提供image_url时,generate_video自动将模型路径从*/text-to-video重写为*/image-to-video。相同的方法适用于视频生视频模型——传递mp4 URL即可。

素材约束(由publish_asset.py强制执行)

  • 图片:.jpg .jpeg .png .webp .gif .bmp,最大10 MB
  • 视频:.mp4 .mov .webm .mkv .m4v,最大100 MB
  • 超出此范围的任何内容在发布前都会被拒绝

3. 一次性fal-assets公共预览设置

每个工作区运行一次。预览会跨会话保持运行。

# 3.1 确保素材文件夹存在并包含占位索引
import os, pathlib
pathlib.Path('output/fal_assets').mkdir(parents=True, exist_ok=True)
if not os.path.exists('output/fal_assets/index.html'):
    open('output/fal_assets/index.html', 'w').write(
        '<!doctype html><html><body><h1>fal asset host</h1></body></html>'
    )

# 3.2 启动预览
preview(action='serve', dir='output/fal_assets', title='fal-assets')

# 3.3 发布到公共URL
preview(action='publish', preview_id='<id from step 3.2>', slug='fal-assets', title='fal-assets')
# → 公共基础:https://community.iamstarchild.com/<user_slug>-fal-assets/

发布后,公共基础URL可重复用于未来的每个图生视频/视频生视频任务。放入output/fal_assets/的文件立即可通过<base>/<filename>访问——无需重新发布。

验证:

curl -sI https://community.iamstarchild.com/<user_slug>-fal-assets/<filename>
# 预期:HTTP/2 200, content-type: image/* or video/*

如果preview(action='serve')返回No available ports in pool,询问用户哪个现有预览可以停止以释放端口——切勿静默终止。


4. 模型选择

层级 模型 每5秒成本 备注
budget fal-ai/wan/v2.5/text-to-video $0.25 最快、最便宜;适合提示迭代
balanced alibaba/happy-horse/text-to-video $0.70 默认;最佳唇形同步,适用于大多数用例
premium bytedance/seedance-2.0/fast/text-to-video $1.20 最佳运动+相机方向
mini bytedance/seedance-2.0/mini/text-to-video $0.36 (480p) / $0.77 (720p) 最便宜的Seedance;按分辨率分层,无1080p。时长必须是字符串"5",不是5"5s")——见下面的陷阱
xai/grok-imagine-video/v1.5/image-to-video 每5秒$0.41 (480p) / $0.71 (720p) 仅图生视频(单个必需的image_url,无image_urls);+$0.01输入图片附加费已包含在估算中。⚠️ resolution="1080p"在模式上有效,但上游没有公布价格——代理以400拒绝并关闭
fal-ai/kling-video/v3/turbo/standard/text-to-video 每5秒$0.56 Kling v3 Turbo Standard,固定$0.112/s;.../turbo/pro/... = $0.14/s ($0.70/5s);.../v3/4k/... = $0.42/s ($2.10/5s)。所有都有i2v变体
alibaba/happy-horse/v1.1/text-to-video 每5秒$0.70 (720p) / $0.90 (1080p) v1.1有自己的1080p层级**$0.18/s**(不是v1.0的2×规则);还有/image-to-video/reference-to-video

⚠️ Happy Horse默认分辨率上游为1080p(v1.0和v1.1):省略resolution会按1080p层级计费(v1.1 5s = $0.90;v1.0 ref2v 5s = $1.40)。显式传递resolution="720p"以获得更便宜的费率。无效的分辨率值会被代理以400拒绝。

参考视频alibaba/happy-horse/reference-to-video.../v1.1/reference-to-video):传递image_urls=[...](1–9个公共HTTP(S) URL的列表)——不是单个image_url参数。generate_video()验证数量和URL方案,并提交image_urls负载字段。

通过将完整模型ID传递给generate_video(model=...)来覆盖。图生视频变体通过将text-to-video替换为image-to-video自动派生。

定价详情和模型注册表位于generate_video.py::estimate_cost


5. 轮询现有请求

exec(open('skills/video/poll_status.py').read())
result = poll_video("019ded6c-d871-7290-bbf1-ddc6993f8958")

当之前的generate_video调用超时或您只有request_id时使用。


6. 提供的脚本

  • generate_video.py — 提交→轮询→下载。处理文生视频和图生视频。
  • publish_asset.py — 将本地文件(或下载远程URL)复制到output/fal_assets/,以便通过fal-assets预览提供。
  • poll_status.py — 通过request_id恢复轮询,完成后下载结果。

7. 故障排除

问题 修复
image_url must be a public HTTP(S) URL 使用publish_asset.py + fal-assets预览,然后传递公共URL
No available ports in pool(预览服务) 询问用户要停止哪个预览;不要自动终止
downstream_service_error after COMPLETED 参考素材主机在渲染过程中失败——重新编码/调整大小为16:9,重新发布,重试
HTTP 402 insufficient_credits 充值余额;提交时预扣费用
HTTP 403 endpoint_not_allowed sc-proxy只允许批准的fal视频端点;从模型表中选择一个
生成上游FAILED 缩短提示,删除不常见的标记,在更改模型前重试一次
HTTP 422 literal_error on duration (Seedance Mini) Mini要求duration字符串"5""10""auto"),不是整数也不是"5s"。当model包含seedance-2.0/mini时,generate_video()自动编码此问题——仅当您手动构建请求体时才会遇到。其他Seedance变体接受整数/"5s"
任务卡在IN_PROGRESS超过15分钟 保存request_id,稍后使用poll_status.py恢复
用户报告fal.media链接“显示空白”/“空白页面” 预期行为——fal使用CSP: sandbox; default-src 'none'提供。交付result["local_path"]处的本地文件,而不是原始URL(见§1)。

8. 基础设施(参考)

  • 调用者 → sc-proxyqueue.fal.run(和api.fal.ai)→ fal模型提供商
  • 所有请求必须包含Authorization: Key fake-falai-key-12345(代理注入真实的FAL_KEY
  • 提交时预扣费。轮询/结果调用免费。
  • 允许的端点:注册模型的视频文生视频/图生视频/视频生视频/编辑视频。其他任何内容返回403 endpoint_not_allowed
  • 最终mp4位于https://*.fal.media/...——公共CDN,下载无需认证。

9. 维护

  • 添加新模型→在generate_video.py::estimate_costtransparent-proxy/apis/falai.py::_VIDEO_PRICING中注册价格。
  • 本技能有意使用fal存储上传进行素材托管:生产环境的FAL_KEY缺少Serverless权限。在情况改变之前,继续使用基于预览的方法。