视频剪辑 Skill
在云端剪辑视频(阿里云 ICE)——不使用本地 ffmpeg。包含三种模式:
- Timeline 剪辑(
SubmitMediaProducingJob)—— 组装多个片段:你编写 Timeline JSON,脚本提交制作任务、轮询任务并返回输出视频 URL。 - 普通模板(
AddTemplate,Type=Timeline)—— 存储参数化的 Timeline Config,检查其ClipsParam契约,并用替换文本/媒体反复渲染 →references/22-normal-templates.md。 - 智能制作(
SubmitIProductionJob)—— 对单个媒体文件运行一种算法(智能封面、logo/字幕擦除、字幕提取、抠像、美颜、横转竖、音频降噪/混音/分离/分析)。不涉及 Timeline → §7.1 和references/13-intelligent-production.md。
本 Skill 是链路的最后一环。 内容理解——发生了什么、在哪里发生、谁在说话、哪些时刻重要——由上游其他能力产出,并作为数据交给本 Skill(§2.4)。本 Skill 负责把那些数据加上素材,变成经过渲染和验证的视频。
硬性规则
以下六条规则没有商量余地。本文档中的其他一切内容——每个字号、颜色、时长、预设和长度比例——都是某个已交付任务的*示例*,而非强制要求。阅读它们是为了了解可能性,然后根据素材和用户需求自行判断。
- 任何东西都不落到用户本地存储。 媒体绝不下载——就地读取(
ffmpeg -i "<https URL>"通过 HTTP 流式读取;快照任务返回带签名的帧 URL)。中间产物存放在 OSS:算法的输出、配音片段、代理文件、转换后的输入——全都是 ICE 任务写入的 OSS 对象,绝不是用户磁盘上的文件。交付物以播放 URL 形式移交(§8),而非下载文件;仅当用户明确要求时才生成本地文件。少数本地工具必须写入才能读取的东西(波形 PNG、silencedetect转写、你查看的帧、edl.json、project.md)放入用户项目之外的一个临时目录——${TMPDIR:-/tmp}/video-editor/<session>——且是一次性的;绝不要在用户工作区中创建它们。用户交来的本地文件先上传到 OSS(§4),再在 OSS 上操作。 - 所有生成都走 ICE;ffmpeg 只分析音频。 剪切、拼接、裁剪、叠加、转场、字幕烧录、混音、变速、语音合成/配音、格式转换:全部由 ICE 任务渲染(Timeline 用
SubmitMediaProducingJob,单媒体算法用SubmitIProductionJob,普通 Timeline 用模板渲染)。ffmpeg 的全部职责是读取音频信号——波形(showwavespic)、静音/语音尾部(silencedetect)、响度(volumedetect)、时长(ffprobe)——除了这些分析数值外不写任何东西(§1.4)。它绝不生成或转换媒体:不使用concat,不对媒体文件使用-filter_complex,不使用-c copy,不重编码,不使用atempo,不转码。帧来自SubmitSnapshotJob,而非 ffmpeg。唯一的例外是图表而非媒体:timeline_view.py从云端快照精灵图中裁出瓦片并叠加在波形上,因为没有任何 ICE API 返回这两者(§1.4)。也不是 Python 媒体库,更不是其他云产品。如果没有任何 ICE 任务能表达用户所需,如实说明并停止——本地渲染的交付物是错误答案,不是变通方案。 - 先确认地域,任何渲染前再确认输出 bucket(§2.1)。模板 Config 生成和
AddTemplate不需要 bucket;渲染才需要。没有默认地域,连cn-shanghai都没有。 - 提交任何东西前用平实语言确认方案(§2.2)。制作任务花费金钱和分钟;一段文字两者都不花。
- 报告任何交付物前先验证它(§9)。
Success只意味着写入了文件,仅此而已。绝不要把未验证的输出报告为已验证。 - 每个多片段 Timeline 都必须编译;绝不直接手写。 即使用户只要
timeline.json并禁止云调用,也要先写edl.json,然后执行python "$SKILL_DIR/scripts/video_editor.py" compile --edl edl.json --output timeline.json——compile是离线的,不发起云调用(§2.1,18-edl-and-compile.md)。生成的文件就是交付物。修复每一个阻塞性检查项违规;compile和submit执行同一套检查清单(§5)。
分工:references/ = 按需阅读的知识库;scripts/video_editor.py = 纯执行器(submit / poll / fetch URL,外加 iproduction / iproduction-status);scripts/frame_qa.py = 对云端素材进行模型审阅——整段视频(--mode full)或带签名的快照帧(--frames),绝不本地采样(§9)。所有剪辑逻辑都在你生成的 Timeline 中。
1. 环境准备
下文中 $SKILL_DIR = 包含本 SKILL.md 的目录。始终用绝对路径调用脚本(python "$SKILL_DIR/scripts/video_editor.py" ...);工作目录通常是用户项目,而非 skill 目录。
pip install -r "$SKILL_DIR/scripts/requirements.txt"
需要 AK/SK(§1.1)和一个 OSS 输出 bucket(§1.2)——没有它们就停下并引导用户。DASHSCOPE_API_KEY(§1.3)和 ffmpeg(§1.4)是可选的:缺失时,改为用你自己的视觉能力读取云端快照帧来验证(§9),绝不跳过验证。
1.1 阿里云凭证(必需)
脚本使用阿里云默认凭证链:环境变量,然后是 aliyun CLI profile(~/.aliyun/config.json,current 指定的 profile,可用 ALIBABA_CLOUD_PROFILE 覆盖),然后是 ~/.alibabacloud/credentials.ini,最后是 ECS RAM 角色。CLI-profile provider 仅存在于 alibabacloud-credentials>=1.0.2,这就是 scripts/requirements.txt 将其下限固定在那里的原因——在更旧版本上,一个完全正常的 aliyun configure profile 会被跳过,失败看起来像凭证缺失,而不是版本问题。
引导用户选择他们偏好的方式:
选项 A —— aliyun CLI(写入可复用 profile;推荐)。如果 aliyun 缺失则安装:
brew install aliyun-cli # macOS;或下载二进制并 tar xzf + sudo mv aliyun /usr/local/bin/
二进制:https://aliyuncli.alicdn.com/aliyun-cli-darwin-arm64-latest.tgz(macOS),https://aliyuncli.alicdn.com/aliyun-cli-linux-amd64-latest.tgz(把 amd64 换成 arm64),https://aliyuncli.alicdn.com/aliyun-cli-windows-amd64-latest.zip(把 aliyun.exe 放到 PATH)
aliyun version # 验证安装 —— 需要 aliyun CLI >= 3.3.3(升级:brew upgrade aliyun-cli,或重新下载二进制)
aliyun configure # 提示输入 AccessKey ID / Secret / region
RAM 角色扮演或 STS token:在提示中选择匹配的认证模式
选项 B —— 在 ~/.zshenv 中设置环境变量(所有 zsh 会话,包括 IDE 终端)
echo 'export ALIBABA_CLOUD_ACCESS_KEY_ID=<id>' >> ~/.zshenv
echo 'export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<secret>' >> ~/.zshenv
从 [AccessKey 控制台](https://ram.console.aliyun.com/manage/ak) 获取密钥。验证 **SDK** 能解析它们——`aliyun sts get-caller-identity` 只能证明 CLI 能读自己的配置,不能证明 Python 链已拾取:
python3 -c "from alibabacloud_credentials.client import Client; print(Client().get_credential().provider_name)"
cli_profile/static_ak → 选项 A 生效;env → 选项 B 生效;CredentialException → 什么都没配置
### 1.2 OSS 输出 bucket(必需)
用于上传和作为任务输出位置:
export OSS_BUCKET=your_bucket_name
export OSS_ENDPOINT=oss-cn-shanghai.aliyuncs.com
bucket 在 Step-0 确认阶段选择(§2.1):运行 `aliyun ossutil ls`,只向用户展示他们确认地域内的 bucket,并让他们选择。绝不静默挑选。OSS 复用相同的凭证链。输出 bucket 必须与制作任务在**同一地域**。
输出 bucket 通常是私有的;§8 涵盖如何把完成的对象变成经过验证的播放链接。
### 1.3 Model Studio API key(可选,用于验证)
`DASHSCOPE_API_KEY` 让 `scripts/frame_qa.py` 能用多模态模型检查完成的视频。它是**独立于 AK/SK 的凭证**——AK/SK 无法调用模型推理。在 [Model Studio 控制台](https://bailian.console.aliyun.com/) → **API-KEY** 创建密钥,然后用 `echo 'export DASHSCOPE_API_KEY=sk-xxxxxxxx' >> ~/.zshenv` 持久化(所有 zsh 会话,包括 IDE 终端)并打开新 shell。如果只有交互式终端需要,改用 `~/.zshrc`;不要在两者中都设置。
**如果用户拒绝或尚未设置**,验证仍然进行——用你自己的视觉能力读取云端快照帧(§9)。提一次该密钥,然后继续;绝不要把未验证的视频报告为已验证。
### 1.4 ffmpeg(可选——仅音频分析)
**剪辑和合成不需要 ffmpeg**——这正是本 Skill 的意义。ffmpeg 在这里只有一个职责:在*理解*和*验证*阶段,把**音频信号**变成模型可以推理的文本或图表。它绝不生成、转换或提取媒体(硬性规则 2),绝不下载媒体文件(硬性规则 1)——给它一个 https URL,它会流式读取所需内容——它唯一写入的文件是临时目录中的分析产物(硬性规则 1)。
用它处理没有任何 ICE API 能返回的音频内容:RMS 波形(`showwavespic`)、静音/语音尾部检测(`silencedetect`——ASR 间隙覆盖句子边界但不覆盖环境音频尾部,`17-snapshot-and-asr.md` §1.5)、响度(`volumedetect`)和时长(`ffprobe`)。把**云端**胶片条与波形堆叠在同一轴上的是 `timeline_view.py`——瓦片来自快照任务;ffmpeg 绘制波形并把两行粘贴成一个 PNG,这是图表而非媒体(硬性规则 2)。所有视觉内容都是云端任务,而非 ffmpeg:帧、胶片条和联系表来自 `SubmitSnapshotJob`(`17-snapshot-and-asr.md` §2),剪辑点来自上游场景标签、`omni_segment.py` 或你阅读的胶片条(§2.4)。
macOS 安装:`brew install ffmpeg`。没有它时:云端快照仍覆盖你需要的每一帧(`17-snapshot-and-asr.md`),你只是失去波形、音频尾部和响度数值——改用 `--mode full` 验证(§9),并如实说明哪些检查无法运行。不要静默降级。
### 1.5 可观测性 —— User-Agent
**UA 模板:** `AlibabaCloud-Agent-Skills/{skill-name}/{session-id} skill-version/{skill-version}`
**Session ID 规则:** 可用时使用宿主的 `AGENT_SESSION_ID`;否则每个进程生成一个 32 位小写十六进制 ID。同一次运行中的每次阿里云调用都必须使用该单一 session ID。这里 `{skill-name}` 是 `alibabacloud-video-editor`,`{skill-version}` 来自 `references/manifest.json`——脚本在导入时、创建任何云客户端之前读取它。`scripts/video_editor.py` 构建一次该值并应用到每个客户端;新客户端也必须设置 `config.user_agent = USER_AGENT`。
---
2. 工作流
| 步骤 | 操作 | 详情 |
|---|---|---|
| 0 | 先确认地域,再确认输出 bucket——先于一切 | → §2.1 |
| 1 | 对请求分类 | → §3 路由表 |
| 2 | 阅读匹配的参考文档 | → §3 |
| 3 | 收集素材 URL | → §4 |
| 4 | 阅读素材——每个未决问题只取一个信号(见下)。先看上游结果(§2.4),然后只运行能回答你仍需决定之事的 asr / snapshot / pack_material.py 流程 | → 17-snapshot-and-asr.md §0、§2.4、19-editor-brief.md |
| 5 | 编写 EDL(剪辑决策),然后 compile 成 Timeline | → 18-edl-and-compile.md;§5 检查清单机械执行 |
| 6 | 用平实语言提出方案——等待确认 | → §2.2 |
| 7 | 提交任务 | → §7 |
| 8 | 轮询,获取签名 URL | → §8 |
| 9 | 验证、自我修复(≤3 轮),然后报告 | → §9 |
单媒体算法请求走捷径:当整个任务是对一个文件运行一种算法(智能封面、logo/字幕擦除、字幕提取、抠像、美颜、横转竖、语音降噪、音频混音/分离、节拍/副歌/质量检测)时,跳过步骤 4-5,从 §2.1 直接进入 §7.1——没有 Timeline,§5 检查清单不适用。步骤 0、3、6、9(地域/bucket、素材 URL、方案确认、验证)仍然适用。如果算法输出随后需与其他素材组装,先运行算法任务,再将其输出送入 timeline 流水线(13-intelligent-production.md §6)。
普通模板创建也走捷径:确认地域,设计并审阅参数化 Config,然后在确认后调用 AddTemplate。在模板渲染之前不需要输出 bucket。阅读 references/22-normal-templates.md。
步骤 4 是按信号进行的,而非全有或全无。 说出你仍需回答的问题,然后只购买能回答它的信号——17-snapshot-and-asr.md §0 是索引。整文件拼接没有未决问题,所以步骤 4 根本不会发生:从步骤 3 直接到步骤 5。用户给定时间和位置的字幕只有一个问题,且是视觉问题——采样一帧并查看它(11-output-verification.md §3);ASR 会回答一个没人问的问题。asr 和 snapshot 是计费任务:“几秒返回”不等于“免费”,运行错误的和运行正确的成本相同。
2.1 环境确认优先
绝不假设地域——连 cn-shanghai 都不行,即使 aliyun CLI profile 或凭证文件中已包含某个地域。对于渲染任务,按此顺序确认:
- 询问用户想在哪个地域提交。列出有效 ICE 地域(
cn-shanghai、cn-beijing、cn-hangzhou、cn-shenzhen、cn-zhangjiakou、ap-southeast-1)并指出约束:AI 功能需要cn-shanghai/cn-beijing/cn-hangzhou——即每个AI_*clip 和 effect 以及每个SubmitIProductionJob函数(§7.1),全部 14 个;MediaId 输入必须在资产自己的地域提交。如果任务尚不明确,用户可暂缓——但在构建任何 Timeline 之前要回到这一步。 - 询问哪个输出 bucket,按已确认地域过滤:
aliyun ossutil ls列出每个 bucket 及其地域——只向用户展示所选地域内的 bucket 并让他们选择。输出 bucket 必须与任务在同一地域。离线生成 Config 或AddTemplate时跳过此步;在首次模板渲染前回到此步。 - 只有在两者都确认后,才询问用户想做什么视频(§3 及以后)。如果任务结果需要不同地域(例如 AI 功能在不支持 AI 的地域,或 MediaId 在别处),回到步骤 1 与用户重新确认。
被阻止的地域是一个问题,绝不回退。 当用户指定的地域无法服务该请求时,说明并停止:指出约束、列出可服务的地域,并要求一个地域及同地域 bucket。不要提交一次以确认本文档已声明之事——iproduction 在任何 API 请求之前本地拒绝该调用,而服务端 400 要往返一次却什么也学不到。也不要自己挑选替代:失败后自行切换地域、bucket 或产品是用户从未做出的第二个决定,会把他们的输出落在他们没要求的地方。“直接提交” / “just submit it” 放弃的是方案确认(§2.2);绝不放弃这一项。
多片段剪辑走 EDL。 每当任务是“组装 N 段源素材”(高光、宣传片、剧集拼接、蒙太奇)时,编写 edl.json——每个保留片段一条,含 source/in/out/beat/quote/reason——并运行 compile(18-edl-and-compile.md)。它产出 Timeline 并机械运行 §5 检查清单,因此迭代意味着编辑一个数字而非重新生成整个 Timeline。装饰不豁免:静音、背景模糊、滤镜和转场是每段的 effects,环境叠加是顶层 EffectTracks,BGM 是 audio 条目——全是 EDL 字段(18-edl-and-compile.md §1)。一个还静音、模糊、加转场并铺音乐床的背靠背拼接仍是拼接,所以仍要编译。只有根本不存在片段列表时才手写 Timeline:单片段任务、数字人旁白、幻灯片模板。
直接生成 Timeline 时,理清:什么输出类型 → 哪些轨道 → 每条轨道哪些片段 → 片段是否需要 In/Out/TimelineIn/TimelineOut(纯背靠背拼接不需要)→ 哪些效果/转场/音量 → 输出 JSON。
当请求在会改变视觉结果方面描述不足时,先问再合成——最重要的背景(没有背景的数字人/旁白视频会渲染在黑底上)。不要静默挑选用户未要求的观感。
2.2 提交前确认方案
一旦素材读完、EDL 起草完毕,用 4-8 句平实语言描述方案并停下。涵盖:剪辑形态、保留和丢弃哪些时刻、预估时长及其与源素材的对比、观感(转场/调色/水印——没有时也要说明)、字幕和音频处理,以及输出规格。然后等待。
问*素材*提出的问题,而非固定清单——正确的问题每次都不同。但有两个几乎总值得问,因为猜错会浪费一次渲染:目标时长和是否需要水印(默认关闭——compile 不发明 EDL 未要求的东西,18-edl-and-compile.md §2)。
什么算确认。 用户能读到的回复中的文字。不是你的内部任务列表或 TODO,不是编译后的 EDL,不是带 --yes 的 submit 命令——该 flag 让*脚本*的 stdin 提示(关于输出路径和覆盖风险)静默,与这一步无关(§7)。compile → submit 一气呵成意味着用户在账单到来时才第一次听说剪辑。所以不要写一个同时覆盖两者的任务项——“陈述方案,然后提交”是一个单个批量工具调用即可勾选的任务项,而方案从未存在。把方案做成独立步骤,完成它、发送它,然后才去碰 submit。如果没人能回答——脚本化或非交互式运行——方案仍要在命令前写出来;缺失人类移除的是回复,不是步骤。
这一步在这里比在本地编辑器更值钱。制作任务花费金钱和分钟,被拒的交付物花费整个往返:一个真实的 79 秒源被剪到 66 秒被拒为“太长,不是高光”,必须在 30 秒重做(19-editor-brief.md §4)。提前一段话本可抓住它。
收到反馈后,修订 EDL 并重新编译——绝不手工修补 Timeline(18-edl-and-compile.md §5)。
2.3 会话记忆 —— project.md
对于会跨越多个会话的项目,在临时目录中 EDL 旁边保留 project.md(硬性规则 1)——绝不在用户项目树中——并每个会话追加一个 ## Session N — YYYY-MM-DD 章节,涵盖:环境(地域、输出 bucket、涉及的 MediaId)、策略(一段话)、决策(剪辑、长度、观感及原因——加上用户拒绝的)、产物(JobId、输出对象路径、值得复用的分析 job id)、待办(延后项)。当用户想保留记录时,粘贴到聊天中或写到他们要求的地方——那是他们的文件,不是中间产物。
有两件事让这在 video editor 中特别有价值。§2.1 不再反复盘问用户——读上次会话并以“上次:cn-beijing / my-bucket,继续?”开场,而非再问一遍。并且分析结果不再重复购买:对未变源已运行的 ASR 或快照任务应被查找,而非重新提交。也要记录被拒绝的内容——用户已否决的策略是最昂贵的重新发现。
启动时,如果 project.md 存在,在提出任何东西之前用一句话总结上次会话。
2.4 上游分析结果——本 Skill 消费什么
链路更早的阶段属于其他能力。当它们交给你数据时,视为权威,不要重新推导:
| 上游结果 | 插入位置 |
|---|---|
剪辑候选 / 高光窗口(from/to + 原因) | EDL 的 ranges[]——in/out 按给定值,理由写入 reason(18-edl-and-compile.md §1) |
| 带时间戳的转写 / 对话时间线 | 替换或交叉检查步骤 4 的 asr 流程 |
| 字幕文件(SRT / WebVTT) | EDL 的 subtitles[],或对展开的 Timeline 使用 decompile --inline-srt(21-timeline-export.md) |
| 标签 / 标签 / 人物出现 | 决定保留哪些窗口;帧级精确的接缝仍来自 ASR 标点 + 间隙(17-snapshot-and-asr.md §1.5) |
| 说话人归属 | 哪条 VoiceId 承载哪句台词,以及术语表名称(17-snapshot-and-asr.md §1.7) |
克隆的 VoiceId(已训练——本 Skill 不训练声音) | AI_TTS clip 上的 customizedVoice(07-smart-media-features.md、09-voice-and-avatar-catalog.md) |
两条规则:
- 上游时间戳是候选级,非帧级精确。 在编译前把每个窗口吸附到真实接缝——标点 + 间隙 ≥ 0.3 秒、上游标签 /
omni_segment.py/ 快照胶片条的镜头边界(§1.4)、silencedetect音频尾部。照搬的粗窗口会截断对白(18-edl-and-compile.md§1.5)。 - 缺失分析是一个问题,不是猜测。 当请求需要你没有的内容知识(哪些时刻重要、谁在说话)时,请用户运行上游能力并交来结果。不要发明窗口,也不要静默回退到整视频剪切。
3. 需求 → 参考路由
找到请求所需能力对应的行,阅读它们,然后构建 Timeline。
这些行是能力,不是场景。没有“高光集”文档,也没有“视频翻译”文档:场景是一种组合,你从下面的行中组合——通常两到三行加上 18-edl-and-compile.md。如果没有单行匹配请求,那是正常情况,不是失败。
| 用户要求 | 阅读 | 关键类型 / 字段 |
|---|---|---|
| 任何内容(轨道与片段基础、时长控制、对齐) | 01-timeline-basics.md | VideoTracks/AudioTracks/SubtitleTracks/EffectTracks、In/Out/TimelineIn/TimelineOut、MainTrack、MaxDuration、ClipId/ReferenceClipId、FECanvas |
| 旁白、解说、BGM、混音、静音、音量、循环音频、降噪、响度归一、提取音频 | 02-multi-track-audio.md | 多个 AudioTracks、Volume(Gain)、AFade、LoopMode、ADenoise、ALoudNorm、AEqualize |
| 标题、字幕、片尾、滚动文字、样式/气泡文字、字幕背景、字幕动画、常驻角标、在已擦除烧录带上定位文字、重写或翻译后整轨重新计时(行宽与停留时间重算、术语表、配音覆盖) | 03-subtitles-and-titles.md(§1 位置,§11 重新计时) | Type: "Text"/"Subtitle"、Content、Alignment+X/Y、FontSize、SubtitleEffects、AaiMotion*、Scroll*、AdaptMode、subtitle_localize.py |
| 转场、滤镜、调色、VFX、蒙版、Ken Burns、缩放、模糊/纯色背景、水印/logo、画中画、分屏 | 04-effects-and-transitions.md | Transition/DLTransition、Filter、VFX、Flip、KenBurns、Zoom、Background、GlobalImage、EffectTracks |
| 照片转视频、图片轮播、幻灯片、相册、片头/片尾标题卡(静帧保持 N 秒) | 05-slideshow-template.md | Type: "Image" + Duration、Transition、KenBurns、BGM |
| 把 N 段组装成剪辑(高光、宣传片、剧集拼接、蒙太奇);记录*为什么*做每个剪辑;提交前验证 Timeline | 18-edl-and-compile.md | compile 子命令、edl.json(sources/ranges/audio/subtitles)、BLOCK vs WARN 检查清单 |
| 拼接多个片段、多集串联、裁剪素材、混合素材类型(静帧 + 视频)、横转竖、贴纸/GIF 叠加、变速、翻转/旋转/裁剪/定格、批量混剪变体 | 06-multi-clip-editing.md | In/Out/MaxOut、Speed、Flip、Rotate、Crop、FreezeFrame、Clip+RandomClip、AdaptMode |
| 文本转语音、语音识别字幕、卡拉 OK 高亮、把台词配音/重录进已有镜头、让重写台词适配镜头时长、跟读旁白、数字人/新闻播报、绿幕或实景背景移除、SSML | 07-smart-media-features.md | AI_TTS、AI_ASR(+AlignmentText、NeedHighlighting)、AI_Avatar、AI_Matting、AI_RealMatting、Harmonization、SpeechRate、customizedVoice、逐行微渲染 |
| 输出分辨率/码率/编码/格式、VOD 或 S3 输出、封面图、完成回调 | 08-output-and-job-config.md | OutputMediaConfig、EditingProduceConfig、MediaMetadata、UserData.NotifyAddress |
选择声音或数字人形象;使用提供的克隆 VoiceId | 09-voice-and-avatar-catalog.md(+ 07-smart-media-features.md 了解接线) | Voice 取值(多情感 / CosyVoice / 方言 / 多语言)、customizedVoice、AvatarId 取值 |
| 用户没有 TTS/数字人旁白脚本 | 10-narration-script-examples.md | Content 脚本风格(故事解说 / 直播带货) |
| 检查完成的视频、帧采样、质量投诉(“输出看起来不对”)、查看某一时刻(这个接缝是否干净、那句台词是否说完、这里画面在做什么)、多段剪切后的接缝验证 | 11-output-verification.md(§6 接缝,§7 重配音输出) | frame_qa.py 整视频审阅、快照采样(--time 毫秒,--count 1 钉住某一瞬间)、帧 QA 盲区、timeline_view.py(胶片条 + 波形,共享轴;--seams edl.json) |
| 剪辑前阅读视频:带时间戳的对话时间线、整视频胶片条 / 联系表、给定时点的帧、用于对齐分析的时间↔像素映射、作为第二意见的镜头/对话分段 | 17-snapshot-and-asr.md(§1.6 真值——一次音频流程、两次云流程——+ omni_segment.py,§1.7 归属,§1.8 转写是草稿) | asr / snapshot 子命令;EditingConfig.SentenceMaxLength、FrameType: normal、Sprite/WebVtt、--cover、--start-time/--duration |
| 所有分析的一个可读视图;决定剪辑可落在哪里 | 17-snapshot-and-asr.md §1.5 | pack_material.py → material_packed.md(间隙 + 标点 + 静音在同一轴) |
| 委托范围选择;选择剪辑形态(高光 / 拼接 / 演示 / 解说 / 访谈 / 蒙太奇) | 19-editor-brief.md | 子 agent brief 模板、结构原型、长度纪律 |
| 一个文件上一种算法:智能封面、视频摘要、移除 logo/台标/水印、擦除烧录字幕、提取字幕到 SRT、绿幕抠像、人脸美颜、横转竖重构、副歌/节拍检测、音频质量检查、语音降噪、音频混音、人声/伴奏分离 | 13-intelligent-production.md | iproduction / iproduction-status、FunctionName、Input/Output、JobParams、输出占位符 |
| 需要本 Skill 不计算的内容知识的请求:视频标签、动作事件、人物出现、关键词时间线、高光候选、说话人归属 | §2.4——请求上游结果,绝不猜测 | EDL ranges[](in/out/reason)、来自 SRT 的 subtitles[]、经 17-snapshot-and-asr.md §1.5 的接缝吸附 |
引擎实际计算的 timeline(在 AI_ASR/AI_TTS/AI_Avatar/VideoDetext 运行后);微调已完成的 AI 结果;在 AI 运行*后*迭代结构而不重跑 AI;把剪辑交给 Premiere | 21-timeline-export.md | export-timeline / export-timeline-status / decompile(+--inline-srt)、ExportType、ProjectId vs Timeline、srt 字幕轨 |
| 创建、生成、检查或渲染可复用普通模板;TemplateId / ClipsParam;可变媒体槽;片头/片尾或默认水印模板 | 22-normal-templates.md | template_editor.py generate/create/get/expand/submit、AddTemplate、标量 $Param、ArrayItems / Array |
| 真实任务现场笔记:提交前 IMS bucket 注册、仅 MediaId 的 ASR 输入、STS vs 长期 AK 签名 URL 交付、防截断拼接规则、无运动观感预设、可填充模板 / ClipsParam 工程 | 23-production-pitfalls.md | aliyun ice get-storage-list、ASR 输入形式、拼接边距、ClipsParam 槽 |
| 权限错误、RAM 设置 | ram-policies.md | ice:*、oss:* 操作 |
AI 功能(AI_*)仅在某些地域运行——在 cn-shanghai、cn-beijing 或 cn-hangzhou 提交。
4. 素材 URL
- 本地文件 → 通过 oss-upload skill 上传,然后使用返回的 OSS URL。
- 已是 URL → 直接使用。裸 URL 不带元数据:当 EDL 需要数值
out(18-edl-and-compile.md)时,用ffprobe "<url>"测量它——它通过 HTTP 流式读取且不写任何东西(硬性规则 1-2)。如果未安装 ffprobe,说明并询问;不要用自制的 MP4/moov 解析器替代,猜时长更糟。 - 逐字复制每个 URL。
MediaURL/FileURL必须与用户输入或更早工具输出逐字符相同。绝不要“规范化”对象键——把一个_重打成-、改变字母大小写或裁掉尾随数字都会产生InvalidMaterial.NotFound: The specified clips url not found。 - 用 MediaId 而非 URL(32 位十六进制资产 id)→ 先运行
media-info(§8)确认文件名、类型、地域和时长(GetMediaInfo在FileInfoList[0].FileBasicInfo.Duration中返回它,因此无需 ffprobe 流程)。在资产自己的地域(或若资产地域缺少 AI 功能,则在支持 AI 的地域)提交任务,并优先选择同一地域的输出 bucket。
5. 提交前检查清单
下面每条规则都来自一个真实失败的任务。提交前扫描此清单——违规会导致制作任务失败(或静默产生错误结果)。
此清单大部分现在机械检查。 compile 和 submit 都会运行它:有失败记录的规则阻塞,其余警告(18-edl-and-compile.md §3)。ICE 没有服务端 dry-run endpoint;Timeline 检查器和普通模板 expand 命令是本地重新实现,因此可能漏掉新的引擎规则。仍要读此清单以了解它们看不到的东西(意图、素材选择、§5-E 参数纪律)。
A. 正确的 clip Type 与放置
| 规则 | 正确 | 错误(失败) |
|---|---|---|
AI 功能前缀 AI_ | AI_ASR、AI_TTS、AI_Matting、AI_RealMatting、AI_Avatar | 裸 ASR / TTS / Matting |
AI_Avatar 是 VideoTrackClips 中的 clip Type | {"Type":"AI_Avatar","AvatarId":...,"Voice":...,"Content":...} | 放到另一个 clip 的 Effects 中 → InvalidTimelineFormat: ... MediaId is empty |
抠像是 clip Effects 中的 effect | {"Type":"AI_RealMatting"} | 抠像 clip Type,或 SubType: "Matting" |
| 绿幕抠像参数 | {"Type":"AI_Matting","Color":"green"} | ColorType / "GreenScreen" |
| 实景(无绿幕)抠像 | AI_RealMatting | AI_Matting(边缘差) |
| 镜像/翻转是专用 effect | {"Type":"Flip","Direction":"horizontal"} | 用 VFX 的 hflip/vflip → InvalidTimelineFormat: Invalid vfx subType |
| 字幕文本字段 | Content | Text |
AI_ASR 有两个有效放置——按意图选择:
- 在
VideoTracks/AudioTracks上某个 clip 的Effects中:{"Type":"AI_ASR","AlignmentText":"...", <style fields>}——字幕由*该 clip 自己的*音频驱动并在同一任务中渲染。旁白 / 数字人视频的首选一步式模式,也是NeedHighlighting/HighlightingStyle唯一有效的放置。 - 作为
SubtitleTracks中的 clip,MediaURL指向源视频——对已有视频语音的普通识别。
语音→字幕始终使用内置 AI_ASR;绝不自己转写音频,也不手工为合成语音定时 Type: "Text" clip。
每个脚本一个 AI_Avatar clip。 把整个旁白放在单个 clip 的 Content 中——按句拆分会让数字人每句都重复开场手势。
B. 音频
- 静音/音量使用
Gain:{"Type":"Volume","Gain":0}(0 = 静音,1 = 原始,>1 放大,最大 10,优先 ≤3)。Volume effect 内的{"Volume": 0}会导致任务失败。 LoopMode仅用于音频 clip:使用一个AudioTrackClipsclip,带LoopMode: true+In/Out+TimelineIn/TimelineOut。要重复视频,使用相邻副本(或模板ArrayItems展开)并把最后一个副本裁剪到目标时长。- 同一轨道上的音频 clip 不得时间重叠;使用单独轨道分层声音。
C. 视觉与效果
- 每个 EffectTrack 一种 effect 类型:每个
EffectTracks条目的EffectTrackItems中只能有一种 effect 类型。Filter 和 VFX 放在单独的 EffectTrack 条目中;混在一起会导致任务失败。(同类型的多个 item 没问题。) GlobalImage需要显式Duration,当 timeline 不含真实视频时——否则它只显示在第一帧。有真实视频时它自动覆盖整个输出。- 要求时背景必须填满屏幕:在背景 clip 上设置
"Width": 1, "Height": 1(画布相对)。仅靠AdaptMode可能留下黑边。 - 常规
Transition会缩短输出其Duration的时长(clip 重叠);使用DLTransition保持总时长不变。
D. Timeline 结构
- 至少一个视频或音频 clip:
VideoTracks和AudioTracks不能都为空——仅字幕 timeline 会失败并报TimelineFormatError: Both video tracks and audio tracks are empty.字幕渲染在*某物之上*,所以无法构建纯文本交付物,要加什么由用户决定,而非你(§2.1)。如果他们没提背景,问他们想要哪种。如果他们明确排除图像、视频和音频,说该请求按原样不可能,并问要放宽哪个约束。绝不要生成或上传资产来通过此检查——黑色 PNG 或静音 WAV 都会覆盖明确指令,并在用户 bucket 留下没人要的对象。 - 更高索引的视频轨道渲染在更低索引之上。
- 省略
TimelineIn/TimelineOut会按数组顺序背靠背拼接 clip。
E. 参数纪律
- 只设置用户要求的参数。 不要为可选样式/效果参数发明值——错误的默认值会静默破坏预期结果:
- 蒙版上的
outer_alpha=1.0让蒙版看起来像没做事;blur_intensity=1.0模糊整个内部。 - 抠像人物叠加上的
Width/Height会重新缩放人物,破坏“同一人,不同背景”。 - 猜的
Gain值会悄悄改变混音。
省略这些字段以应用引擎默认值,或从参考文档复制一个已验证的组合。
- URL 逐字(§4)。
6. 最小 Timeline 示例
完整、简化与时长控制的示例在 references/01-timeline-basics.md 中。手写 Timeline 仅允许用于单 clip Timeline 或导出的 Timeline(§7.2)。 两个或更多 clip 时:写 EDL,然后 compile -e edl.json -O timeline.json(§2 步骤 5,18-edl-and-compile.md)。EDL 通常只有几行,compile 是一条离线命令;它也是唯一机械运行 §5 检查清单的东西——在你自己的脚本中导入 validate_timeline / lint_timeline 并不会运行它。
7. 提交任务
停——§2.2 的方案已在你回复中了吗? 如果你最后发给用户的是命令而非描述剪辑的段落,不要运行这个。compile 和 submit 在同一批工具调用中正是本节要防止的失败。
提交并等待完成(--yes 跳过脚本的 stdin 提示,而非 §2.2)
python "$SKILL_DIR/scripts/video_editor.py" submit \
--timeline timeline.json \
--output-config output.json \
--region <region confirmed in §2.1> \
--wait --yes
`--region` 必填且无默认值。去掉 `--wait` 可提交而不轮询;`--client-token` 使重试幂等。所有 flag:`video_editor.py submit --help`。
> **有两种不同的确认,`--yes` 只覆盖其中一种。** 没有 `--yes` 时脚本在 stdin 询问 `Do you want to proceed? [y/N]` 并在非交互式 shell 中**中止**,所以 agent 基本上总是传它。该 flag 只跳过脚本自己关于输出路径、分辨率、地域和覆盖风险的提示。它*不是* §2.2 的方案确认——没有 flag 能是,因为 §2.2 发生在对话中,在此命令存在之前。只有当方案已在你可见回复中时才到达 `submit`。
`OutputMediaConfig`:
{
"MediaURL": "https://{your-bucket}.oss-cn-shanghai.aliyuncs.com/{your-target-video-path}",
"Width": 1080,
"Height": 1920
}
如果用户未说明分辨率,使用 1080×1920(竖屏)或 1920×1080(横屏)。更多字段(码率、编码、VOD/S3 输出、回调):`08-output-and-job-config.md`。
提交返回 `JobId`。
### 7.0 普通 Timeline 模板
可复用剪辑结构,阅读 `references/22-normal-templates.md`。本地生成 Config,向用户展示其固定资产和替换槽,然后仅在确认后创建持久模板。渲染不熟悉的模板前,`get` 其 `ClipsParam` 并本地 `expand`——绝不猜控制台生成的数字槽 ID,并记住名为 `VideoDuration` 的槽只描述它所替换的字段(references/22 §Parameter Rules)。
python "$SKILL_DIR/scripts/template_editor.py" generate --preset video-concat -o template_config.json
现在停下,把 Config 摆在用户面前:其固定资产、替换槽,以及这些槽隐含的 `ClipsParam` 契约。`AddTemplate` 创建持久云资源,所以这就是 §7 注释说 `--yes` 无法提供的确认。
python "$SKILL_DIR/scripts/template_editor.py" create --name "Video Concatenation Template" \
--config template_config.json --region <confirmed region> --yes
模板渲染是正常制作任务,因此 §2.2 确认、同地域输出 bucket、轮询、§9 验证和 ≤3 轮自我修复都适用(`references/22-normal-templates.md` §Workflow)。
### 7.1 智能制作任务(单媒体算法)
一种算法,一个输入文件,无 Timeline。**提交前阅读 `references/13-intelligent-production.md`**——14 个函数名、其 `JobParams`、所需输出占位符和结果形状不可猜测。
从媒体资产生成智能封面图到 OSS
python "$SKILL_DIR/scripts/video_editor.py" iproduction \
--function Cover --input <mediaId-or-oss://bucket/object> \
--output 'oss://<bucket>/covers/{source}-{sequenceId}.png' \
--job-params '{"Model":""}' \
--region <region confirmed in §2.1> --wait --yes
轮询 / 重读任务
python "$SKILL_DIR/scripts/video_editor.py" iproduction-status --job-id <job_id> --region <region>
- **`SubmitIProductionJob` 没有 ClientToken**——盲目重试会计费第二个任务。重新提交前先查询。
- 输入 bucket、输出 bucket、媒体资产和任务都必须位于**同一地域**。
- **全部 14 个函数都是 AI 功能**:仅 `cn-shanghai` / `cn-beijing` / `cn-hangzhou`。任何其他地域——`cn-shenzhen`、`cn-zhangjiakou`、`ap-southeast-1`——会让 `iproduction` 在到达 API 前本地失败并报 `ValidationError`;服务本身只会回答 `InvalidParameter.FunctionNotSupported`。该拒绝就是此请求的终点:回到 §2.1 向用户要一个地域和同地域 bucket,绝不替代。
- 验证结果(§9)与 timeline 任务完全一样——擦除或美颜任务无论是否改变任何东西都报 `Success`。
### 7.2 项目导出——AI 展开的 Timeline
你提交的 Timeline 持有 AI **声明**(`AI_ASR`、`AI_TTS`、`AI_Avatar`、`VideoDetext`);真实地址和时序只在引擎运行它们之后存在。当用户想要*计算后*的 timeline 时,导出它——`references/21-timeline-export.md` 有命令和 flag。
python "$SKILL_DIR/scripts/video_editor.py" export-timeline \
--project-id <ProjectId from GetMediaProducingJob> \
--bucket <scratch bucket, same region> --prefix export/ep01 \
--region <region confirmed in §2.1> --output timeline_expanded.json --wait --yes
**传 `ProjectId`,不是 `Timeline`**——ProjectId 展开已发生的渲染,而未渲染的 Timeline 会让导出**运行并计费**其 AI 任务。这个 Timeline 可以手工编辑(§11 的例外),因为它背后没有 EDL,但把它 `decompile` 回 EDL 更好:与其他一切相同的循环、离线,且绝不重跑 AI。
---
8. 轮询与报告
查询一次(region = 任务提交的地域)
python "$SKILL_DIR/scripts/video_editor.py" status --job-id <job_id> --region <region>
等待完成
python "$SKILL_DIR/scripts/video_editor.py" status --job-id <job_id> --region <region> --wait
添加 --details 在诊断模板渲染时打印提交的 ClipsParam 和 Timeline。
将 MediaId 解析为签名(认证)URL 和媒体详情(region = 资产的地域)
python "$SKILL_DIR/scripts/video_editor.py" media-info --media-id <media_id> --region <region>
私有 bucket 交付的已验证 V4 签名 URL(支持 AK 和 STS)
zsh "$SKILL_DIR/scripts/oss_sign_clean.sh" oss://<bucket>/<object> [ttl-seconds] [region-or-endpoint]
状态值:`Init`、`Queuing`、`Processing` = 仍在运行;`Success` = 完成;`Failed` = 检查消息找原因。
`Success` 时,`status` 打印任务的 `MediaId`、`MediaURL` 和时长。用该 `MediaId` 运行 `media-info` 获取**签名 URL**——输出 bucket 通常私有,所以普通 OSS URL 不可查看。
**两个 URL,两个任务。** `media-info` URL 是给*你*的、现在用的:约一小时过期,有些 STS 签名的根本无法获取——适合你即将做的 §9 检查,不适合用户稍后要打开的任何东西。你交付的来自 `oss_sign_clean.sh`:V4、携带 STS token、地域限定,并在打印前经 curl 验证。验证失败不是交付物(`23-production-pitfalls.md` §3)。如果签名器本身失败,如实说明,把 `media-info` URL 标注为短时且未验证地传递,并给出重签命令——绝不要让原始 URL 披着已验证 URL 的外衣出去。
**该 URL 是交付物——但还不是答案。** 它只在 §9 之后到达用户。`media-info` 返回时长和分辨率是元数据,不是验证:它无法区分静音 BGM 和已混音 BGM。将其报告为带过期时间和重签一行命令的播放链接;绝不把完成的视频下载到用户机器(硬性规则 1)。仅在用户明确要求时才获取本地副本。
---
9. 验证输出
Success 只意味着写入了文件。错误素材、黑帧、字幕被裁和静音音频都会报 Success。报告任何交付物前先验证它。 完整指南:references/11-output-verification.md。
选择第一个可行的路径:
| 顺序 | 路径 | 命令 | 需要 |
|---|---|---|---|
| 1 | 云端快照帧,你来读(首选) | video_editor.py snapshot --mode normal -i <output MediaId or oss:// object> -r <region> --time <ms> --count 12 --interval 5 -O "oss://<bucket>/qa/f-{Count}.jpg" --wait,然后 snapshot-urls 获取签名链接 | AK/SK + 输出 bucket |
| 2 | 整视频 + 模型 | frame_qa.py --video "<signed URL>" --mode full | DASHSCOPE_API_KEY |
| 3 | 覆盖整个输出的云端胶片条 | video_editor.py snapshot --mode webvtt --cover <duration> → 读精灵图瓦片(§9 接缝检查见下) | AK/SK + 输出 bucket |
帧优先——无论时长成本持平(89 MB / 78 秒视频 → 约 500 KB JPEG,约 3-5k token),而整视频审阅会 token 化每一秒。短转场需要比 5 秒间隔更密的采样:--interval 是秒且只在一个任务内间隔帧,而 --time 是毫秒,所以任何瞬间都有自己的任务(--time <ms> --count 1)——±0.1 秒和 ±0.2 秒的可疑接缝是四个单帧任务(11-output-verification.md §6)。frame_qa.py 只审阅云端素材(--video <signed URL>,或通过 --frames 的签名帧 URL),绝不下载任何东西(硬性规则 1-2)。
没有 DASHSCOPE_API_KEY? 不要跳过验证,也不要因密钥阻塞。路径 1 和 3 根本不需要密钥——用支持 URL 的视觉/浏览器工具检查签名帧 URL。不要把 HTTP URL 传给需要本地绝对路径的文件读取器;必要时,curl 帧到临时目录并检查该文件。你很可能就是多模态模型,所以把自己的视觉当作审阅者。向用户指一次 §1.3,然后继续。视觉是仅针对*画面*问题的免密钥路径——音频主导的交付物走下面的 ffmpeg 聆听路径,而非帧。自己无法读图? 那密钥就不是可选的:把同样的签名帧 URL 交给模型(frame_qa.py --frames "<url>" …)并将其发现报告为模型审阅,而非你自己的。只有在既无视觉又无密钥时,才把输出报告为*未验证*并说明原因。
用户放弃验证(“别检查了” / “just send the URL”)? 尊重它——这是他们的决定,路径 1 花费一个任务和一分钟他们可能不想花。但放弃覆盖的是*运行*检查,不是*报告*:把 URL 标为未验证交付,直说 Success 只证明写入了字节,说明应他们要求跳过了什么(帧、音频尾部、渲染时长与意图对比),并给出会运行它的那一条命令(上方 snapshot,路径 1),以便改主意只花十秒。回复绝不能读起来像已验证的交付物(硬性规则 5)。
当交付物价值在音频或运动时升级到 --mode full——TTS 旁白、AI_Avatar 唇同步、BGM 混音、KenBurns/Scroll* 动画。帧采样听不到音频也看不到同步和卡顿。对于旁白主导输出,把渲染时长与预期旁白时长比较;渲染更短会截断旁白,而无解释的更长可能留下黑/静音尾部。任一不匹配都是失败交付物,即使任务报 Success。比扫描间隔短的转场并非够不着——用单帧任务瞄准它——但每个瞬间花一个任务,所以先扫描,只精确定位看起来不对的。
--mode full 需要密钥。音频主导交付物仍有一条免密钥路径:把 ffmpeg 指向签名输出 URL,读信号而非画面。 那是分析,不是硬性规则 2 禁止的本地混音/渲染——它流式读取,唯一写入的文件是临时目录中的分析产物(§1.4)。对输出运行 volumedetect 或 astats 可判定混音床是否在要求电平、源音频是否存活、尾部是否过早静音。既无密钥又无 ffmpeg 时,报告音频未验证并说明缺哪个——帧扫描不是替代品,因为无论 BGM 在 20% 还是静音,帧看起来都一样。
多段剪切额外需要接缝聚焦验证(每个剪辑处对白完整;若要求水印,放置正确且未被切)——11-output-verification.md §6。模型 QA 很少抓住被切断的台词。工具是 timeline_view.py --seams edl.json:每个接缝一张图,两侧都有,胶片条和音频波形在共享时间轴上。这种配对能抓住主要失败——音频越过视觉剪辑的台词——单帧无法显示,因为剪辑处的帧只是一张脸。
纯整文件拼接不需要源帧。 素材身份已两次证明:URL 逐字复制(§4),ICE 在无法解析时大声失败并报 InvalidMaterial.NotFound。对输出在头、接缝和尾采样,并把渲染时长与源时长之和比较——这能抓住丢文件、换序和黑接缝。把输出帧与源快照像素匹配会为回答 Timeline 已解决的问题买每个锚点一个计费任务。仅当剪辑*转换*了素材——裁剪、抠像、擦除、变速——且你需要看它从什么开始时,才买源帧。
非视频 IProduction 交付物(§7.1)不适合 frame_qa.py:读提取的 SRT 并对照源检查时序和文本;读检测 JSON / Result 并根据媒体时长合理检查范围;音频输出用 --mode full,它会聆听。视频输出(擦除、美颜、横转竖、抠像)走上面的正常路径——在应改变的区域采样帧。
9.1 自我修复循环——上限 3 轮
验证不是你要交出的报告,而是你先闭合的循环:
- 验证。如果一切通过,展示交付物。
- 如果失败,修复真源——EDL,或普通模板渲染的模板 Config/ClipsParam——然后重新编译/展开、重新提交、重新验证。改变假设,而非只是参数类型。
- 3 轮后停止。 如果问题仍存在,把结果标为未交付,列出未解决缺陷,并附上证据;绝不把无解释的不匹配变成“模板行为”或已完成结果。
以比抓住它的那轮更高的分辨率重新验证失败的东西:1 fps 标记的接缝得到 4-8 fps 字幕带条(11-output-verification.md §6),而非又一次 1 fps 扫描。只有先前失败的检查通过后,才声称缺陷已修复。
不要向用户展示你未验证的预览。如果你不会发布它,就不要展示它。
然后报告:实际提交的 Timeline(总结多阶段流水线;当结果取决于轨道如何挂载——来自提取 SRT 的字幕轨、配音音轨、水印/效果层——说明挂载本身,例如 SubtitleTracks[].FileURL → SRT 对象,而不只是 JobId)、输出信息(bucket / 对象路径 / 地域 / MediaId / 时长 / 分辨率 / JobId)、签名观看 URL(注明会过期)、使用了哪条验证路径、其发现、以及它无法检查什么,以及花了多少轮自我修复。
10. 错误 → 修复
在 references/25-error-index.md 中查找消息:每一行都指出原因、最短修复和解释它的章节。报 Success 却仍毁掉交付物的失败是 §11 的内容。
11. 反模式
references/25-error-index.md 列出会大声失败的东西。这些是返回 Success 却仍产生坏交付物——或浪费一次往返——的东西。每个都曾被付出过代价。
流程
- 方案确认前就剪辑。 一次渲染花金钱;一段文字不花(§2.2)。常见形态是
compile直接在同一轮进入submit --yes,把内部任务列表误认为用户看过的方案(§2.2“什么算确认”)。 - 把你没看过的输出报告为看过的。
Success只意味着写入了字节(§9)。常见形态是status→media-info→ “输出已验证”:时长和分辨率是元数据,在音频交付物上它们对混音一言不发(§8、§9)。当用户放弃检查时,说明并标交付物未验证——放弃买的是跳过,不是健康证明(§9)。 - 在同一缺陷上循环超过 3 轮。 命名并移交(§9.1)。
- 验证失败后手工修补 Timeline。 它会偏离产生它的决策,下一轮无从推理——修复 EDL(
18-edl-and-compile.md§5)。唯一例外是导出的 Timeline(§7.2):AI 展开背后没有 EDL,所以直接编辑它是微调结果的唯一方式。 - 微调你提交的 timeline 而非计算后的那个。 其
AI_*条目是占位符——对齐器的句子边界和真实时长不在其中。先导出(§7.2)。 - 对未变源重跑分析。 ASR 和快照输出是未变输入的不可变函数;缓存它们(§2.3)。
- 下载媒体来看它,或把你的工作文件写进用户项目。 流式读取、快照它,把临时文件留在临时目录(硬性规则 1)。完成的视频也一样:交付物是播放 URL(§8),不是他们磁盘上的文件。
project.md已记录地域/bucket 时仍问用户。(§2.3)- 探测一个本文档已声明约束的地域,然后自己移动任务。 在
cn-shenzhen三次InvalidParameter.FunctionNotSupported没教到 §7.1 未说的任何东西;之后切到cn-shanghai和不同 bucket 决定了用户没要求的两个事。在第一次拒绝时停下并询问(§2.1)。
阅读素材
- 快照任务上的
FrameType: intra。 静默交付 ⅓ 的帧且仍报Success(17-snapshot-and-asr.md§2.2)。 - 因为某个未文档化 API 字段出现在响应示例中就信任它。
SubmitASRJob接受并忽略它们而不报错(17-snapshot-and-asr.md§1.3)。 - 根据你的请求参数计算胶片条瓦片坐标。 服务器会重写它们;读 VTT(
17-snapshot-and-asr.md§2.3)。 - 发明上游拥有的内容知识。 高光候选、标签和说话人归属作为数据到来(§2.4);猜的窗口是押在硬币上的计费渲染。请求上游结果,并用
SubmitASRJob获取对话时间线。 - 用
qwen-omni-turbo取时间戳。 即使在 40 秒片段上也会量化并幻觉(17-snapshot-and-asr.md§1.6)。
剪切
- 仅凭静音间隙判断句子边界。 实测:16 个符合间隙条件的候选中 2 个位于句中。要求尾部标点*且*间隙 ≥ 0.3 秒(
17-snapshot-and-asr.md§1.5)。 - 把
Out切在视觉场景变化处。 对话音频经常跨过剪辑;跟随音频尾部(18-edl-and-compile.md§1.5)。 - 为达目标长度在对话块内裁剪。 改为丢弃整块(
18-edl-and-compile.md§1.5)。 - 保留大部分源的“高光”。 79 秒 → 66 秒被拒;30 秒通过。默认 30-40 %(
19-editor-brief.md§4)。 - 把“尽可能长”作为长度选项提供。 把顶部选项上限设为源的一半。
合成
- 为省一次往返的本地 ffmpeg 渲染——
concat片段、-filter_complex叠加、烧录字幕、atempo配音。它写出 ICE 从未产生的交付物,下游无法复现或重编辑,且被彻底禁止(硬性规则 2)。修复 EDL 或 Timeline 并重新提交;如果没有 ICE 任务能表达该剪辑,改为报告它。 - 发明用户从未要求的可选参数。 错误默认值静默破坏预期结果——
outer_alpha=1.0让蒙版看起来像无效;抠像人物上的Width/Height会重新缩放他们(§5-E)。 - Text clip 上的
X/Y。 语义不可靠;仅用Alignment并检查一帧(03-subtitles-and-titles.md)。 - 没人要的水印。 默认关闭(§2.2)。
- 多段剪切上的转场。 它们模糊帧并吞掉台词尾部;除非要求,否则硬切(
18-edl-and-compile.md§1.5)。 - 把
AI_Avatar脚本拆到多个 clip。 数字人每句都重复开场手势(§5-A)。 - 为合成语音手工定时
Textclip。 使用AI_ASR带AlignmentText,让引擎对齐(§5-A)。 - 把
HighlightingStyle.FontColor当 RGB 十六进制。 它是字节序 BGR,无#前缀——与同一 clip 上正常FontColor/OutlineColour字段(#RRGGBB)相反。"00FFFF"渲染黄色;"FFFF00"渲染青色;"#FFFF00"渲染黑色(解析失败)。始终在采样帧中验证颜色(07-smart-media-features.md)。 - 翻译轨复用源字幕时序。 西班牙语/德语比英语长 10-30 %;源 cue 时长是让翻译文本溢出画面或一闪而过的原因。按语言重算换行和停留时间,并延长每个 cue 以覆盖其配音音频(
03-subtitles-and-titles.md§11)。 - 把加快配音作为过长台词的第一修复。 阶梯是重写翻译 → 提高
SpeechRate→ 在 ICE 重渲染中对音频 clip 用Speed(上限约 1.5)——绝不用本地atempo(硬性规则 2)。一个 34 字符台词重写为 21 字符后在自然速度下适配其 2 秒镜头;加速版被拒为“赶”(07-smart-media-features.md)。且绝不改变画面速度来适配音频。 - 信任未经长度检查的配音 ASR 读取。 识别会在截断的 take 上幻觉*完整*句子,并在短窗口发明词——它会隐藏你正在检查的缺陷。先测量音频,再读它(
11-output-verification.md§7)。 - 把提供的
VoiceId接到错误说话人的台词,或试图自己训练。 归属由谁在屏幕上动嘴裁定,而非音色猜测(17-snapshot-and-asr.md§1.7);克隆声音是用户交来的输入(§2.4),绝不是本 Skill 提交的任务(07-smart-media-features.md)。
12. 文件地图
| 路径 | 用途 |
|---|---|
scripts/requirements.txt | Python 依赖 |
related_apis.yaml | 依赖的阿里云 API |
references/manifest.json | Skill 名称 + 版本——UA skill-version/ 来源,在首次云调用前读取(§1.5) |
scripts/video_editor.py | 执行器:compile(离线 EDL → Timeline + 检查清单)/ submit / status / media-info / asr / asr-status / snapshot / snapshot-urls / iproduction / iproduction-status / export-timeline / export-timeline-status / decompile(离线展开 Timeline → EDL) |
scripts/template_editor.py | 普通模板执行器:离线通用 Config 预设和本地 expand / AddTemplate / GetTemplate / TemplateId + ClipsParam 制作任务 |
scripts/frame_qa.py | 仅对云端素材的模型审阅:整视频(--video,§9)或签名快照帧 URL(--frames)——绝不本地采样(硬性规则 1-2) |
scripts/pack_material.py | 合并 ASR + WebVTT + silencedetect 为 material_packed.md——一个时间轴、剪辑标记、缓存 |
scripts/timeline_view.py | 共享轴上的胶片条 + 音频波形;--seams edl.json 用于逐接缝验证 |
scripts/omni_segment.py | qwen3.5-omni-plus 镜头/对话分段——对 ASR 转写的第二意见(17-snapshot-and-asr.md §1.6) |
scripts/oss_sign_clean.sh | 私有 bucket 交付的已验证 OSS V4 签名 URL;支持 AK 和 STS(§8) |
scripts/subtitle_localize.py | 本地化 cue 生成器:换行 + 停留重算 + 术语表断言 + SRT,强制 sub_end ⊇ 实测配音(03-subtitles-and-titles.md §11) |
references/ | 能力知识库(§3 路由)、25-error-index.md、ram-policies.md |
evals/scenarios/ | 评测场景 |
阿里云skills
◯ 评论 0