Funscript 格式逐字段说明
Funscript 格式是一个 JSON 对象,其中有一个必不可少的键 actions:由 {"at", "pos"} 对组成的列表,给出以毫秒计的时间点上 0 到 100 的位置。它周围是 version、inverted、range 和 metadata。本页定义每个字段、文件遵循的约定,并准确说明 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- 由点组成的数组,每个点是一个带有
at和pos的对象。这是播放器唯一需要的字段。没有它的文件不是可用的脚本。 at- 该点的时间,从视频开始算起的毫秒数,为整数。
1500表示第一秒半。 pos- 在该时间应处的位置,为 0 到 100 的整数。0 和 100 在物理上意味着什么取决于设备及其设置;文件只表示“在范围中走了多远”。
version- 字符串形式的格式版本,通常为
"1.0"。 invertedtrue或false。为 true 时,位置应上下颠倒解读,即100 − pos。range- 一个数字,通常为
100,描述pos的跨度。大多数文件保持为 100。 metadata- 一个对象,用于记录与脚本有关的任何信息:制作它的程序、标题、备注、标签。播放器播放文件时不需要它。
编辑器生成的文件常常带有额外的顶层键,例如章节或书签。这是允许的;不理解这些键的读取程序应忽略它们,最好还能保留它们。
格式正确的文件遵循的约定
at是一个整数毫秒值,从视频开头算起,绝不为负。pos是 0 到 100 之间的整数。- 动作按
at排序,最早的在前。 - 任何两个动作的
at都不相同。 - 数字是 JSON 数字,不是字符串:写
"at": 400,而不是"at": "400"。
当文件违反这些规则时,各个程序的宽容程度不同。桌面应用会尽量修复,具体见下文。我们自己的浏览器工具 Report Studio 则不会:它假定动作已经排好序,以最后一个动作作为时长,忽略 inverted 和 range,并拒绝 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,这样其他所有播放器看到的都是相同的动作。已发布的应用会忽略这个标志,所以反向的文件会上下颠倒地播放;- 小数形式的
at和pos值会四舍五入到最接近的整数,NaN 或无穷大的值会被跳过; - 未知的顶层键(例如章节或书签)会被保留,并在保存时写回;已发布的应用在保存时会丢弃它们;
- 不是文本、不是 JSON、不是对象或没有
actions列表的文件会得到一条通俗易懂的提示,没有可用动作的脚本不会被关联到视频。
AutoScript Sync 如何写入文件
应用保存的每个脚本,无论是生成的还是编辑过的,也无论在编辑器里做了什么,都遵守上述约定:
- 动作按时间升序写入,时间各不相同,
at为非负整数毫秒,pos为 0 到 100 之间的整数。如果两个点四舍五入后落在同一毫秒,以后一个为准。 - 文件头:
version、inverted和range按现有值写入;生成的脚本为"1.0"、false和100。 - 元数据:
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键,或条目中没有数值型的at和pos。 - 时间顺序错乱
- 通常是拼接两个脚本或手工编辑造成的。假定动作已排序的程序会显示错误的时长,或播放时出现跳动。
- 时间重复
- 同一个
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 在保存时会丢弃它们,所以请保留一份原文件。
延伸阅读
- 用校验器检查文件在你的浏览器中找出本页列出的错误,并提供一份修复后的副本。
- 通俗易懂的入门介绍funscript 是什么、设备如何使用它,不涉及字段细节。
- 制作脚本:手工或自动生成从视频到一个保存好、检查过的文件的完整流程。
- 学习中心全部四个参考页面。