Funscript 格式逐字段说明

Funscript 格式是一个 JSON 对象,其中有一个必不可少的键 actions:由 {"at", "pos"} 对组成的列表,给出以毫秒计的时间点上 0 到 100 的位置。它周围是 versioninvertedrangemetadata。本页定义每个字段、文件遵循的约定,并准确说明 AutoScript Sync 读写文件时会做什么。

已于 2026 年 9 月 21 日对照应用代码核实。描述的是通用约定,而非正式规范。

结构

funscript 是一个以 UTF-8 文本保存、扩展名为 .funscript 的 JSON 对象。一个完整的小文件,采用 AutoScript Sync 保存的结构:

{
  "version": "1.0",
  "inverted": false,
  "range": 100,
  "metadata": {
    "creator": "AutoScript Sync",
    "format": "funscript"
  },
  "actions": [
    {"at": 0,    "pos": 50},
    {"at": 350,  "pos": 95},
    {"at": 720,  "pos": 5},
    {"at": 1080, "pos": 95},
    {"at": 1500, "pos": 5},
    {"at": 5500, "pos": 5}
  ]
}

最后两个点在四秒内保持相同位置:静止写成两个 pos 相同的点,而不是留空。在 JSON 中键的顺序无关紧要,空白也可以随意。

字段

actions
由点组成的数组,每个点是一个带有 atpos 的对象。这是播放器唯一需要的字段。没有它的文件不是可用的脚本。
at
该点的时间,从视频开始算起的毫秒数,为整数。1500 表示第一秒半。
pos
在该时间应处的位置,为 0 到 100 的整数。0 和 100 在物理上意味着什么取决于设备及其设置;文件只表示“在范围中走了多远”。
version
字符串形式的格式版本,通常为 "1.0"
inverted
truefalse。为 true 时,位置应上下颠倒解读,即 100 − pos
range
一个数字,通常为 100,描述 pos 的跨度。大多数文件保持为 100。
metadata
一个对象,用于记录与脚本有关的任何信息:制作它的程序、标题、备注、标签。播放器播放文件时不需要它。

编辑器生成的文件常常带有额外的顶层键,例如章节或书签。这是允许的;不理解这些键的读取程序应忽略它们,最好还能保留它们。

格式正确的文件遵循的约定

  • at 是一个整数毫秒值,从视频开头算起,绝不为负。
  • pos 是 0 到 100 之间的整数。
  • 动作按 at 排序,最早的在前。
  • 任何两个动作的 at 都不相同。
  • 数字是 JSON 数字,不是字符串:写 "at": 400,而不是 "at": "400"

当文件违反这些规则时,各个程序的宽容程度不同。桌面应用会尽量修复,具体见下文。我们自己的浏览器工具 Report Studio 则不会:它假定动作已经排好序,以最后一个动作作为时长,忽略 invertedrange,并拒绝 at 值为字符串的文件。遵守全部五条约定的文件就能避开这些差异。

AutoScript Sync 如何读取文件

当你用 Load Funscript… 打开脚本、把脚本拖到窗口上,或打开旁边有同名脚本的视频时,应用会修复其中的动作,而不是拒绝这个文件:

  • 按时间对动作排序;
  • 合并时间相同的动作,保留最后一个;
  • pos 限制在 0–100 之间,把负时间改为 0;
  • 跳过无法读取的条目,且不会告诉你跳过了多少;
  • 会读取 range,但从不据此重新缩放,因此 range 不是 100 的文件仍按 0–100 处理;
  • version 保持原样(缺失时为 "1.0")。

下一次更新(2.121.2,已构建但尚未发布)会让读取器接受更多文件,并保留文件中更多的内容:

  • 带字节顺序标记(BOM)或以 UTF-16 保存的文件可以载入,而不会被拒绝;
  • inverted: true 会在载入时应用一次(100 − pos),并给你一条提示,文件保存时写回 inverted: false,这样其他所有播放器看到的都是相同的动作。已发布的应用会忽略这个标志,所以反向的文件会上下颠倒地播放;
  • 小数形式的 atpos 值会四舍五入到最接近的整数,NaN 或无穷大的值会被跳过;
  • 未知的顶层键(例如章节或书签)会被保留,并在保存时写回;已发布的应用在保存时会丢弃它们;
  • 不是文本、不是 JSON、不是对象或没有 actions 列表的文件会得到一条通俗易懂的提示,没有可用动作的脚本不会被关联到视频。

