
条件视频
当检测到特定的游戏内事件时,播放自定义视频。它专为策划的游戏体验而设计,如服务器、故事地图、任务包和角色扮演设置,在这些场景中,电影化的反馈可以提升沉浸感。
🎬 ConditionalVideos
为 Minecraft 设计的、由服务器感知的过场视频触发模组。只需配置一次条件,客户端即可在关键时机播放同步视频——无论是本地文件、URL 还是完整播放列表。
✨ 概述
ConditionalVideos 会在检测到特定游戏内事件时播放自定义视频——包括首次加入、死亡、击杀、进度完成、物品里程碑、计分板阈值等等。
它可在客户端和专用服务器上运行:服务器负责检测条件并告知对应客户端播放内容,而客户端则负责实际播放。这使得它非常适合服务器、剧情地图、任务整合包以及角色扮演场景,在这些场景中,过场反馈能显著提升沉浸感。
核心亮点
- 超过十种触发类型,从
firstJoin到计分板阈值以及模组自定义条件。 - 每种条件均可设置播放列表,支持淡入淡出/硬切转场、循环播放、文字叠加、每条片段独立音量以及定时切换。
- 通过 WATERMeDIA 实现广泛的视频源支持——本地文件、直接 URL、高质量 YouTube 视频、Twitch/Kick 片段、TikTok、SoundCloud 等等。
- 内置播放队列,确保重叠的触发事件按顺序播放,而不是互相打断。
- 为其他模组提供小型公共 API(详见项目 Wiki)。
🧩 兼容性与需求
| Minecraft 版本 | 模组加载器 | Java 版本 |
|---|---|---|
| 1.20.1 | Fabric, Forge | 17+ |
| 1.21.1 | Fabric, NeoForge | 21+ |
| 1.21.11 | Fabric, NeoForge | 21+ |
| 26.1.2 | Fabric, NeoForge | 25+ |
| 26.2 | Fabric, NeoForge | 25+ |
在 26.2 版本中,游戏可使用任一渲染器运行。视频在两种渲染器下均可播放,但对 Vulkan 渲染器的支持尚处于实验阶段——Minecraft 将其作为可选的预览功能提供,因此如果遇到问题,OpenGL 仍然是最安全的选择。
必需依赖(客户端):
- WATERMeDIA: Multimedia API — v3.0.0.23+
- WATERMeDIA: Native Binaries — v3.0.0.6+
- Fabric API — 任意版本(仅限 Fabric)
配置文件:
config/conditionalvideos.json— 客户端 / 单人游戏规则config/conditionalvideos-server.json— 专用服务器的权威规则config/conditionalvideos-common.json— 客户端播放行为(服务器也会读取其中同步的选项)
在多人游戏中,由专用服务器掌控配置,并自动将任何本地视频文件发送给客户端(在重连时会缓存并复用),而 URL 则由每个客户端直接流式播放。请将 conditionalvideos-server.json 视为服务器内容的唯一权威来源。
🎯 支持的条件
每个条件都通过一个播放列表进行配置。简单条件使用单个配置键;带键条件则是 id → condition 的映射。
简单条件(单键):
firstJoin— 当玩家进入世界/会话时播放。始终优先:如果世界加载期间其他条件也被触发,firstJoin会先播放,其余条件则在队列中等待。playerDeath— 任何死亡事件的默认过场视频。totemUsed— 不死图腾救下玩家时触发。bedSleep— 玩家开始在床上睡觉时触发。
带键条件(id → condition 映射):
deathByEntity— 被特定击杀者实体 ID 杀死时触发(会覆盖playerDeath)。entityKilled— 玩家击败了配置的实体 ID 时触发。advancementCompleted— 完成了配置的进度时触发。dimensionChanged— 玩家进入配置的维度时触发。itemObtained— 玩家获得配置的物品时触发(拾取、合成或熔炼产物)。itemCrafted— 实际合成了配置的物品时触发(独立于itemObtained)。recipeUnlocked— 配方书中新解锁了配置的配方时触发。scoreboard— 玩家在某个计分板目标上的分数满足比较条件时触发(见下文)。custom— 无内置检测器;仅由公共 API 或play命令触发。
计分板比较器
每个 scoreboard 条目都会使用 comparator 将玩家的分数与 value 进行比较:
comparator 值 |
触发条件 |
|---|---|
equal |
score == value |
less |
score < value |
greater |
score > value |
lessOrEqual |
score <= value |
greaterOrEqual |
score >= value(默认值) |
它是边沿触发的:一个满足条件的比较只会触发一次,并且只有在条件变为假并再次变回真后才会重新武装。由于分数会随世界持久化保存,因此如果在退出登录前比较条件已经满足,重新加入时不会再次触发。
🗂️ 配置 conditionalvideos.json
每个条件条目在 videos: [...] 下包含一个播放列表,外加一些共享标志。每个 videos 数组中的项目都是一个 VideoEntry,用于描述单个视频片段及其叠加、跳过、循环和转场选项。只有 firstJoin 预配置了内容;其他所有条件在您添加视频之前都是空的 {}。
共享条件字段
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
repeatableInSameSession |
boolean |
是 | 若为 false,该条件每次会话只能触发一次。若为 true,则可重复触发。 |
playlistLoop |
boolean |
否 | 若为 true,播放列表在最后一个条目播放完毕后会从第一个条目重新开始。默认 false。 |
videos |
VideoEntry[] |
是 | 一个或多个按顺序播放的条目。长度为 1 时等同于单视频设置。 |
scoreboard 条目会在条件层级添加两个字段:value(int,必填——阈值)和 comparator(string,可选——默认为 greaterOrEqual)。
VideoEntry 字段
| 属性 | 类型 | 必填 | 描述 |
|---|---|---|---|
source |
string |
是 | 本地视频文件的路径(相对于游戏目录或绝对路径)或 URL(http://、https://、YouTube 链接)。 |
skippable |
boolean |
否 | 若为 true,用户可以跳过播放。默认 true。当 videoLoop = true 时强制为 true。 |
videoLoop |
boolean |
否 | 若为 true,该条目将无缝循环播放直至被跳过。默认 false。要求 skippable = true。 |
enableBackground |
boolean |
否 | 在视频后方绘制纯色全屏背景。默认 true。 |
colorBackground |
string |
否 | 十六进制颜色,格式为 #RRGGBB 或 #AARRGGBB。默认 #000000。 |
videoTitle |
string |
否 | 可选的标题叠加。支持旧版格式代码(&6、&l、&r 等)。 |
videoTitlePosition |
string |
否 | topLeft、topRight、bottomLeft、bottomRight。默认 bottomLeft。 |
videoDescription |
string |
否 | 可选的描述叠加。支持旧版格式代码。 |
videoDescriptionPosition |
string |
否 | topLeft、topRight、bottomLeft、bottomRight。默认 bottomLeft。 |
titleTextScale |
float |
否 | 应用于标题字体的缩放倍数。默认 1.0。 |
descriptionTextScale |
float |
否 | 应用于描述字体的缩放倍数。默认 1.0。 |
textBoxOpacity |
float |
否 | 标题/描述后方文本框的不透明度,取值 0.0–1.0。省略则使用旧版的自动透明度。 |
videoVolume |
float |
否 | 此条目的音量,取值 0.0–1.0。默认 1.0。 |
transition |
string |
否 | 从上一个条目进入此条目时应用的转场效果。可为 cut(默认)或 fadeOut/In。对第一个条目无效。 |
nextAt |
float |
否 | (自从此条目开始播放算起的)秒数,到达该时间后切换到/转场至下一个条目。省略则等待视频自然结束。 |
transition是传入条目的属性:如果videos[1].transition = "fadeOut/In",则播放器会将videos[0]淡出,同时将videos[1]淡入。cut则是指瞬间、帧完美的切换。
示例
{
"configVersion": 3,
"firstJoin": {
"repeatableInSameSession": false,
"playlistLoop": false,
"videos": [
{
"source": "videos/intro_part1.mp4",
"skippable": true,
"enableBackground": true,
"colorBackground": "#FF000000",
"videoTitle": "&6&l欢迎",
"videoTitlePosition": "topLeft",
"videoDescription": "&f祝您旅途愉快",
"videoDescriptionPosition": "topLeft",
"titleTextScale": 1.4,
"textBoxOpacity": 0.5,
"videoVolume": 0.8,
"nextAt": 8.0
},
{
"source": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"skippable": true,
"videoVolume": 1.0,
"transition": "fadeOut/In"
}
]
},
"playerDeath": {
"repeatableInSameSession": true,
"videos": [
{ "source": "videos/death/default_death.mp4", "videoTitle": "&c你死了" }
]
},
"totemUsed": {
"repeatableInSameSession": true,
"videos": [
{ "source": "videos/totem.mp4", "videoTitle": "&e被图腾救了一命" }
]
},
"bedSleep": {},
"entityKilled": {
"minecraft:warden": {
"repeatableInSameSession": false,
"videos": [
{ "source": "videos/kills/warden.mp4", "skippable": false, "videoTitle": "&5&l史诗胜利" }
]
}
},
"deathByEntity": {
"minecraft:creeper": {
"repeatableInSameSession": false,
"videos": [
{ "source": "videos/death/creeper_death.mp4", "videoTitle": "&a轰隆…" }
]
}
},
"advancementCompleted": {
"minecraft:story/mine_diamond": {
"repeatableInSameSession": false,
"videos": [
{ "source": "videos/advancements/diamond.mp4", "videoTitle": "&b钻石!" }
]
}
},
"dimensionChanged": {
"minecraft:the_nether": {
"repeatableInSameSession": true,
"playlistLoop": true,
"videos": [
{ "source": "videos/dimensions/nether_loop.mp4", "videoLoop": true, "videoTitle": "&c进入了下界" }
]
}
},
"itemObtained": {
"minecraft:diamond": {
"repeatableInSameSession": false,
"videos": [
{ "source": "videos/items/first_diamond.mp4", "videoTitle": "&b第一颗钻石" }
]
}
},
"itemCrafted": {
"minecraft:crafting_table": {
"repeatableInSameSession": false,
"videos": [
{ "source": "videos/items/first_table.mp4", "videoTitle": "&6工作台" }
]
}
},
"recipeUnlocked": {
"minecraft:furnace": {
"repeatableInSameSession": false,
"videos": [
{ "source": "videos/recipes/furnace.mp4", "videoTitle": "&7熔炉已解锁" }
]
}
},
"scoreboard": {
"kills": {
"repeatableInSameSession": false,
"value": 100,
"comparator": "greaterOrEqual",
"videos": [
{ "source": "videos/scoreboard/100_kills.mp4", "videoTitle": "&c击杀数达到100!" }
]
}
},
"custom": {},
"consumedConditionSessions": []
}配置安全性:单个格式错误的条目绝不会导致文件被清空。条目的解析是宽松的——错误的条目会被跳过并记录日志,而所有有效的条目都会保留。如果出现 JSON 语法错误,文件将保持原样,并且仅当次会话在内存中使用默认值,因此您可以修复拼写错误而不会丢失配置。
⚙️ 通用配置(conditionalvideos-common.json)
控制客户端播放行为。会自动创建并使用安全默认值。
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
videoQuality |
string |
AUTO |
AUTO 会自动选择最佳可用流。任何其他值(LOWEST、LOW、MEDIUM、HIGH、HIGHEST)都会强制使用该质量。仅对多码率源(如 YouTube 等)有效。 |
alwaysShowCursor |
boolean |
false |
若为 true,播放界面永远不会自动隐藏鼠标光标。 |
allowGameSounds |
boolean |
false |
若为 true,视频播放期间原版 Minecraft 音效会继续播放(默认静音)。 |
blockMatureContent |
boolean |
true |
若为 true,包含成人内容的源会被阻止。仅客户端——服务器无法覆盖此设置。 |
debugLogging |
boolean |
false |
若为 true,会输出详细的 [CV/...] 诊断信息。正常游玩时保持关闭;仅在排查问题时开启。 |
在多人游戏中,
videoQuality、alwaysShowCursor和allowGameSounds在服务器可用时优先使用服务器通用配置中的值;blockMatureContent和debugLogging始终读取本地客户端文件中的设置。
⌨️ 游戏内控制
默认情况下,跳过键未绑定,这会回退到 ESC 键。您可以在 选项 → 控制 → Conditional Videos 下绑定一个专用按键;绑定后,该按键将成为唯一生效的跳过键,屏幕上的提示也会始终显示其名称。
- 轻按跳过键 → 跳到播放列表的下一个条目(如果是最后一个条目,则关闭播放)。循环中的条目也会被打断。
- 按住跳过键 → 会出现一个白色进度条填充;在进度条填满后松开即可跳过整个播放列表(关闭播放)。进度条填满时会出现“松开以跳过播放列表”的消息。在进度条填满之前松开则会取消操作,不会跳过任何内容。
skippable = false会为该条目禁用以上两种操作,并隐藏跳过提示——玩家必须等待视频结束或播放列表推进。
其他行为:鼠标光标会在闲置几秒后自动隐藏(除非 alwaysShowCursor 为 true),视频播放期间原版音效会被静音(除非 allowGameSounds 为 true),并且播放过程中会隐藏游戏内的浮动通知。
🧑⚖️ 服务器命令
以下命令对权限等级 2 及以上的玩家(命令方块、管理员)和服务器控制台可用:
/conditionalvideos play <目标> <条件>
/conditionalvideos stop <目标>
/conditionalvideos pause <目标>play强制在每个目标上播放某个条件,忽略每会话一次的限制。<条件>会自动补全为至少包含一个视频的键。stop关闭当前正在进行的播放并清除待处理队列。pause切换当前视频的暂停/继续状态。
条件键对于简单条件使用裸键(firstJoin、playerDeath、totemUsed、bedSleep),对于带键条件则使用 类型/键 的形式,例如 entityKilled/minecraft:warden、advancement/minecraft:story/mine_diamond、dimension/minecraft:the_nether、scoreboard/kills、custom/my_event。
命令/API 键中的进度和维度使用
advancement/...和dimension/...前缀,而配置文件 JSON 则将其存储在advancementCompleted和dimensionChanged映射下。
🌍 本地化
界面和命令文本目前提供 en_us、es_es、es_ar 和 es_mx 四种语言。如需添加更多语言,请将 <locale>.json 文件放入资源包中的 assets/conditionalvideos/lang/ 目录下。
🧰 开发者 API
其他模组可以通过 org.mateof24.conditionalvideos.api 包中一个小型、稳定的公共 API 来注册自定义条件以及触发/控制播放。
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。