首页 / 全部技能 / 内容创作 / countdown-video
内容创作 · iart-ai/tiktok-video-skills

countdown-video

This skill should be used when the user asks to "make a countdown timer video", "create a countdown animation", "build a stream starting soon countdown", "do an event/launch/sale countdown", "animate a mm:ss or dd:hh:mm:ss timer", "add digit roll/flip transitions to a counter", or "loop a countdown background". Covers frame-accurate (drift-free) timers, digit flip/roll motion, time formatting, and a configurable duration prop.

L4 高权限 · 分级授权与审计V1 已固定执行命令联网读写文件Dual-pass Audit
Author iart-aiGitHub iart-ai/tiktok-video-skills ↗Stars 11License MIT(仓库根 LICENSE 为 "MIT License / Copyright (c) 2026 iart.ai";GitHub API spdx_id = MIT;.claude-plugin/plugin.json 亦声明 "license": "MIT")Commit 2a775336b5
管控等级描述 skill 的能力与建议配套的管控措施,不代表质量或安全认证,也不表示可用或不可用。是否使用由用户和管理者决定。不同 agent 宿主对权限的约束各不相同,请勿假定宿主一定会提供安全兜底。第三方 skill 版权归原作者,使用风险由使用者自行承担。

1实现原理 · 为什么它能做到

全篇只有一条铁律:剩余时间必须由权威时钟推导,禁止把剩余值放进 state 递减。

skills/countdown-video/SKILL.md
Never store remaining time in state and decrement it. Recompute it every frame.
这里在做什么:把「漂移」从调参问题变成结构问题——每帧重算,慢帧自动自愈,误差不累积。这条铁律同时决定了取整方式与验收断言。

用机制层理由解释 setInterval 为什么会漂(回调至少晚 1000ms 触发,且在标签页被节流或渲染帧变慢时叠加)。

skills/countdown-video/SKILL.md
A `setInterval(fn, 1000)` countdown **drifts** — the callback fires *at least* 1000 ms later, never exactly, and stacks up when the tab is throttled or a render frame is slow.
这里在做什么:给出机理而非「经验上不好」,agent 遇到 rAF / Date.now 变体时能自行推导正确写法,而不是背规则。

Remotion 侧的可依赖时钟是 useCurrentFrame():第 N 帧恒等于 N/fps 秒,于是「帧精确」是构造性成立的。

skills/countdown-video/SKILL.md
`useCurrentFrame()` is deterministic: frame N is always rendered at exactly `N/fps` seconds.
这里在做什么:把渲染器确定性当可依赖前提;但取整边界仍要求用静帧复核(对应 verify 段与收尾清单第 2 条)。

取整用 ceil 并 clamp 到 0,使「1」能显示满整秒、末帧正好落在 00:00。

skills/countdown-video/SKILL.md
const remaining = Math.max(0, Math.ceil(durationInSeconds - elapsed));
这里在做什么:一行 ceil 同时决定观感(不做 ceil 数字会提前翻)与验收断言(末帧读数)——本 skill 最「贵」的一行。

时长是 prop 而非常量,并与 durationInFrames 绑定,避免倒计时走到 00:00 后仍有余帧。

skills/countdown-video/SKILL.md
Set the composition's `durationInFrames` to `durationInSeconds * fps` so the video is exactly as long as the countdown.
这里在做什么:同一组件覆盖 5 分钟直播倒计时与 30 秒促销倒计时,只换一个输入;reference 的注册示例就是 `durationInFrames={DURATION_SECONDS * FPS}`。

Web(非渲染)路径改用 rAF 驱动 performance.now(),且只在显示秒变化时重绘。

skills/countdown-video/SKILL.md
if (remaining !== lastShown) { render(remaining); lastShown = remaining; }
这里在做什么:1Hz 的数字不该按 60Hz 重绘;把「帧驱动」的正确性从渲染环境搬到浏览器环境。

字体层用 tabular-nums 固定字宽,数字跳动不引起版式位移。

skills/countdown-video/SKILL.md
Always set `font-variant-numeric: tabular-nums` (or a monospace digit font) so digits keep equal width and the layout does not jitter as numbers change.
这里在做什么:倒计时最常见的廉价感来源(数字宽度变化导致整块抖动)被一条 CSS 规则封死。

数字动画的原则是「动位置、不动文本内容」,且必须帧驱动而非 CSS transition。

skills/countdown-video/SKILL.md
Animate the *position*, not the text content, so the change is a glide, not a pop.
这里在做什么:把 odometer 手感抽象成位移函数,于是天然可确定性重放;reference/digit-flip.md 给出卷帘与翻牌两套完整组件。

