跳转至

MIBO TF 媒体制作说明

最后更新:

本说明用于制作 MIBO“TF 媒体”页面播放的图片和动画。MIBO 不直接播放普通 MP4、MOV、GIF 或带音轨视频;源素材需要先转换成规定尺寸和编码,再按媒体套装、分类和动作组命名。

这里的 TF 媒体与仪表背景、音乐背景和宠物包是三套独立资源,请不要混放。

1. 最终交付格式

类型 正式格式 存储尺寸 其他要求 单文件上限
动画 AVI 容器中的 MJPEG/MJPG 320×816 仅视频轨、无音轨、1–30 FPS 512 MiB
静态图 baseline JPEG 320×820 不要 progressive 2 MiB

MIBO 的页面逻辑尺寸是 820×320,但媒体文件按屏幕物理扫描方向保存。通常应以正常横屏 820×320 构图,再使用 MIBO 转换工具生成 320×816 或 320×820 的最终文件,不要直接把 普通横屏素材复制进 TF 卡。

2. 媒体套装目录

每个一级子目录都是一套可单独选择的媒体:

/mibo/资源/媒体/
└── 我的媒体套装/
    ├── 启动/
    ├── 日常/
    ├── 随机/
    ├── 场景/
    └── 音乐/

套装名可以使用中文。建议五个分类目录都创建,即使某一类暂时为空。

2.1 五个分类的含义

  • 启动:每次从其他页面进入 TF 媒体页时随机播放一组,结束后进入日常调度。
  • 日常:正常顺序或随机轮播。
  • 随机:在完整日常动作结束后,按 EVCC 设置的概率或时间间隔插入。
  • 场景:不自动轮播,只供用户手动选择或自动化触发。
  • 音乐:跟随 EVCC 的音乐播放状态和 BPM。

“启动、日常、随机、场景”只读取分类目录中的直接文件,不能再建立动作子目录。“音乐”可以在 根目录放兜底动画,还可以增加一层纯数字 BPM 目录或一个扁平的 auto 目录。

3. 设计源素材

3.1 画面方向

  • 设计时使用正常横屏 820×320 画布最直观。
  • 转换工具会先等比缩放和补边,再转成 MIBO 的物理存储方向。
  • 工具默认不裁切,因此比例不同的素材会出现补边,不会丢失主体。
  • 如果源素材已经是 320×816 视频或 320×820 图片的物理方向,转换时使用 --source-physical,避免再次旋转。

3.2 动画建议

  • 普通动画推荐 24 FPS;MIBO 接受 1–30 FPS。
  • 开头和结尾片段不宜过长,循环片段要检查首尾衔接。
  • 画面中不要依赖原视频音频,MIBO 只播放视频轨。
  • 避免极高噪点、细碎粒子和每帧全屏随机变化,这会显著增大 MJPEG 文件。
  • 重要主体不要紧贴边缘,转换时可能因比例补边而改变可视面积。

3.3 静态图片建议

  • 用于短暂停留或表情卡片时可以使用 JPEG。
  • 音乐分类只接受 AVI,不要把 JPEG 放入“音乐”。
  • 静态图片没有动画分段;重命名会改变它在资源目录中的身份。

4. 使用 MIBO 工具转换

需要在 MIBO 工程根目录运行,并确保电脑已安装 FFmpeg。工具接受常见视频、AVI、MJPEG 和 JPEG 源文件;PNG、WebP 或 GIF 等素材应先用图片/视频工具转换为可接受的源格式。

4.1 转换单个文件

python3 tools/prepare_tf_media.py \
  <输入文件> \
  <临时输出目录> \
  --fps 24 \
  --quality 8

--quality 数值越小质量越高、文件通常也越大。默认 8 适合先做平衡版本。

如果输入已经是物理方向:

python3 tools/prepare_tf_media.py \
  <输入文件> \
  <临时输出目录> \
  --source-physical \
  --fps 24 \
  --quality 8

4.2 批量转换

输入也可以是一个平铺目录。工具只处理该目录中的直接文件,不递归进入子目录:

python3 tools/prepare_tf_media.py \
  <源素材目录> \
  <临时输出目录> \
  --fps 24 \
  --quality 8

