video
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesevideo
视频生成
Use this skill for all video-generation requests on Starchild.
Core principle: call the provided scripts. Do not re-implement proxy/billing/upload plumbing.
在Starchild上,所有视频生成请求均可使用此技能。
核心原则: 调用提供的脚本。请勿重新实现代理/计费/上传相关逻辑。
1. Text-to-video (most common)
1. 文本转视频(最常用)
python
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,
)python
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/..."}
result -> {"success": True, "cost": 0.70, "video_url": "...", "local_path": "output/videos/..."}
`generate_video` automatically: submits → polls → fetches result → downloads mp4 to `output/videos/`.
`generate_video`会自动执行:提交任务 → 轮询状态 → 获取结果 → 将mp4文件下载至`output/videos/`目录。Delivering the result to the user — IMPORTANT
向用户交付结果——重要提示
Never hand the user the raw (e.g. ). fal serves these files with , which means:
video_urlhttps://*.fal.media/.../*.mp4Content-Security-Policy: sandbox; default-src 'none'- Opening the link in a browser shows a blank page (no inline player triggered).
- Embedding via /
<video>is blocked by CSP.<iframe> - There is no header, so the browser does not auto-download either.
Content-Disposition: attachment - URL-side tweaks (query params, , etc.) cannot fix this — only a server-side header change would, and we don't control fal's CDN.
?download=1
The only reliable user-facing delivery path is the already-downloaded local file:
- Use (e.g.
result["local_path"]) —output/videos/xxx.mp4always downloads on success.generate_video - Tell the user the file is saved to and is viewable in the workspace file panel / file browser.
output/videos/<filename> - On Web channel, also embed it inline so the user can preview it in chat:
(or link asmarkdown
— the workspace serves these directly with the right headers).[video](output/videos/<filename>.mp4) - On Telegram / WeChat: send the file via or
send_to_telegram(file_path="output/videos/...", message_type="video").send_to_wechat(file_path="output/videos/...", message_type="video")
If the download somehow failed ( missing) — re-fetch with:
local_pathbash
curl -L -o output/videos/<filename>.mp4 "<video_url>"Then deliver the local path. Still do not give the user the raw fal URL as the primary deliverable.
切勿直接将原始(例如)提供给用户。 fal采用策略提供这些文件,这意味着:
video_urlhttps://*.fal.media/.../*.mp4Content-Security-Policy: sandbox; default-src 'none'- 在浏览器中打开链接会显示空白页面(无法触发内嵌播放器)。
- 通过/
<video>嵌入会被CSP阻止。<iframe> - 不存在头,因此浏览器不会自动下载文件。
Content-Disposition: attachment - URL侧的调整(查询参数、等)无法解决此问题——只有修改服务器端头部才能解决,而我们无法控制fal的CDN。
?download=1
唯一可靠的用户交付路径是已下载的本地文件:
- 使用(例如
result["local_path"])——output/videos/xxx.mp4在成功时总会自动下载文件。generate_video - 告知用户文件已保存至,可在工作区文件面板/文件浏览器中查看。
output/videos/<filename> - 在Web渠道中,还可将文件内嵌到聊天中供用户预览:
(或链接为markdown
——工作区会使用正确的头部直接提供这些文件)。[video](output/videos/<filename>.mp4) - 在Telegram / 微信中:通过或
send_to_telegram(file_path="output/videos/...", message_type="video")发送文件。send_to_wechat(file_path="output/videos/...", message_type="video")
如果下载失败(缺失)——可通过以下命令重新获取:
local_pathbash
curl -L -o output/videos/<filename>.mp4 "<video_url>"然后交付本地路径。仍需注意切勿将原始fal URL作为主要交付内容提供给用户。
2. Image-to-video / video-to-video (reference assets)
2. 图像转视频 / 视频转视频(参考资产)
fal.ai needs the reference asset as a public https URL. fal storage upload requires a Serverless permission your key currently does not have. The reliable path is to expose the asset via a published Starchild preview.
fal.ai需要参考资产为公开HTTPS URL。fal存储上传需要Serverless权限,而当前你的密钥不具备该权限。可靠的解决方案是通过已发布的Starchild预览暴露资产。
Standard procedure
标准流程
- Drop or copy the asset into using
output/fal_assets/.publish_asset.py - Make sure a preview named is running and published (one-time setup, see §3).
fal-assets - Build the public URL as .
<preview_base>/<filename> - Call .
generate_video(... image_url=public_url)
python
undefined- 使用将资产放入或复制到
publish_asset.py目录。output/fal_assets/ - 确保名为的预览已启动并发布(一次性设置,见第3节)。
fal-assets - 构建公开URL,格式为。
<preview_base>/<filename> - 调用。
generate_video(... image_url=public_url)
python
undefinedStep 1: publish a local image into the asset folder
步骤1:将本地图像发布到资产文件夹
exec(open('skills/video/publish_asset.py').read())
asset = publish_local('/path/to/your/photo.jpg')
exec(open('skills/video/publish_asset.py').read())
asset = publish_local('/path/to/your/photo.jpg')
or: publish_from_url('https://example.com/photo.jpg')
或:publish_from_url('https://example.com/photo.jpg')
filename = asset['filename']
filename = asset['filename']
Step 2: combine with the preview's public base URL (see §3)
步骤2:与预览的公开基础URL组合(见第3节)
public_url = f"https://community.iamstarchild.com/<user_slug>-fal-assets/{filename}"
public_url = f"https://community.iamstarchild.com/<user_slug>-fal-assets/{filename}"
Step 3: image-to-video
步骤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,
)
`generate_video` auto-rewrites the model path from `*/text-to-video` to `*/image-to-video` whenever `image_url` is provided. The same approach works for video-to-video models — pass an mp4 URL instead.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即可。Asset constraints (enforced by publish_asset.py
)
publish_asset.py资产约束(由publish_asset.py
强制执行)
publish_asset.py- Image: , max 10 MB
.jpg .jpeg .png .webp .gif .bmp - Video: , max 100 MB
.mp4 .mov .webm .mkv .m4v - Anything outside these is rejected before publish
- 图像:,最大10 MB
.jpg .jpeg .png .webp .gif .bmp - 视频:,最大100 MB
.mp4 .mov .webm .mkv .m4v - 超出上述范围的内容会在发布前被拒绝
3. One-time fal-assets
public preview setup
fal-assets3. fal-assets
公开预览的一次性设置
fal-assetsRun this once per workspace. The preview keeps running across sessions.
python
undefined每个工作区只需运行一次。预览会在会话间持续运行。
python
undefined3.1 ensure the asset folder exists with a placeholder index
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>'
)
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 start the preview
3.2 启动预览
preview(action='serve', dir='output/fal_assets', title='fal-assets')
preview(action='serve', dir='output/fal_assets', title='fal-assets')
3.3 publish to a public URL
3.3 发布到公开URL
preview(action='publish', preview_id='<id from step 3.2>', slug='fal-assets', title='fal-assets')
preview(action='publish', preview_id='<id from step 3.2>', slug='fal-assets', title='fal-assets')
→ public base: https://community.iamstarchild.com/<user_slug>-fal-assets/
→ 公开基础URL:https://community.iamstarchild.com/<user_slug>-fal-assets/
After publish, the public base URL is reusable for every future image-to-video / video-to-video task. Files dropped into `output/fal_assets/` become reachable as `<base>/<filename>` immediately — no re-publish needed.
Verify with:
```bash
curl -sI https://community.iamstarchild.com/<user_slug>-fal-assets/<filename>
发布后,公开基础URL可重复用于未来所有图像转视频/视频转视频任务。放入`output/fal_assets/`的文件会立即变为`<base>/<filename>`可访问状态——无需重新发布。
验证方法:
```bash
curl -sI https://community.iamstarchild.com/<user_slug>-fal-assets/<filename>expect: HTTP/2 200, content-type: image/* or video/*
预期结果:HTTP/2 200,content-type: image/* 或 video/*
If `preview(action='serve')` returns `No available ports in pool`, ask the user which existing preview can be stopped to free a port — never silently kill one.
---
如果`preview(action='serve')`返回`No available ports in pool`,请询问用户可以停止哪个现有预览以释放端口——切勿静默终止任何预览。
---4. Model selection
4. 模型选择
| Tier | Model | Cost / 5s | Notes |
|---|---|---|---|
| budget | | $0.25 | Fastest, cheapest; good for prompt iteration |
| balanced | | $0.70 | Default; best lip-sync, most use cases |
| premium | | $1.20 | Best motion + camera direction |
Override by passing the full model id to . Image-to-video variants are auto-derived by replacing with .
generate_video(model=...)text-to-videoimage-to-videoPricing details and model registry live in .
generate_video.py::estimate_cost| 层级 | 模型 | 每5秒成本 | 说明 |
|---|---|---|---|
| budget | | $0.25 | 速度最快、成本最低;适合提示词迭代 |
| balanced | | $0.70 | 默认模型;唇形同步效果最佳,适用于大多数场景 |
| premium | | $1.20 | 运动效果与镜头调度最佳 |
可通过向传入完整模型ID来覆盖默认选择。图像转视频变体可通过将替换为自动派生。
generate_video(model=...)text-to-videoimage-to-video定价详情和模型注册表位于中。
generate_video.py::estimate_cost5. Polling an existing request
5. 轮询现有请求
python
exec(open('skills/video/poll_status.py').read())
result = poll_video("019ded6c-d871-7290-bbf1-ddc6993f8958")Use this when an earlier call timed out or you only have a .
generate_videorequest_idpython
exec(open('skills/video/poll_status.py').read())
result = poll_video("019ded6c-d871-7290-bbf1-ddc6993f8958")当之前的调用超时或仅拥有时,可使用此方法。
generate_videorequest_id6. Provided scripts
6. 提供的脚本
- — submit → poll → download. Handles text-to-video and image-to-video.
generate_video.py - — copy local files (or download remote URLs) into
publish_asset.pyso they can be served by theoutput/fal_assets/preview.fal-assets - — resume polling by
poll_status.py, downloads the result on completion.request_id
- — 提交任务 → 轮询状态 → 下载结果。支持文本转视频和图像转视频。
generate_video.py - — 将本地文件(或下载远程URL)复制到
publish_asset.py目录,以便通过output/fal_assets/预览提供服务。fal-assets - — 通过
poll_status.py恢复轮询,完成后下载结果。request_id
7. Troubleshooting
7. 故障排查
| Problem | Fix |
|---|---|
| Use |
| Ask the user which preview to stop; do not auto-kill |
| Reference asset host failed mid-render — re-encode/resize to 16:9, re-publish, retry |
| Top up balance; cost is pre-charged on submit |
| sc-proxy only allows approved fal video endpoints; pick one from the model table |
Generation | Shorten prompt, drop unusual tokens, retry once before changing model |
Job stuck | Save |
| User reports the fal.media link "shows nothing" / "blank page" | Expected — fal serves with |
| 问题 | 解决方法 |
|---|---|
| 使用 |
| 询问用户停止哪个预览;请勿自动终止 |
| 参考资产主机在渲染中途故障——重新编码/调整为16:9比例,重新发布后重试 |
| 充值余额;提交任务时会预先扣费 |
| sc-proxy仅允许已批准的fal视频端点;从模型表中选择一个 |
上游生成 | 缩短提示词,移除特殊令牌,更换模型前重试一次 |
任务卡在 | 保存 |
| 用户反馈fal.media链接“显示空白”/“空白页面” | 此为预期情况——fal采用 |
8. Infrastructure (reference)
8. 基础设施(参考)
- Caller → →
sc-proxy(andqueue.fal.run) → fal model providersapi.fal.ai - All requests must include (proxy injects the real
Authorization: Key fake-falai-key-12345)FAL_KEY - Pre-charge happens at submit. Poll/result calls are free.
- Allowed endpoints: video text-to-video / image-to-video / video-to-video / edit-video for the registered models. Anything else returns .
403 endpoint_not_allowed - Final mp4 lives at — public CDN, no auth needed for download.
https://*.fal.media/...
- 调用方 → →
sc-proxy(以及queue.fal.run)→ fal模型提供商api.fal.ai - 所有请求必须包含(代理会注入真实的
Authorization: Key fake-falai-key-12345)FAL_KEY - 预先扣费在提交任务时发生。轮询/获取结果的调用免费。
- 允许的端点:已注册模型的视频文本转视频/图像转视频/视频转视频/编辑视频接口。其他任何请求都会返回。
403 endpoint_not_allowed - 最终mp4文件存储在——公开CDN,下载无需认证。
https://*.fal.media/...
9. Maintenance
9. 维护
- Adding a new model → register price in and in
generate_video.py::estimate_cost.transparent-proxy/apis/falai.py::_VIDEO_PRICING - Asset hosting via fal storage upload is intentionally not used in this skill: the production lacks Serverless permission. Keep using the preview-based approach until that changes.
FAL_KEY
- 添加新模型 → 在和
generate_video.py::estimate_cost中注册价格。transparent-proxy/apis/falai.py::_VIDEO_PRICING - 本技能故意不使用fal存储上传来托管资产:生产环境的缺少Serverless权限。在权限变更前,请继续使用基于预览的方案。
FAL_KEY