- 文档
【免费下载链接】VTubeStudio
VTube Studio API Development Page
本文基于仓库中的 Permissions/README.md 展开,系统讲解 VTube Studio 公共 API 的权限(Permissions)体系:权限为何存在、当前全部可用权限及其对应请求、PermissionRequest消息的完整 REQUEST/RESPONSE 报文格式,以及错误处理与用户侧权限管理。读完本文后,你可以在插件中正确实现权限申请逻辑(含"静默查询已授权列表"这一用法),并能处理 Files/ErrorID.cs 中定义的权限相关错误码。
一、为什么 VTube Studio API 需要权限体系
VTube Studio 提供一套基于 WebSocket 的公共 API(默认监听ws://localhost:8001),插件可以在完成身份认证后触发热键、注入追踪数据、加载物品、切换模型等。但其中一部分功能被锁定在权限之后,插件必须在认证之后额外向用户申请。
Permissions/README.md 给出的设计初衷与 iOS、Android 的权限模型一致:当插件要使用"有风险或潜在危险"的功能时,例如把任意图片数据加载为物品(item),必须让用户明确知情并主动授权。申请权限时,VTube Studio 会弹出一个对话框,向用户解释该权限的用途、展示插件名称与开发者信息,由用户选择授予(Allow)或拒绝(Cancel)。上图中弹窗明确标注了 "Load custom images" 是一项 risky permission,只有理解其行为并信任插件开发者时才应授予。
从源码结构看,权限校验的结果直接体现为 API 错误码:Files/ErrorID.cs 中定义了通用错误
RequestRequiresPermission = 9, // Returned when a request requires a certain permission that has not been granted for this plugin.即插件在未获得对应权限时发送受保护请求(如携带自定义图片数据的ItemLoadRequest),会收到errorID: 9。这就是权限体系在 API 层的最终落点。
二、当前可用的权限列表
Permissions/README.md 列出了当前全部权限(文档标注 "more to come!!",即后续版本可能新增),申请时使用表中的权限名作为标识:
LoadCustomImagesAsItems
- 使用位置:
ItemLoadRequest的customDataBase64字段。 - 作用:获得该权限后,插件可以提交自定义的 PNG/JPG(GIF)数据,由 VTube Studio 将其加载为场景物品;没有该权限时,插件只能加载用户已经在 VTube Studio 中自行添加的物品文件。
- 风险说明(权限弹窗原文):允许插件在展示预览后向 VTube Studio 加载任意图片,意味着插件可以把任意图片直接显示到屏幕上。
结合 README.md 主文档中 "Custom Data Items" 一节,可以补全使用该权限时的实际约束,使申请权限后的调用真正可落地:
| 约束项 | 要求 |
|---|---|
customDataBase64 | base64 编码的 JPG/PNG/GIF 文件数据;不使用该功能时留空/NULL |
| 图片尺寸 | 64 ~ 2048 像素(含边界) |
| 数据大小 | 小于 5 MB(指编码前的二进制数据) |
| GIF 帧数 | 至少 1 帧、至多 1024 帧,且所有帧尺寸一致 |
| 不支持的类型 | 自定义数据目前不支持 Live2D 物品 |
fileName字段 | 仍需提供;字母数字(可含连字符),8~32 字符,必须以.jpg/.png/.gif结尾 |
| 加载方式 | customDataAskUserFirst=false直接加载;=true先向用户弹窗确认(最多同时 6 个弹窗,超限时请求报错) |
| 白名单机制 | 用户允许加载后,按 SHA256 哈希加入白名单,相同数据后续加载不再弹窗;customDataSkipAskingUserIfWhitelisted=false可强制每次都弹窗 |
| 超时机制 | customDataAskTimer设置弹窗倒计时秒数,设为 0 或负数则一直显示直到用户操作 |
一个不带自定义数据的ItemLoadRequest完整示例(取自 README.md 主文档):
{ "apiName": "VTubeStudioPublicAPI", "apiVersion": "1.0", "requestID": "SomeID", "messageType": "ItemLoadRequest", "data": { "fileName": "some_item_name.jpg", "positionX": 0, "positionY": 0.5, "size": 0.33, "rotation": 90, "fadeTime": 0.5, "order": 4, "failIfOrderTaken": false, "smoothing": 0, "censored": false, "flipped": false, "locked": false, "unloadWhenPluginDisconnects": true, "customDataBase64": "", "customDataAskUserFirst": true, "customDataSkipAskingUserIfWhitelisted": true, "customDataAskTimer": -1 } }如果customDataBase64填入了有效图片数据但未持有LoadCustomImagesAsItems权限,请求会返回RequestRequiresPermission(errorID 9)错误。
三、使用PermissionRequest申请权限或查询已授权列表
3.1 请求语义
PermissionRequest有两种用法,由requestedPermission字段是否留空决定:
- 申请权限:
requestedPermission填入有效权限名(当前唯一有效值为LoadCustomImagesAsItems)。VTube Studio 会向用户展示权限信息弹窗(含插件名称与开发者),用户可选择授予或拒绝。文档同时提醒:请只申请你的插件真正需要的权限。 - 静默查询:
requestedPermission留空。此时不会弹出任何窗口,响应中直接返回当前插件已授予的全部权限列表,适合插件启动时检查能力而不打扰用户。
REQUEST
{ "apiName": "VTubeStudioPublicAPI", "apiVersion": "1.0", "requestID": "SomeID", "messageType": "PermissionRequest", "data": { "requestedPermission": "LoadCustomImagesAsItems" } }3.2 已授权时的行为
如果该插件之前已获授权,响应会立即返回,不再向用户展示弹窗——这意味着用户只会在插件第一次申请某个权限时被询问一次。
3.3 权限的撤销路径
一次授予后,插件无法通过 API 撤销该权限,只有用户可以在 VTube Studio 的 API 配置(针对该插件的 Config/Permissions 页面)中随时取消。VTS 主配置面板的 "Plugins" 区域提供了 "Plugin config/permissions" 入口,进入后即可看到每个插件的权限开关(如 "Load custom images" 对应LoadCustomImagesAsItems),用户可自由切换:
3.4 会返回错误的场景
Permissions/README.md 指出,以下情况会返回错误而非授权结果:
- 申请了一个未知权限(权限名不存在);
- 用户当前正打开着 API 配置窗口(Permission config window is open);
- 插件配置文件读写出现问题(Could not open or write permission file for this plugin)。
这三种错误与通用错误码一起,完整对应 Files/ErrorID.cs 中PermissionRequest专属错误段:
// Errors related to PermissionRequest PermissionRequestUnknownPermission = 1100, PermissionRequestCannotRequestRightNow = 1101, // Permission config window is open. PermissionRequestFileProblem = 1102, // Could not open or write permission file for this plugin.因此插件端处理PermissionResponse时应同时检查errorID:收到1101时应提示用户关闭配置窗口后重试,收到1102时应检查配置目录的读写状态。
四、PermissionResponse响应结构与字段解析
RESPONSE
{ "apiName": "VTubeStudioPublicAPI", "apiVersion": "1.0", "timestamp": 1625405710728, "requestID": "SomeID", "messageType": "PermissionResponse", "data": { "grantSuccess": true, "requestedPermission": "LoadCustomImagesAsItems", "permissions": [ { "name": "LoadCustomImagesAsItems", "granted": true } ] } }关键字段说明:
| 字段 | 含义 |
|---|---|
permissions | 始终包含 VTube Studio 提供的全部权限(而非仅当前插件的),每个条目含name与granted;granted表示你的插件当前是否拥有该权限 |
grantSuccess | 当你确实发起了权限申请时,指示用户是否刚刚授予了该权限 |
requestedPermission | 发起申请时,返回被授予(或所申请)的权限名 |
由此可以得出两条实现建议:
- 不要只依赖
grantSuccess:即使grantSuccess为true,也应解析permissions数组确认granted状态,因为响应本身携带全量权限视图,一次请求即可核对所有权限; - 静默查询复用同一报文:插件连接/重连后想恢复能力状态时,发送
requestedPermission为空的请求即可无感地拿到授权列表,无需触发弹窗。
五、权限在整体 API 流程中的位置
结合 README.md 主文档的 "API Permissions" 与 "Authentication" 章节,权限机制的完整调用链是:
- 连接WebSocket 服务(默认端口 8001,用户可在 VTS 内修改);
- 认证:首次通过
AuthenticationTokenRequest请求 token(用户在弹窗中允许后获得),之后每个会话用AuthenticationRequest携带 token 完成认证; - 申请权限:认证完成后,按需发送
PermissionRequest获取如LoadCustomImagesAsItems的授权; - 使用受保护功能:例如携带
customDataBase64的ItemLoadRequest;权限缺失时以RequestRequiresPermission(errorID 9)拒绝。
这一顺序是硬性前提——所有 API 请求都要求先通过认证,权限则叠加在认证之上的第二道门。开发时建议把"认证失败"(token 被用户吊销等)与"权限不足"(errorID 9)分开处理:前者需要重新走 token 流程,后者只需引导用户在 VTS 的插件权限页面开启开关或等待下一次弹窗授权。
六、小结
- VTube Studio 的权限机制对标移动平台的系统权限:功能风险与用户知情权挂钩,弹窗由用户决定授予与否;
- 当前唯一已定义的权限是
LoadCustomImagesAsItems,服务于ItemLoadRequest的customDataBase64自定义图片物品加载场景,且文档明确提示未来会扩展权限列表; PermissionRequest既能申请权限(requestedPermission非空,可能弹窗),也能静默查询全量权限状态(留空,不弹窗);- 权限授予后插件无法经 API 撤销,但用户可随时在 VTS 的 Plugin config/permissions 中取消;
- 错误处理需覆盖
Files/ErrorID.cs中的RequestRequiresPermission(9)与PermissionRequestUnknownPermission/PermissionRequestCannotRequestRightNow/PermissionRequestFileProblem(1100~1102)四个错误码。
进一步阅读可参考仓库内的 Permissions/README.md、Files/ErrorID.cs 以及 README.md 中 Authentication 与 Custom Data Items 两个章节。
- 文档
【免费下载链接】VTubeStudio
VTube Studio API Development Page
相关推荐
chrome-extensions-samples 可选权限(Optional Permissions)实战:用 permissions API 按需申请 serial 串口权限
chrome extensions samples 可选权限(Optional Permissions)实战:用 permissions API 按需申请 se
示例工程Termux权限管理:Android权限申请和使用
Termux权限管理:Android权限申请和使用 引言:移动端终端的权限挑战 你是否曾在Android设备上使用Termux时遇到"权限被拒绝"的错误?作为一
移动开发CLI操作系统Diia应用中的动态权限申请:Accompanist Permissions库使用
Diia应用中的动态权限申请:Accompanist Permissions库使用 你是否还在为Android应用中的权限申请逻辑繁琐而烦恼?用户拒绝权限后不知
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考