输出已存在时,工具默认拒绝覆盖。只有确认目标文件可以替换时才增加 --overwrite。推荐先输出 到临时目录,检查后再按下一节规则重命名和分类。

4.3 转换工具会做什么

  • 保留源画面的完整内容,等比缩放后补黑边。
  • 按 MIBO 的物理扫描方向旋转。
  • 视频输出为 MJPEG AVI,并移除音轨。
  • 静态图输出为 baseline JPEG。
  • 检查输出尺寸、视频编码和帧率。

这一步只检查单个媒体文件,不会判断它是否放在正确分类、文件名是否构成完整动作组。

5. 普通动画命名

建议使用“稳定英文 key + 中文显示名”:

wave__挥手.avi                    单文件动作,等价于 loop01

wave__挥手__start.avi             等价于 start00
wave__挥手__loop.avi              等价于 loop00
wave__挥手__end.avi               等价于 end00

wave__挥手__start01.avi
wave__挥手__loop01.avi
wave__挥手__loop02.avi
wave__挥手__end01.avi

播放顺序是 start → loop → end。一个动作组至少要有一个 loop;start 和 end 可以省略。

命名规则:

  • key 长度为 1–32 个 ASCII 字符。
  • key 必须以小写字母或数字开头,只能包含小写字母、数字、_ 和 -。
  • 同一套装的“启动、日常、随机、场景”不要重复使用同一个 key。
  • 同一 key 的所有片段必须使用相同中文显示名。
  • 显示名最多 95 个 UTF-8 字节,不能包含 |。
  • 完整 TF 路径最多 159 个 UTF-8 字节,因此套装名和显示名不要过长。
  • start/loop/end 后可使用 00–99;不写数字时等价于 00。
  • key__中文名.avi 是便捷的单文件 loop01。
  • 不写稳定 key 的中文文件名可以兼容播放,但改名会改变资源 ID,不适合长期自动化。
  • idle 不是保留词,放在哪个分类就按哪个分类调度。

6. 音乐媒体

6.1 目录方式

音乐/
├── dance__听歌舞蹈.avi
├── 120/
│   └── dance__听歌舞蹈.avi
└── auto/
    ├── dance__听歌舞蹈__transition.avi
    ├── dance__听歌舞蹈__loop_60.avi
    ├── dance__听歌舞蹈__loop_120.avi
    └── dance__听歌舞蹈__loop_180.avi
  • “音乐”根目录:歌曲没有 BPM,或没有更合适候选时使用的兜底。
  • 音乐/120/:以原速播放的普通 120 BPM 素材;数字必须是 1–999。
  • 音乐/auto/:允许 MIBO 选择合适参考 BPM 并只做减速播放的素材。

不要建立 音乐/auto/120/。auto 下面必须直接放 AVI。

6.2 auto 命名

key__中文名__transition.avi
key__中文名__loop_<BPM>.avi
  • <BPM> 必须是 1–999 的整数。
  • 同一 key 可以准备多个参考 BPM 的 loop。
  • transition 会在进入 loop 前和退出 loop 后各播放一次,不会在结束时自动倒放。
  • 如果开始和结束确实不同,也可分别使用 __start.avi 与 __end.avi。
  • transition、start、end 和所有 loop 的 key、中文名必须一致。
  • auto 内所有 AVI 必须严格为 24 FPS。
  • loop 建议包含完整的 4 拍或 8 拍,并保证首尾无缝衔接。

歌曲有 BPM 时,接近 ±5 BPM 的普通数字目录优先。没有接近档位时,MIBO 会选择不低于歌曲 BPM 的最小 auto 参考,只减速、不加速。歌曲 BPM 高于所有 auto 档时,会再尝试普通数字目录, 最后回退到音乐根目录。

7. 让 Codex 协助制作

把本目录的 mibo-assistant/ Skill 导入 Codex 后,可以这样提问:

请使用 $mibo-assistant,把 <源素材目录> 制作成一套名为“我的媒体套装”的 MIBO TF 媒体。
先读取当前 MIBO 的媒体规则和 tools/prepare_tf_media.py,不要直接覆盖正式目录。

