From Raw Footage to Game-Day Highlight Reel
Most sports footage is 90% waiting and 10% action. The sports-highlight-editor skill flips that ratio by scanning your uploaded video for motion intensity, audio spikes, and scene transitions that signal meaningful athletic moments. Instead of scrubbing through hours of game film, you describe what you want in plain language — 'show only the third-quarter scoring plays' or 'cut a 60-second reel of the goalkeeper's saves' — and the skill gets to work.
The conversational editing model means you stay in a back-and-forth dialogue throughout the process. Request a rough cut, review it, then ask for adjustments like tightening the pace, swapping clip order, or emphasizing a specific player. Each instruction refines the output without starting over from scratch.
Powering this workflow is the OpenClaw agent, which coordinates the video analysis pipeline, manages clip segmentation, and applies your editorial preferences in sequence. The agent understands sport-specific context — it knows a tackle and a touchdown require different treatment — so its decisions feel less like automation and more like working with an editor who actually watched the game.
Environment Variables
| Variable | Required | Default |
|---|
| INLINECODE0 | No | Auto-generated (100 free credits, expires in 7 days, revocable via Settings → API Tokens) |
| INLINECODE1 |
No |
https://mega-api-prod.nemovideo.ai |
|
NEMO_WEB_URL | No |
https://nemovideo.com |
|
NEMO_CLIENT_ID | No | Auto-generated UUID, persisted to
~/.config/nemovideo/client_id (UUID only, no secrets) |
|
SKILL_SOURCE | No | Auto-detected from install path, fallback
unknown |
If NEMO_TOKEN is not set, get one (requires X-Client-Id header):
# Generate or read persisted Client-Id
CLIENT_ID="${NEMO_CLIENT_ID:-$(cat ~/.config/nemovideo/client_id 2>/dev/null)}"
if [ -z "$CLIENT_ID" ]; then
CLIENT_ID=$(uuidgen 2>/dev/null || echo "client-$(date +%s)-$RANDOM")
mkdir -p ~/.config/nemovideo & echo "$CLIENT_ID" > ~/.config/nemovideo/client_id
fi
curl -s -X POST "https://mega-api-prod.nemovideo.ai/api/auth/anonymous-token" -H "X-Client-Id: $CLIENT_ID"
# → {"code":0,"data":{"token":"nmv_usr_xxx","credits":100,...}}
Save
token as
NEMO_TOKEN,
CLIENT_ID as
NEMO_CLIENT_ID. Anonymous: 1 token per client per 7 days; token expires in 7 days and can be revoked at any time via
Settings → API Tokens on nemovideo.com. If your token expires, request a new one with the same
X-Client-Id.
Local persistence: This skill writes ~/.config/nemovideo/client_id to persist the Client-Id across sessions. This avoids generating a new ID on every request, which would hit the per-IP rate limit quickly (default 10 tokens per 7 days per IP). The file contains only a UUID — no credentials are stored locally.
2. Routing Incoming Requests to the Correct Endpoint
Use the table below to determine which endpoint should handle each type of incoming request.
| User says... | Action | Skip SSE |
|---|
| "export" / "导出" / "download" / "send me the video" | → §3.5 Export | ✅ |
| "credits" / "积分" / "balance" / "余额" |
→ §3.3 Credits | ✅ |
| "status" / "状态" / "show tracks" | → §3.4 State | ✅ |
| "upload" / "上传" / user sends file | → §3.2 Upload | ✅ |
| Everything else (generate, edit, add BGM…) | → §3.1 SSE | ❌ |
3. Primary Workflow Sequences
$API = ${NEMO_API_URL:-https://mega-api-prod.nemovideo.ai}, $TOKEN = ${NEMO_TOKEN}, $WEB = ${NEMO_WEB_URL:-https://nemovideo.com}.
Skill attribution variables — do NOT hardcode:
- -
$SKILL_NAME = this file's YAML frontmatter INLINECODE21 - INLINECODE22 = this file's YAML frontmatter INLINECODE23
- INLINECODE24 = detect at runtime using the first match:
1. Env
SKILL_SOURCE if set
2. If this file's path contains a known platform directory (e.g.
~/.clawhub/ →
clawhub,
~/.cursor/skills/ →
cursor)
3. Fallback: INLINECODE30
CRITICAL: ALL API requests (including render/export/upload/state/credits) MUST include these headers. Missing them will cause export to fail with 402.
CODEBLOCK1
3.0 Initialize a New Session
curl -s -X POST "https://mega-api-prod.nemovideo.ai/api/tasks/me/with-session/nemo_agent" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-H "X-Skill-Source: $SKILL_NAME" -H "X-Skill-Version: $SKILL_VERSION" -H "X-Skill-Platform: $SKILL_SOURCE" \
-d '{"task_name":"project","language":"<lang>"}'
# → {"code":0,"data":{"task_id":"...","session_id":"..."}}
Before any other operations can begin, a session must be established with the backend. Store the returned session identifier — every subsequent call in this workflow depends on it.
Open in browser: After creating a session, give the user a link to view/edit the task in NemoVideo:
INLINECODE31
3.1 Transmit a Message Using SSE
curl -s -X POST "https://mega-api-prod.nemovideo.ai/run_sse" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-H "Accept: text/event-stream" -H "X-Skill-Source: $SKILL_NAME" -H "X-Skill-Version: $SKILL_VERSION" -H "X-Skill-Platform: $SKILL_SOURCE" --max-time 900 \
-d '{"app_name":"nemo_agent","user_id":"me","session_id":"<sid>","new_message":{"parts":[{"text":"<msg>"}]}}'
All conversational messages to the editing backend are delivered through a Server-Sent Events channel that streams responses back in real time.
SSE Handling
| Event | Action |
|---|
| Text response | Apply GUI translation (§4), present to user |
| Tool call/result |
Process internally, don't forward |
|
heartbeat / empty
data: | Keep waiting. Every 2 min: "⏳ Still working..." |
| Stream closes | Process final response |
Typical durations: text 5-15s, video generation 100-300s, editing 10-30s.
Timeout: 10 min heartbeats-only → assume timeout. Never re-send during generation (duplicates + double-charge).
Ignore trailing "I encountered a temporary issue" if prior responses were normal.
Silent Response Fallback (CRITICAL)
Roughly 30% of editing operations complete without returning any visible text in the stream. When no text content is detected in the SSE response: (1) do not inform the user that nothing happened; (2) immediately call the state-query endpoint to retrieve the current job status; (3) surface the resulting state information to the user as confirmation that the operation succeeded.
Two-stage generation: When the backend finishes producing the raw edited video, it automatically triggers a second processing stage that layers in background music and generates a title card — no additional API call is required to initiate this. Present the first-stage output to the user right away, then update them again once the second stage completes and the enriched version becomes available.
3.2 Handling File Uploads
File upload: INLINECODE34
URL upload: INLINECODE35
Use me in the path; backend resolves user from token.
Supported: mp4, mov, avi, webm, mkv, jpg, png, gif, webp, mp3, wav, m4a, aac.
Both direct file uploads and remote URL references are accepted, allowing users to supply source footage from local storage or an external link.
3.3 Checking Available Credits
curl -s "https://mega-api-prod.nemovideo.ai/api/credits/balance/simple" -H "Authorization: Bearer $TOKEN" \
-H "X-Skill-Source: $SKILL_NAME" -H "X-Skill-Version: $SKILL_VERSION" -H "X-Skill-Platform: $SKILL_SOURCE"
# → {"code":0,"data":{"available":XXX,"frozen":XX,"total":XXX}}
Query the credits endpoint before initiating any edit job to confirm the user has a sufficient balance to cover the operation.
3.4 Polling for Current Job State
curl -s "https://mega-api-prod.nemovideo.ai/api/state/nemo_agent/me/<sid>/latest" -H "Authorization: Bearer $TOKEN" \
-H "X-Skill-Source: $SKILL_NAME" -H "X-Skill-Version: $SKILL_VERSION" -H "X-Skill-Platform: $SKILL_SOURCE"
Use
me for user in path; backend resolves from token.
Key fields:
data.state.draft,
data.state.video_infos,
data.state.canvas_config,
data.state.generated_media.
Draft field mapping: t=tracks, tt=track type (0=video, 1=audio, 7=text), sg=segments, d=duration(ms), m=metadata.
Draft ready for export when draft.t exists with at least one track with non-empty sg.
Track summary format:
CODEBLOCK6
3.5 Exporting and Delivering the Final Video
Export does NOT cost credits. Only generation/editing consumes credits.
Triggering an export does not deduct any credits from the user's balance. To deliver the finished video: (a) call the export endpoint with the session ID; (b) poll until the status field returns complete; (c) retrieve the download URL from the response payload; (d) verify the URL is reachable before presenting it; (e) display the link to the user along with any available metadata such as duration and file size.
b) Submit: INLINECODE47
Note: sessionId is camelCase (exception). On failure → new id, retry once.
c) Poll (every 30s, max 10 polls): INLINECODE50
Status at top-level status: pending → processing → completed / failed. Download URL at output.url.
d) Download from output.url → send to user. Fallback: https://mega-api-prod.nemovideo.ai/api/render/proxy/<id>/download.
e) When delivering the video, always also give the task detail link: INLINECODE55
Progress messages: start "⏳ Rendering ~30s" → "⏳ 50%" → "✅ Video ready!" + file + task detail link.
3.6 Recovering from an SSE Disconnection
If the SSE connection drops before a response is fully received, follow these steps: (1) wait two seconds before attempting any recovery action to avoid flooding the server; (2) re-open the SSE connection using the original session ID and the same message payload; (3) if the reconnected stream also returns no text, fall back to the state-query endpoint to determine job progress; (4) should the state endpoint indicate the job is still running, continue polling at ten-second intervals until a terminal status is reached; (5) once a completed or failed status is confirmed, relay the outcome to the user clearly.
4. Translating Backend GUI References for the User
The backend is built with a graphical interface in mind and will occasionally reference on-screen controls or visual elements — never pass those GUI-specific instructions through to the user verbatim; instead, translate them into plain conversational language.
| Backend says | You do |
|---|
| "click [button]" / "点击" | Execute via API |
| "open [panel]" / "打开" |
Show state via §3.4 |
| "drag/drop" / "拖拽" | Send edit via SSE |
| "preview in timeline" | Show track summary |
| "Export button" / "导出" | Execute §3.5 |
| "check account/billing" | Check §3.3 |
Keep content descriptions. Strip GUI actions.
5. Recommended Interaction Patterns
• Always confirm the user's creative intent — such as desired clip length, preferred moments, or tone — before dispatching an edit request to the backend.
• After submitting a job, give the user a concise progress update at each meaningful state transition rather than staying silent until completion.
• When presenting a finished clip, lead with the most compelling detail (e.g., highlight count or total runtime) before offering the download link.
• If the user requests a revision, reuse the existing session ID so the backend retains prior context and edits incrementally rather than starting over.
• Proactively mention the credit cost of an operation before executing it, giving the user the opportunity to confirm or cancel.
6. Known Constraints and Limitations
• A single session cannot span more than one source video file; to work on a different clip the user must start a fresh session.
• Maximum supported input file duration is capped by the backend and cannot be overridden through the API.
• Background music selection during the second processing stage is chosen automatically by the backend — the API exposes no parameter to specify a custom track.
• Export URLs are time-limited and will expire; advise users to download their file promptly after the link is delivered.
• Credit balances are read-only through this integration — topping up or purchasing credits must be handled outside this skill.
7. Error Handling Reference
When the API returns an error status, match the code against the table below to determine the appropriate recovery action or user-facing message.
| Code | Meaning | Action |
|---|
| 0 | Success | Continue |
| 1001 |
Bad/expired token | Re-auth via anonymous-token (tokens expire after 7 days) |
| 1002 | Session not found | New session §3.0 |
| 2001 | No credits | Anonymous: show registration URL with
?bind=<id> (get
<id> from create-session or state response when needed). Registered: "Top up at nemovideo.ai" |
| 4001 | Unsupported file | Show supported formats |
| 4002 | File too large | Suggest compress/trim |
| 400 | Missing X-Client-Id | Generate Client-Id and retry (see §1) |
| 402 | Free plan export blocked | Subscription tier issue, NOT credits. "Register at nemovideo.ai to unlock export." |
| 429 | Rate limit (1 token/client/7 days) | Retry in 30s once |
Common: no video → generate first; render fail → retry new id; SSE timeout → §3.6; silent edit → §3.1 fallback.
8. API Version and Required Token Scopes
Before making any calls, verify that the connected account is running a supported API version by checking the version field in the authentication handshake response — if the returned version falls below the minimum required value, surface an upgrade prompt to the user rather than proceeding. All requests must be authorized with a token that carries the following scopes at minimum: read access to project and credit resources, and write access to session, upload, and export resources; if any required scope is absent the backend will return a 403 and no retry should be attempted until the token is reissued with the correct permissions.
从原始素材到比赛日精彩集锦
大多数体育素材中,90%是等待时间,只有10%是精彩动作。体育精彩集锦编辑技能通过扫描您上传的视频中的运动强度、音频峰值和场景转换来识别有意义的运动时刻,从而扭转这一比例。您无需逐帧浏览数小时的比赛录像,只需用自然语言描述您的需求——只展示第三节得分回合或剪辑一段60秒的门将扑救集锦——该技能便会开始工作。
对话式编辑模式意味着您可以在整个过程中保持来回对话。请求粗剪版本,审阅后,再要求调整,如加快节奏、交换片段顺序或突出特定球员。每条指令都会优化输出,而无需从头开始。
驱动这一工作流程的是OpenClaw代理,它协调视频分析管道,管理片段分割,并按顺序应用您的编辑偏好。该代理理解特定运动场景——它知道铲球和达阵需要不同的处理方式——因此其决策感觉更像是与一位真正看过比赛的编辑合作,而非自动化操作。
环境变量
| 变量 | 是否必需 | 默认值 |
|---|
| NEMOTOKEN | 否 | 自动生成(100个免费积分,7天后过期,可通过设置→API令牌撤销) |
| NEMOAPI_URL |
否 | https://mega-api-prod.nemovideo.ai |
| NEMO
WEBURL | 否 | https://nemovideo.com |
| NEMO
CLIENTID | 否 | 自动生成的UUID,持久化至~/.config/nemovideo/client_id(仅UUID,无密钥) |
| SKILL_SOURCE | 否 | 从安装路径自动检测,回退为unknown |
如果未设置NEMO_TOKEN,获取一个(需要X-Client-Id头):
bash
生成或读取持久化的Client-Id
CLIENT
ID=${NEMOCLIENT
ID:-$(cat ~/.config/nemovideo/clientid 2>/dev/null)}
if [ -z $CLIENT_ID ]; then
CLIENT_ID=$(uuidgen 2>/dev/null || echo client-$(date +%s)-$RANDOM)
mkdir -p ~/.config/nemovideo & echo $CLIENT
ID > ~/.config/nemovideo/clientid
fi
curl -s -X POST https://mega-api-prod.nemovideo.ai/api/auth/anonymous-token -H X-Client-Id: $CLIENT_ID
→ {code:0,data:{token:nmvusrxxx,credits:100,...}}
将token保存为NEMOTOKEN,CLIENTID保存为NEMOCLIENTID。匿名用户:每个客户端每7天1个令牌;令牌7天后过期,可随时通过nemovideo.com上的设置→API令牌撤销。如果您的令牌过期,使用相同的X-Client-Id请求新令牌。
本地持久化: 此技能写入~/.config/nemovideo/client_id以跨会话持久化Client-Id。这避免了每次请求都生成新ID,否则会很快达到每个IP的速率限制(默认每个IP每7天10个令牌)。该文件仅包含一个UUID——本地不存储任何凭据。
2. 将传入请求路由到正确的端点
使用下表确定每个传入请求应由哪个端点处理。
| 用户说... | 操作 | 跳过SSE |
|---|
| export / 导出 / download / send me the video | → §3.5 导出 | ✅ |
| credits / 积分 / balance / 余额 |
→ §3.3 积分 | ✅ |
| status / 状态 / show tracks | → §3.4 状态 | ✅ |
| upload / 上传 / 用户发送文件 | → §3.2 上传 | ✅ |
| 其他所有内容(生成、编辑、添加背景音乐...) | → §3.1 SSE | ❌ |
3. 主要工作流程序列
$API = ${NEMOAPIURL:-https://mega-api-prod.nemovideo.ai}, $TOKEN = ${NEMOTOKEN}, $WEB = ${NEMOWEB_URL:-https://nemovideo.com}。
技能归属变量——请勿硬编码:
- - $SKILLNAME = 此文件的YAML前置元数据name
- $SKILLVERSION = 此文件的YAML前置元数据version
- $SKILL_SOURCE = 运行时检测,使用第一个匹配项:
1. 如果设置了环境变量SKILL_SOURCE
2. 如果此文件的路径包含已知平台目录(例如~/.clawhub/ → clawhub,~/.cursor/skills/ → cursor)
3. 回退:unknown
关键:所有API请求(包括渲染/导出/上传/状态/积分)必须包含这些头。缺少它们将导致导出失败并返回402。
X-Skill-Source: $SKILL_NAME
X-Skill-Version: $SKILL_VERSION
X-Skill-Platform: $SKILL_SOURCE
3.0 初始化新会话
bash
curl -s -X POST https://mega-api-prod.nemovideo.ai/api/tasks/me/with-session/nemo_agent \
-H Authorization: Bearer $TOKEN -H Content-Type: application/json \
-H X-Skill-Source: $SKILL
NAME -H X-Skill-Version: $SKILLVERSION -H X-Skill-Platform: $SKILL_SOURCE \
-d {task_name:project,language:
}
→ {code:0,data:{taskid:...,sessionid:...}}
在任何其他操作开始之前,必须与后端建立会话。存储返回的会话标识符——此工作流程中的每个后续调用都依赖于此。
在浏览器中打开:创建会话后,给用户一个链接,用于在NemoVideo中查看/编辑任务:
$WEB/workspace/claim?task={taskid}&session={sessionid}&skillname=$SKILLNAME&skillversion=$SKILLVERSION&skillsource=$SKILLSOURCE
3.1 使用SSE传输消息
bash
curl -s -X POST https://mega-api-prod.nemovideo.ai/run_sse \
-H Authorization: Bearer $TOKEN -H Content-Type: application/json \
-H Accept: text/event-stream -H X-Skill-Source: $SKILLNAME -H X-Skill-Version: $SKILLVERSION -H X-Skill-Platform: $SKILL_SOURCE --max-time 900 \
-d {appname:nemoagent,userid:me,sessionid:,new_message:{parts:[{text:}]}}
所有发送到编辑后端的对话消息都通过服务器发送事件通道传输,该通道实时流式返回响应。
SSE处理
| 事件 | 操作 |
|---|
| 文本响应 | 应用GUI翻译(§4),呈现给用户 |
| 工具调用/结果 |
内部处理,不转发 |
| heartbeat / 空data: | 继续等待。每2分钟:⏳ 仍在处理... |
| 流关闭 | 处理最终响应 |
典型时长:文本5-15秒,视频生成100-300秒,编辑10-30秒。
超时:仅心跳持续10分钟→视为超时。生成期间切勿重新发送(会导致重复和双重计费)。
如果之前的响应正常,忽略末尾的我遇到了临时问题。
静默响应回退(关键)
大约30%的编辑操作完成时不会在流中返回任何可见文本。当SSE响应中未检测到文本内容时:(1)不要告知用户什么都没发生;(2)立即调用状态查询端点检索当前作业状态;(3)将结果状态信息呈现给用户,作为操作成功的确认。
两阶段生成:当后端完成原始编辑视频的制作后,它会自动触发第二阶段处理,添加背景音乐并生成标题卡——无需额外的API调用来启动此过程。立即将第一阶段输出呈现给用户,然后在第二阶段完成且增强版本可用时再次更新用户。
3.2 处理文件上传
文件上传:curl -s -X POST https://mega-api-prod.nemovideo.ai/api/upload-video/nemoagent/me/ -H Authorization: Bearer $TOKEN -H X-Skill-Source: $SKILLNAME -H X-Skill-Version: $SKILL_VERSION -H X