直播/常驻画面要求背景无缝循环:运动周期必须整除时间线,按 frame % loopFrames 读取。

skills/countdown-video/SKILL.md
read it as `frame % loopFrames` so there is no visible seam at the wrap
这里在做什么:把「无缝」变成算术条件(周期整除)而不是靠肉眼找缝;reference §4 给正弦漂移的实现与 loopFrames = fps*6 的取值示范。

验收被写成数字等式:第 N 帧显示值必须等于 ceil(duration − N/fps),末帧 00:00。

skills/countdown-video/SKILL.md
at frame N, displayed = ceil(durationInSeconds - N/fps) (e.g. 300s @ 30fps, frame 4500 → 150s → "02:30")
这里在做什么:把「有没有漂移/差一秒」变成可复算断言——三张静帧即可判死,不必编码后再看。

reference 把纪律落成可运行组件,并给出到固定日期的 web 变体(每帧 target − Date.now() 重算 + 时区处理)。

skills/countdown-video/references/countdown-cookbook.md
Register it so `durationInFrames` matches the countdown exactly — the video ends when the timer does:
这里在做什么:文档与代码自洽;第二个应用面(日历倒计时)证明这条铁律不只为渲染服务。

2核心能力

01帧精确 Remotion 倒计时组件(mm:ss 与 dd:hh:mm:ss 双格式、去前导零、末态可 hold)
02直播页/网页计时器(rAF + performance.now(),仅在秒变化时重绘)
03到固定日期/时刻的倒计时(target − Date.now(),reference 含时区处理)
04时间格式化与「何时丢掉前导 0 单位」的规则(mm:ss / hh:mm:ss / dd:hh:mm:ss)
05两种确定性数字动画:odometer 卷帘与 split-flap 翻牌
06「starting soon」直播画面布局(品牌块 + 社交账号 + 渐变背景)与末态 hold(如 WE'RE LIVE)
07交付-验证回路:带真实 durationInSeconds 出静帧 → 复算数字 → 编码 → probe-mp4 断言竖屏规格

3外部依赖

KindDependency / Endpoint
clinpx remotion still / render / compositions
cliscripts/contact-sheet.sh + scripts/probe-mp4.sh(仓库根共享验证工具箱,SKILL.md 明列)
packageffmpeg / ffprobe(系统依赖)
clinpx -y playwright screenshot(scripts/seek-shot.sh,仓库级 Light tier 通用件)

4管控建议与判定依据

建议配套管控措施
面向 Agent
分级或逐次授权,建议在沙箱运行
面向管理者
审批流程、可回滚、全程审计
判定依据(文件路径与关键语句摘要)
  • scripts/: 执行本地脚本或命令: (SKILL.md 明列的验证回路)`npx remotion still Countdown out/f-*.png --frame=N --pro
  • 网络端点: 声明外部网络访问: (可选,通常不走)`scripts/seek-shot.sh` 走 `npx -y playwright screenshot`:首次从 npm 取
  • 本地工作目录: 文件读写与工件输出: agent 按本 skill 构建的 Remotion 工程与 out/countdown.mp4、out/demo.gif
审计说明: 。三段自证:① 判级对象=skills/countdown-video/(find 确认目录内只有 SKILL.md、README.md、references/{countdown-cookbook.md,digit-flip.md} 四个 .md,零可执行文件、零资产);② 目录内自身行为=本地写入(Remotion 工程、out/*.mp4、静帧)+本地 CLI(`npx remotion`;ffmpeg/ffprobe 经仓库根 scripts/),skills/ 全域 `process.env` / `api[_-]?key` / `token` / `cookie` / `https?://` 运行时端点均 0 命中;③ 唯一网络面是 npm 官方渠道取包(remotion / @remotion/*,以及 seek-shot.sh 若被使用时的 playwright 与 Chromium),与站内蓝档先例(hyperframes、general-video:npx 经 npm 官方渠道拉包不单独抬档;motion-background:同一套 scripts/ 判蓝)同口径。不升黄:无「固定公开端点查询」、无抓取、无官方 CLI 的 update/check。不升橙:零凭据/环境变量读取,零素材外发(本 skill 不涉及任何音频/图像上行),也不依赖第三方镜像或插件服务。非红档:无 TLS 降级、无沙箱关闭、无反自动化绕过、无任意代码执行面。附注:本 skill 的「实时时钟」用法不涉及网络;唯一隐私面是用户把倒计时指向自己的真实活动时间——属内容层而非代码层行为。

5第二遍独立确认

  • [ok] 「禁止 setInterval 递减」是否在 reference 的示例实现里也真的遵守(防第一遍只信 SKILL.md 的说法) — reference 全量 grep:countdown-cookbook.md 组件 `const frame = useCurrentFrame();`,注册处 `durationInFrames={DURATION_SECONDS * FPS}`;到日期的 web 组件 `Math.max(0, target - Date.now())` 每帧重算并自述 "never a decrement";digit-flip.md 两个组件同样 `const frame = useCurrentFrame();`。setInterval 全 skill 仅作反例出现 1 次。
  • [ok] 「倒计时结束时视频正好结束」是否真被约束住 — SKILL.md 明写 `durationInFrames` = `durationInSeconds * fps`;cookbook 给出 "Register it so `durationInFrames` matches the countdown exactly — the video ends when the timer does:" 的注册片段;收尾清单第 2 条把它列为验收项。文档、示例、验收三者一致,不是单向声明。
  • [unlocatable] 「每分钟约丢 1 秒」的漂移量级是否有据 — SKILL.md 写 "Reports of ~1 second lost per minute are common.",但仓库内无基准脚本、无引用、无数据文件;本次为只读侦查且不运行计时实验,故不验证该数值,仅记为文档声明,不在结论中当已核事实使用。
  • [ok] seek-shot.sh(Light tier)对本 skill 是否可用(防「Packaged helper」被读者误解为三条脚本都属本 skill) — scripts/README.md 把 seek-shot 归为「standalone HTML + `?t=N` harness」的 Light tier;本 skill 交付是 Remotion 组件(Heavy tier),SKILL.md 的 Packaged helper 行只点名 contact-sheet 与 probe-mp4。不存在悬空引用,也不存在被夸大的能力。
  • [ok] 三仓库共享脚本是否同内容(跨包一致性) — md5 逐字节比对:contact-sheet.sh b7dcc28034c9bf8fda5d48683e54d8b5、probe-mp4.sh 167b7977c50f492014e1a6fef8c9ed12、seek-shot.sh 24a4130cd1e64874154429b0b4af12da,iart-tiktok / iart-text-message / iart-youtube 三包完全相同。
  • [ok] SKILL.md 是否声称了 reference 未兑现的能力(防文档夸大) — SKILL.md 承诺的四件事——可配置 duration、mm:ss 与 dd:hh:mm:ss、drift-free 计时、无缝循环背景——在 countdown-cookbook.md 与 digit-flip.md 里各有对应实现(§1 组件、§2 到日期、§4 循环、digit-flip 两组件),逐项可定位,无空头承诺。

6结论

  • 一条原则贯穿两个运行环境(渲染 useCurrentFrame、网页 performance.now()/Date.now()),倒计时正确性由构造保证而非测试保证
  • 观感细节被一并钉死:ceil 让「1」显示满一秒、tabular-nums 防抖动、末态可 hold
  • 验收是等式而非印象:第 N 帧读数 = ceil(duration − N/fps),末帧 00:00,任何第三方都能复算
  • 数字动画给两套现成实现且全部帧驱动,绕开「CSS transition 在 headless 渲染中失效/不可确定性重放」这个常见坑
  • 场景覆盖完整:直播 starting soon、促销 mm:ss、发布 dd:hh:mm:ss、循环背景各有配方,直接可落地
  • 适合: 适合:直播「starting soon / be right back」画面、促销与发布倒计时、任何必须「在某一帧归零」的计时动画;也适合需要同一条计时逻辑同时服务渲染 MP4 与网页实时展示的项目,以及追求确定性重放(同 props 同输出)的批量生产。能接受「先出三张静帧人工核对数字、再付编码成本」的流程。
    不适合: 不适合:① 只需近似倒计时、不在乎末帧是否精确的随手剪辑;② 需要复杂时间语义(跨时区日历、法定节假日、依赖服务器真实时间的公开倒计时)——本 skill 只给格式化与取整,业务日历要另做;③ 期望「一小时倒计时秒渲染」的场景(帧数即成本);④ 需要旁白/字幕与计时同步的项目(本 skill 无音频能力,应配 caption-animation 或 audiogram);⑤ 只拷贝单个 skill 目录而不含仓库根 scripts/ 的安装方式(contact-sheet/probe-mp4 引用会悬空)。
    Install Agent-Ready
    ① Verified Mirror 2026-09-28
    Option A · Direct DownloadDownload countdown-video.tar.gz
    sha256: 2730e6053383cccb…
    Option B · Copy Guide for Agent
    install.json
    agent 读 JSON 指南后会自动从本站下载安装,无需更多说明。
    ② Upstream GitHub
    GitHub Repo ↗
    Pinned to commit 2a775336b5.