请先列出每个源文件准备归入“启动、日常、随机、场景、音乐”的哪一类,以及稳定 key、
中文显示名、start/loop/end 分段和 BPM 方案。得到我确认后,在临时目录转换为规定的
MJPEG AVI 或 baseline JPEG,运行文件名、目录和编码校验,最后给出部署清单。

如果要制作音乐自动变速素材:

请使用 $mibo-assistant,为动作 <key/中文名> 制作 MIBO 音乐 auto 组。
参考 BPM 为 60、120、180;所有文件严格 24 FPS。先检查循环是否按完整节拍首尾衔接,
再制作一份共用 transition 和三份 loop_<BPM>,不要创建 auto/<BPM> 子目录。

Codex 应先生成计划和临时结果,再由用户确认分类与覆盖范围。只有“转换成功”不能证明动作切分、 中文名称、节拍或真机观感正确。

8. 校验目录和文件名

完成整个媒体目录后运行:

python3 tools/validate_expression_assets.py \
  <媒体根目录> \
  --compact

媒体根目录可以是一个套装,也可以是包含多个套装的 /mibo/资源/媒体。该检查会验证 AVI 的 目录深度、key、中文显示名、片段编号和动作组完整性。

然后建立可选的只读校验索引:

python3 tools/build_media_validation_index.py <媒体根目录>

它会进一步检查每个 AVI 的 RIFF/MJPEG 头、320×816 尺寸、1–30 FPS、auto 的 24 FPS 和 文件大小,并生成 .mibo-media-index-v1。这个文件由工具生成,不要手工编辑。

静态 JPEG 在转换时会检查 baseline 和 320×820;仍应另外确认每张图小于 2 MiB,并逐张查看 画面方向。

项目的格式回归测试:

python3 tools/test_media_format_policy.py

9. 部署到 TF 卡

  1. 把完成校验的整个套装放入 /mibo/资源/媒体/。
  2. 如果已有同名套装,先备份,不要直接覆盖唯一可用版本。
  3. 关机读卡复制后安全推出;或在恢复模式中上传并等待校验完成。
  4. 回到日常系统,执行“系统维护 → 重建 TF 索引”。
  5. 在 EVCC 或 MIBO 中选择新媒体套装。

如果使用工程中的 TF 同步脚本,先运行:

./tools/sync_tf_card.sh status
./tools/sync_tf_card.sh push --dry-run

真实 push 会把实体卡的 /mibo 精确镜像为工作区内容,可能删除只存在于实体卡的普通文件。 确认删除清单和备份后才能执行。

10. 实体 MIBO 验收

至少检查:

  • 套装能被发现、选择,并在重启后保持。
  • 每次进入媒体页只执行一组“启动”。
  • “日常”顺序和随机模式都能连续播放。
  • “随机”只在完整日常动作边界插入。
  • “场景”不会自行轮播,手动和自动化触发正常。
  • start、loop、end 顺序正确,循环没有明显跳帧。
  • 音乐无 BPM、普通 BPM 和 auto 三条回退路径都正常。
  • 图片与动画方向正确,没有拉伸、裁边、花屏或音轨错误。
  • 连续播放和切换页面时不会永久黑屏。

11. 常见错误

错误 结果 修正
直接复制 MP4/GIF MIBO 不识别 用 prepare_tf_media.py 转为 MJPEG AVI
横屏素材直接改后缀 尺寸和方向错误 让转换工具生成物理存储方向
AVI 带 H.264 或音轨 校验或播放失败 重新输出只有 MJPEG 视频轨的 AVI
progressive JPEG 静态图被拒绝 重新保存为 baseline JPEG
在日常目录建动作子目录 文件不被扫描 前四类只放直接文件
建立 auto/120/ 目录层级无效 loop 文件直接放在 auto/
同一 key 使用不同中文名 动作组校验失败 统一所有片段的显示名
缺少 loop 动作组不可播放 至少提供一个 loop
auto 不是 24 FPS 索引构建失败 统一重新转为 24 FPS
只看格式校验 无法证明节拍和真机观感 最后完成实体 MIBO 播放验收