AutoScript Sync 如何写入文件

应用保存的每个脚本,无论是生成的还是编辑过的,也无论在编辑器里做了什么,都遵守上述约定:

  • 动作按时间升序写入,时间各不相同,at 为非负整数毫秒,pos 为 0 到 100 之间的整数。如果两个点四舍五入后落在同一毫秒,以后一个为准。
  • 文件头versioninvertedrange 按现有值写入;生成的脚本为 "1.0"false100
  • 元数据creator 始终设为 "AutoScript Sync"format 设为 "funscript"。覆盖保存其他工具的脚本时,会替换其 creator。
  • 生成的脚本中的分析详情:生成器、识别摘要、耗时、追踪路径,以及一个 ai 块,其中包含每个两秒窗口的场景类型标签、追踪区域、有多少是补填而非实测的,以及锚点选举得分。
  • 安全保存:JSON 以缩进格式先写入临时文件,再替换原文件,因此保存途中崩溃也不会损坏现有脚本。
  • 备份:当 Generate 保存到视频旁边时,任何已有的脚本会先复制为 <name>.funscript.bak。只保留一个备份;下一次 Generate 会覆盖它。

磁盘上的文件从不会按设备做适配。应用把脚本发送到 Autoblow AI Ultra 时,会将一份副本按设备限制适配,并去掉分析元数据,只保留动作和少数几个文件头字段(generator、creator、format、version、range、stroke_expansion,以及存在时的 id)。

常见错误及排查方法

funscript 校验器会在你的浏览器中逐项检查这些问题,无需上传文件,并列出发现的问题。

无效的 JSON
缺少逗号或括号,或最后一个动作后面多了一个逗号。修好之前,任何程序都无法读取该文件。
动作缺失或格式错误
没有 actions 键,或条目中没有数值型的 atpos
时间顺序错乱
通常是拼接两个脚本或手工编辑造成的。假定动作已排序的程序会显示错误的时长,或播放时出现跳动。
时间重复
同一个 at 上有两个位置不同的点:播放器不可能同时处在两个位置。
位置超出 0–100
低于 0 或高于 100 的 pos 指向了播放器映射到设备的范围之外。
动作对设备来说太快
这不是格式错误,但短时间内的大幅跳动超出了设备的能力。校验器会标出超过你所设速度上限的片段,默认是每秒 400 单位。

当文件是有效的 JSON 且带有 actions 列表时,校验器会提供一份修复后的副本:按时间排序、合并重复时间、把位置限制在 0–100 并对数值取整,文件中的其他内容全部保留。它无法修复损坏的 JSON 或缺失的 actions 列表,也不会放慢过快的动作。

常见问题

有官方的 funscript 规范吗?

本页描述的是流通中的文件所遵循的约定,以及 AutoScript Sync 读取和写入的内容。它不是正式标准,我们也不描述其他播放器如何处理边界情况。

一个脚本每秒应该有多少个点?

格式本身不规定频率。点应该放在动作转向的地方。AutoScript Sync 生成的脚本会在实测动作的每次反转处放一个点,因此慢的场景点少,快的场景点多。

为什么别人做的脚本却显示 "creator": "AutoScript Sync"?

应用每次保存时都会把自己的名字写为 creator,包括覆盖保存其他工具的脚本。分享时,请把原作者的名字写回元数据,或写在你的帖子里。

AutoScript Sync 会保留章节和其他额外的键吗?

在下一次更新(2.121.2)中会:未知的顶层键会被保留并写回。已发布的 2.121.1 在保存时会丢弃它们,所以请保留一份原文件。

延伸阅读

从你的视频生成格式规范的脚本

AutoScript Sync 会在你的视频旁写出标准的 funscript;试用版就是完整的应用,可用一天。