自定义 Assets 指南:唤醒词、字体、表情与聊天背景

自定义 Assets 指南:唤醒词、字体、表情与聊天背景

小智固件把唤醒词模型、文本字体、表情图片和聊天背景集中打包成一个 assets.bin,写入 Flash 的 assets 分区。换掉这个文件,就能在不改应用代码的情况下定制设备的外观和唤醒词。本文说明 assets.bin 包含什么、如何制作,以及如何写入设备。

本文对应上游 v2.5.2 与 xiaozhi-assets-generator。只有分区表含 assets 分区(分区表 v2)的开发板才支持;没有该分区时,启动日志会提示 No assets partition found。

一、可以定制什么

内容作用对应字段
唤醒词预设 WakeNet 模型,或 ESP32-S3 上的 MultiNet 自定义命令词srmodels、multinet
文本字体屏幕上聊天文字使用的 .bin 字体text_font
表情集合21 种情绪对应的 PNG 或 GIF 图片emoji_collection
聊天背景浅色、深色两套文字颜色、背景颜色或背景图skin

字段都写在 assets.bin 内的 index.json 中,详见下文「五、index.json 结构」。

二、assets 分区

分区表 v2 为不同容量的 Flash 预留 assets 分区(类型 data,子类型 spiffs),上游 partitions/v2/README.md 给出的大小如下:

分区表assets 大小
8m.csv2 MB
16m.csv8 MB
16m_c3.csv4 MB(受可用 mmap 页限制)
32m.csv16 MB

assets.bin 不能超过分区大小。设备启动时会校验 assets.bin 头部与校验和,校验失败时该分区不会被启用。

三、制作 assets.bin

方式一:Assets 生成器(推荐)

xiaozhi-assets-generator 是一个单页应用。它在浏览器本地生成 assets.bin,不依赖后端接口。操作分三步:

  1. 选择芯片(esp32s3、esp32c3、esp32p4、esp32c6)、屏幕类型和分辨率;颜色目前只支持 16 位 RGB565。
  2. 在四个标签页中完成主题设计:唤醒词、字体、表情、聊天背景。
  3. 确认待打包清单后点击生成。自定义字体耗时较长,转换结果会缓存,重新生成更快。

各标签页的规则如下。

唤醒词

  • 预设唤醒词(WakeNet):ESP32-C3 / C6 只支持 WakeNet9s 模型,ESP32-S3 / P4 只支持 WakeNet9 模型。

    唤醒词C3 / C6(WakeNet9s)S3 / P4(WakeNet9)
    Hi,乐鑫wn9s_hilexinwn9_hilexin
    Hi,ESPwn9s_hiespwn9_hiesp
    你好小智wn9s_nihaoxiaozhiwn9_nihaoxiaozhi_tts
    Hi,Jasonwn9s_hijason_tts2wn9_hijason_tts2
    小爱同学-wn9_xiaoaitongxue
    嗨小欧-wn9_hai1xiao3ou1_tts3
    你好小瑞-wn9_ni3hao3xiao3rui4_tts3
  • 自定义唤醒词(MultiNet):生成器目前只面向 ESP32-S3。中文使用 mn6_cn 或 mn7_cn,输入拼音,例如 ni hao xiao zhi;英文使用 mn6_en 或 mn7_en。可设置阈值(0-100)和超时时间。

字体

  • 预设字体为阿里巴巴普惠体,覆盖约 7000 个常用字:font_puhui_14_1、font_puhui_16_4、font_puhui_20_4、font_puhui_30_4(命名规则为 字体名_字号_bpp)。
  • 自定义字体支持 TTF、WOFF,字号范围 8-80,bpp 可选 1、2、4;字符集可选 GB2312(7445 个字符)或 DeepSeek R1(7405 个字符,默认)。转换使用 lv_font_conv,输出命名为 font_[字体名]_[字号]_[BPP].bin。

表情集合

一套表情共 21 张图,其中 neutral 是默认表情,其余为:happy、laughing、funny、sad、angry、crying、loving、embarrassed、surprised、shocked、thinking、winking、cool、relaxed、delicious、kissy、confident、sleepy、silly、confused。

  • 预设:Twemoji 32x32 或 64x64 PNG。
  • 自定义:统一图片宽高(不超过屏幕分辨率),选择 GIF 动图或透明背景 PNG;必须提供 neutral,其他可选,缺省时用 neutral 代替。

聊天背景

浅色与深色模式各自配置。默认背景色为 #ffffff(浅色)和 #121212(深色),也可以改颜色或使用静态图片。图片会自动适配屏幕分辨率,格式通常为 RGB565 位图,带 64 字节头部,内容为 lv_image_dsc_t。

方式二:命令行 scripts/spiffs_assets

固件仓库自带 scripts/spiffs_assets/build.py,可以把唤醒词模型、字体和表情目录打包成 assets.bin(需要 Python 3.6+):

cd scripts/spiffs_assets

./build.py \
    --wakenet_model ../../managed_components/espressif__esp-sr/model/wakenet_model/wn9_nihaoxiaozhi_tts \
    --text_font ../../components/noto-fonts/cbin/font_noto_sans_common_20_4.bin \
    --emoji_collection ../../components/noto-fonts/png/noto-color-emoji_64/

三个参数都可以省略,只处理需要的部分。表情目录支持 .png 和 .gif。脚本会重建 build/ 目录,并生成:

  • build/assets/:全部资源文件和 index.json
  • build/assets.bin:最终的 SPIFFS 资源文件
  • build/config.json、build/output/:构建配置与中间文件

四、写入设备

三种方式任选其一:

1. 编译时写入

在 idf.py menuconfig 的「Xiaozhi Assistant」中,把 Flash Assets 选为 Flash Custom Assets,并设置 Custom Assets File。该值可以是本地文件,也可以是 http:// 或 https:// 地址。后续 idf.py flash 会把它写入 assets 分区。

选项说明:

  • Flash Default Assets(默认):按当前 sdkconfig 自动打包默认资源。
  • Flash Emote Assets:仅在启用 Emote 消息样式时可选,生成并写入表情资源。
  • Flash Custom Assets:使用你提供的 assets.bin。
  • Do not flash assets:不写入 assets 分区。
CUSTOM_ASSETS_FILE 为相对路径时,main/CMakeLists.txt 按 main/ 目录解析,与 Kconfig 帮助文字中的「项目目录」不一致。建议使用绝对路径,避免找不到文件而编译失败。

2. 直接烧录分区

先在你使用的分区表里找到 assets 行的偏移,例如 partitions/v2/16m.csv 中为 0x800000、大小 8 MB,然后:

# Replace the offset with the assets row of your partition table
esptool.py -b 460800 write_flash -z 0x800000 assets.bin

3. 通过 MCP 让设备自行下载

先把 assets.bin 放到设备可以访问的 HTTP(S) 地址,再调用仅用户可见的 MCP 工具 self.assets.set_download_url,参数为 url。设备会把地址保存下来,下次启动联网后(先于固件版本检查)取出地址并清除,显示下载进度、擦写 assets 分区并应用新资源。地址只使用一次,下载失败需要重新设置;文件必须不大于分区,否则下载会失败。工具用法见 MCP 物联网控制用法。

五、index.json 结构

assets.bin 内的 index.json 描述各项资源。下面是生成器文档中的示例(省略了部分表情):

{
    "version": 1,
    "chip_model": "esp32s3",
    "display_config": {
        "width": 320,
        "height": 240,
        "monochrome": false,
        "color": "RGB565"
    },
    "srmodels": "srmodels.bin",
    "text_font": "font_puhui_common_30_4.bin",
    "skin": {
        "light": {
            "text_color": "#000000",
            "background_color": "#FFFFFF",
            "background_image": "background_light.raw"
        },
        "dark": {
            "text_color": "#FFFFFF",
            "background_color": "#121212",
            "background_image": "background_dark.raw"
        }
    },
    "emoji_collection": [
        { "name": "sleepy", "file": "sleepy.png" }
    ],
    "multinet": {
        "model": "mn6_cn",
        "command": "ni hao xiao zhi",
        "threshold": 20,
        "duration": 3000
    }
}

固件只接受 version 不大于 1 的索引;版本更高时会提示升级固件。

六、只改唤醒词:编译选项

只想换唤醒词时,也可以不制作 assets.bin,直接在 menuconfig 的「Xiaozhi Assistant」中设置 Wake Word Implementation Type:

选项说明
Wakenet model with AFE默认(ESP32-S3 / P4 / S31 且有 PSRAM),有条件时支持回声消除(AEC)
Wakenet model without AFE面向 ESP32-C3 / C5 / C6,以及带 PSRAM 的 ESP32
Multinet model (Custom Wake Word)自定义唤醒词,要求 ESP32-S3 / P4 / S31 且有 PSRAM
Disabled关闭唤醒词

选择自定义唤醒词后,还可以设置:

  • CUSTOM_WAKE_WORD:中文使用拼音,词间用空格分隔,默认 xiao tu dou
  • CUSTOM_WAKE_WORD_DISPLAY:识别后发给服务器的问候语,默认 小土豆
  • CUSTOM_WAKE_WORD_THRESHOLD:1-99,数值越小越灵敏,默认 20

七、常见问题

现象或日志可能原因处理
No assets partition found / Assets partition is disabled分区表没有 assets 分区改用 v2 分区表,或选择支持的开发板
校验和不匹配(checksum ... does not match)assets.bin 损坏或写入偏移不对重新生成,并核对分区表中的偏移
The assets version N is not supported, please upgrade the firmware索引版本高于固件支持的版本升级固件,或用匹配版本的生成器重新制作
Assets file size ... is larger than partition size文件超过 assets 分区大小减少表情数量、降低字号或 bpp,或换用更大的分区表
字体不生效(Ignoring invalid text font asset)字体文件无效或与显示不兼容重新转换字体,检查字号与 bpp

相关文档

来源