你的私人 AI 伴侣 · 基于 xiaozhi WebSocket 协议 · Echo Show 全屏显示
最后更新:2026-05-28 · 版本 v1.0(DeepSeek V4 Flash + 硅基流动 CosyVoice2 + 多 ASR 可选)
把一台越狱的 Echo Show 5 变成会说话、有表情的 AI 伴侣:
素材来源:Piggy Emoji Expressions Animation Pack(IconScout,20 个表情)
.json 文件(Lottie 格式),每个文件是一个表情动画将 20 个表情映射到 Piggy 的 8 个状态:
| Piggy 状态 | 触发条件 | 对应表情(优先级从高到低) | 文件名建议 |
|---|---|---|---|
idle | 连接成功,等待输入 | Winking → Cute Laugh → Adorable | idle.json(用 Winking) |
listening | 用户开始说话 | Attitude → Surprised | listening.json(用 Attitude) |
thinking | 用户说完,等待 LLM | Thinking → Suspicious | thinking.json(用 Thinking) |
speaking | TTS 开始播放 | Laughing → Cute Laugh | speaking.json(用 Laughing) |
happy | LLM emotion: happy | In Love → Gratitude → Greedy | happy.json(用 In Love) |
sad | LLM emotion: sad | Sad → Crying | sad.json(用 Sad) |
angry | LLM emotion: angry | Angry → Angry Stare | angry.json(用 Angry) |
disconnected | WebSocket 断连 | Shocked → Dizzy | disconnected.json(用 Shocked) |
💡 每个状态只需要 1 个 JSON 文件。剩余 12 个表情可以留着做随机彩蛋(比如长时间 idle 切到 Sleeping)。
# 下载的 JSON 文件重命名后放入 assets/lottie/ cp idle.json /var/www/piggy/assets/lottie/ cp listening.json /var/www/piggy/assets/lottie/ cp thinking.json /var/www/piggy/assets/lottie/ cp speaking.json /var/www/piggy/assets/lottie/ cp happy.json /var/www/piggy/assets/lottie/ cp sad.json /var/www/piggy/assets/lottie/ cp angry.json /var/www/piggy/assets/lottie/ cp disconnected.json /var/www/piggy/assets/lottie/ # 提交到 git cd /var/www/piggy git add assets/lottie/ git commit -m "Add piggy Lottie expressions" git push
在 index.html 中引入 Lottie Web:
<!-- index.html <head> 中添加 --> <script src="lib/lottie.min.js"></script>
修改 piggy.js,用 Lottie 替换 CSS 动画:
class PiggyCharacter {
constructor() {
this.container = document.getElementById('piggy');
this.anim = null;
this.state = 'idle';
this._loadAnimation('idle');
}
static ANIMATIONS = {
idle: '/assets/lottie/idle.json',
listening: '/assets/lottie/listening.json',
thinking: '/assets/lottie/thinking.json',
speaking: '/assets/lottie/speaking.json',
happy: '/assets/lottie/happy.json',
sad: '/assets/lottie/sad.json',
angry: '/assets/lottie/angry.json',
disconnected: '/assets/lottie/disconnected.json',
};
setState(state) {
if (this.state === state) return;
this.state = state;
this._loadAnimation(state);
}
_loadAnimation(state) {
if (this.anim) this.anim.destroy();
const path = PiggyCharacter.ANIMATIONS[state];
if (!path) return;
this.anim = lottie.loadAnimation({
container: this.container,
renderer: 'svg',
loop: true,
autoplay: true,
path: path,
});
}
}
💡 Lottie 动画是矢量 SVG,自动缩放适配屏幕。文件通常 20-100KB,加载很快。
小猪的角色状态与 xiaozhi 事件对应:
| xiaozhi 事件 | 角色状态 | 小猪表现 |
|---|---|---|
| WebSocket 连接建立 | 😊 idle | 眨眼、微微摇晃、尾巴轻摆 |
{"type":"listen","state":"start"} | 👂 listening | 耳朵竖起、眼睛睁大 |
{"type":"listen","state":"stop"} | 🤔 thinking | 头顶冒问号、眼睛转圈 |
{"type":"tts","state":"start"} | 🗣️ speaking | 嘴巴动、表情开心 |
{"type":"tts","state":"stop"} | 😊 idle | 回到发呆 |
{"type":"llm","emotion":"happy"} | 😆 happy | 笑眼、跳动、爱心特效 |
{"type":"llm","emotion":"sad"} | 😢 sad | 垂眼、耳朵耷拉 |
{"type":"llm","emotion":"angry"} | 😠 angry | 皱眉、鼻孔喷气 |
| 连接断开 | 😵 disconnected | 眼睛变×、显示"连接中..." |
| 方案 | 成本 | 延迟 | 内存 | 中文效果 |
|---|---|---|---|---|
| Groq Whisper 免费 | 免费 (28,800s/天) | ~300ms | 0(云端) | ⭐⭐⭐⭐ |
| Qwen3 ASR Flash 推荐 | ¥0.015/分钟 | ~200ms | 0(云端) | ⭐⭐⭐⭐⭐ |
| FunASR (本地) | 免费 | ~500ms | ~800MB ❌ | ⭐⭐⭐⭐⭐ |
| 阿里百炼 Paraformer 流式 | ¥0.015/分钟 | ~200ms | 0(云端) | ⭐⭐⭐⭐⭐ |
💡 阿里百炼 Paraformer 流式识别,延迟低,中文效果好。Qwen3 ASR Flash 基于大模型,准确率最高但非流式。Groq Whisper 免费备选。
💡 三个方案用同一个阿里云百炼 API Key(Paraformer 和 Qwen3ASRFlash)。
| 方案 | 成本 | 音质 | 延迟 | 特色 |
|---|---|---|---|---|
| 硅基流动 CosyVoice2 推荐 | $7.15/百万字符 | ⭐⭐⭐⭐⭐ | ~300ms | 双向流式,首音 0.3s,情感控制强。model: FunAudioLLM/CosyVoice2-0.5B,voice: :alex(男) / :diana(女) 等 |
| EdgeTTS 备选 | 免费 | ⭐⭐⭐⭐ | ~1-2s | 音色多,中文 zh-CN-XiaoxiaoNeural 甜,适合调试 |
| FishSpeech (本地) | 免费 | ⭐⭐⭐⭐⭐ | ~1s | 可克隆任意音色,但吃资源 (~1GB) |
| 小米 MiMo V2.5 🆕 待观察 | 限时免费 | ⭐⭐⭐⭐⭐ | 不支持流式 | 大模型 TTS,支持声音克隆 + 风格指令 + 方言。⚠️ API 格式不兼容(用 chat/completions 而非 audio/speech),且暂无实时流式,无法用于实时语音对话。等官方支持流式后再接入。 |
💡 流式管线优势:LLM 首 Token 到达即触发 TTS 边合成边发音频,CosyVoice2 首音 ~0.15s。整体响应延迟从 ~4s 降到 ~1.5s。
| 层 | 技术 | 说明 |
|---|---|---|
| 前端 | 原生 HTML/CSS/JS | 单文件,零依赖,Echo Show 兼容性最佳 |
| 动画 | Lottie Web + CSS fallback | Lottie 渲染小猪表情,CSS 做简单微动 |
| 通信 | WebSocket (xiaozhi 协议) | JSON 状态帧 + Opus binary 音频帧 |
| 音频采集 | getUserMedia + Web Audio API | 浏览器麦克风 → PCM/OPUS → WebSocket |
| 音频播放 | Web Audio API | 接收 base64 音频 → 解码 → 播放 |
| 后端 | xiaozhi-esp32-server (Docker) | 已验证的开源方案,9.6k stars |
| ASR | Qwen3 ASR Flash / Groq Whisper | 大模型识别 ¥0.015/分钟;Groq 免费备选 |
| LLM | DeepSeek V4 Flash | 速度快,中文强,¥0.5/百万Token |
| TTS | 硅基流动 CosyVoice2 | 流式,首音 ~0.15s,$7.15/百万字符,情感控制强 |
| VAD | SileroVAD | 本地运行,极轻量 (~5MB) |
| 唤醒词 | Porcupine WASM (浏览器端) | 路线 B:纯浏览器 WebAssembly,支持中文自定义唤醒词,无需装 App |
| 设备端 | Fully Kiosk Browser | €8.90 买断,全屏/常亮/防退出/麦克风授权/开机自启 |
| 反代 | Cloudflare Tunnel + Nginx | Cloudflare Tunnel (http2) 暴露到公网,nginx 监听 80 端口做 WebSocket 代理 |
| 仓库 | GitHub: piggy-display | 已有:treetree17/piggy-display (私有) |
| 组件 | 内存 | 说明 |
|---|---|---|
| 已有服务 (Hermes + HA + Syncthing) | ~2509MB | 当前占用 (65%) |
| xiaozhi-esp32-server | 🟡 ~200-300MB | 纯 API 模式,无本地 ASR/TTS |
| SileroVAD | ~5MB | 极轻量 |
| 新增总计 | ~300MB | |
| 剩余可用 | ~700MB | ⚠️ 比较紧张,需要监控 |
⚠️ 如果后续上 FishSpeech (本地 TTS),需要额外 ~1GB,当前服务器不够。方案:停掉不用的服务,或升级到 8GB Droplet。
nano 文件路径(保存:Ctrl+O → 回车 → 退出:Ctrl+X)tee 一次性写入(代码块中已提供,直接复制粘贴即可)/opt/data/xiaozhi/ = 宿主机目录,/opt/xiaozhi-esp32-server/data/ = 容器内映射路径
1. 创建目录
mkdir -p /opt/data/xiaozhi mkdir -p ~/xiaozhi-stack
2. docker-compose.yml — 在宿主机创建:
sudo nano ~/xiaozhi-stack/docker-compose.yaml
粘贴以下内容:
services:
xiaozhi-server:
image: ghcr.m.daocloud.io/xinnan-tech/xiaozhi-esp32-server:server_latest
container_name: xiaozhi-server
restart: unless-stopped
security_opt:
- seccomp:unconfined
ports:
- '127.0.0.1:8000:8000' # WebSocket
- '127.0.0.1:8003:8003' # HTTP/OTA
volumes:
- /opt/data/xiaozhi:/opt/xiaozhi-esp32-server/data
extra_hosts:
- 'host.docker.internal:host-gateway'
deploy:
resources:
limits:
memory: 256M
cpus: '0.5'
💡 extra_hosts 让容器内可通过 host.docker.internal:8642 访问宿主机的 Hermes API。默认配置不需要这行,但留着也没坏处。
3. data/.config.yaml — 在宿主机编辑:
sudo nano /opt/data/xiaozhi/.config.yaml
粘贴以下内容(替换 YOUR_XXX 为你的实际密钥):
根据选择的 LLM 方案,使用对应的配置:
默认配置:DeepSeek V4 Flash 直连
server:
ip: 0.0.0.0
port: 8000
http_port: 8003
websocket: wss://piggy.treetree.tech/xiaozhi/v1/
selected_module:
ASR: Qwen3ASRFlash
LLM: DeepSeekLLM
TTS: CosyVoiceSiliconflow
VAD: SileroVAD
Intent: nointent
Memory: nomem
ASR:
Qwen3ASRFlash:
type: qwen3_asr_flash
api_key: YOUR_DASHSCOPE_API_KEY
base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
model_name: qwen3-asr-flash
output_dir: tmp/
enable_lid: true # 自动语种检测
enable_itn: true # 逆文本归一化
# 备选:阿里百炼 Paraformer 流式(WebSocket 流式,延迟低)
AliyunBLStreamASR:
type: aliyunbl_stream
api_key: YOUR_DASHSCOPE_API_KEY # 同一个阿里云百炼 API Key
model: paraformer-realtime-v2
format: pcm
sample_rate: 16000
output_dir: tmp/
punctuation_prediction_enabled: true
inverse_text_normalization_enabled: true
# 备选:Groq Whisper(免费,每天 28,800 秒)
GroqASR:
type: openai
api_key: YOUR_GROQ_KEY
base_url: https://api.groq.com/openai/v1/audio/transcriptions
model_name: whisper-large-v3-turbo
language: "zh" # 强制识别为中文
prompt: "这是中文对话,包含少量英语单词。" # 引导模型识别中文为主、偶尔夹杂英语
output_dir: tmp/
# 备选:讯飞流式 ASR(需注册讯飞开放平台)
XunfeiStreamASR:
type: xunfei_stream
app_id: YOUR_APP_ID
api_key: YOUR_API_KEY
api_secret: YOUR_API_SECRET
domain: slm
language: zh_cn
accent: mandarin
LLM:
DeepSeekLLM:
type: openai
model_name: deepseek-chat
url: https://api.deepseek.com
api_key: YOUR_DEEPSEEK_API_KEY
temperature: 0.7
TTS:
# 备选:EdgeTTS(免费,无需 API Key)
EdgeTTS:
type: edge
voice: zh-CN-XiaoxiaoNeural
output_dir: tmp/
# 备选:硅基流动 CosyVoice2(可能不稳定)
CosyVoiceSiliconflow:
type: siliconflow
model: FunAudioLLM/CosyVoice2-0.5B
voice: FunAudioLLM/CosyVoice2-0.5B:diana
access_token: YOUR_SILICONFLOW_API_KEY
output_dir: tmp/
VAD:
SileroVAD:
type: silero
threshold: 0.5
model_dir: models/snakers4_silero-vad
min_silence_duration_ms: 500
prompt: |
你是小猪 Piggy,一只可爱的小猪 AI 伴侣。说话简短可爱,喜欢用 emoji。
你住在 Echo Show 屏幕上,会随情绪变换表情。
在宿主机编辑 /opt/data/xiaozhi/.config.yaml,修改两处即可,重启容器生效:
sudo nano /opt/data/xiaozhi/.config.yaml
# 1. 改 selected_module.TTS
selected_module:
TTS: CosyVoiceSiliconflow # ← 改这里(可选值见下表)
# 2. 确认对应 TTS 配置段存在
TTS:
# 推荐:EdgeTTS(免费,稳定,无需 API Key)
EdgeTTS:
type: edge
voice: zh-CN-XiaoxiaoNeural # 微软甜美女声
format: mp3 # 指定输出格式为 MP3,避免 WAV 格式错误
output_dir: tmp/
# 备选:硅基流动 CosyVoice2(可能不稳定)
CosyVoiceSiliconflow:
type: siliconflow
model: FunAudioLLM/CosyVoice2-0.5B
voice: FunAudioLLM/CosyVoice2-0.5B:diana # 欢快女声(可选: :alex :benjamin :charles :david :anna :bella :claire :diana)
access_token: 你的_SILICONFLOW_API_KEY
output_dir: tmp/
💡 CosyVoice2 可用音色::alex(男声)、:diana(女声,欢快)、更多见 SiliconFlow 文档。格式:FunAudioLLM/CosyVoice2-0.5B:音色名。
💡 提示:硅基流动 CosyVoice2 支持流式合成,首音延迟低。如果遇到稳定性问题,可随时切换到 EdgeTTS(免费备选)。
| TTS 名称 | selected_module 值 | model | voice | 价格 |
|---|---|---|---|---|
| CosyVoice2 (SiliconFlow) | CosyVoiceSiliconflow | FunAudioLLM/CosyVoice2-0.5B | :alex / :diana | $7.15/百万字符 |
| EdgeTTS | EdgeTTS | — | zh-CN-XiaoxiaoNeural | 免费 |
| 火山引擎 豆包2.0 | HuoshanDoubleStreamTTS | — | zh_female_wanwanxiaohe_moon_bigtts | ~42元/月 |
| 阿里百炼 CosyVoice | AliBLTTS | cosyvoice-v2 | longcheng_v2 | 按量计费 |
| OpenAI TTS | OpenAITTS | tts-1 | alloy / nova 等 | $15/百万字符 |
💡 完整 TTS 列表见 xiaozhi-server 官方 config.yaml。
方案 A:DeepSeek V4 Flash 直连(默认,已在上面 config.yaml 中配置好)
无需额外操作,selected_module.LLM: DeepSeekLLM 即可。
方案 B:Hermes API 网关(可选,需先启用 Hermes API Server)
与方案 A 的区别:LLM 调用经过 Hermes 中转,自动获得记忆、工具、技能。只需改两处:
sudo nano /opt/data/xiaozhi/.config.yaml
# /opt/data/xiaozhi/.config.yaml — 改两处
selected_module:
LLM: HermesLLM # ← 从 DeepSeekLLM 改为 HermesLLM
Memory: nomem # Hermes 自带记忆,xiaozhi 侧关闭
LLM:
HermesLLM:
type: openai
model_name: hermes-agent
url: http://host.docker.internal:8642/v1
api_key: piggy-secret-key # 需与 Hermes API_SERVER_KEY 一致
启用 Hermes API Server 步骤:
# 1. 在宿主机编辑 /opt/hermes/.env,添加: nano /opt/hermes/.env
添加以下三行:
API_SERVER_ENABLED=true API_SERVER_HOST=127.0.0.1 API_SERVER_KEY=piggy-secret-key # 2. 重启 Hermes docker compose -f /opt/hermes/docker-compose.yml restart gateway # 3. 验证 curl -s http://127.0.0.1:8642/health # 4. 改好 config.yaml(见上面),重启 xiaozhi-server cd ~/xiaozhi-stack && docker compose restart
4. 启动 xiaozhi-server
# 预检端口占用 ss -tlnp | grep -E ':8000|:8003' && echo "⚠️ 端口被占用,先停掉冲突服务" || echo "✅ 端口空闲" cd ~/xiaozhi-stack && docker compose up -d docker logs -f xiaozhi-server # 看到 "Websocket地址是 ws://..." 即成功
1. 克隆仓库
git clone git@github.com:treetree17/piggy-display.git /var/www/piggy
2. 验证文件
ls -la /var/www/piggy/ # 应该看到: index.html, css/, js/, assets/, lib/, nginx/
3. 后续更新
cd /var/www/piggy && git pull
1. 创建配置文件 — 在宿主机用 tee 一次性写入(比手动 nano 不容易出错):
sudo tee /etc/nginx/sites-available/piggy > /dev/null << 'EOF'
server {
listen 80;
http2 off;
server_name piggy.treetree.tech;
# 拒绝访问隐藏文件(.git/ 等)
location ~ /\\. {
deny all;
return 404;
}
# 前端静态文件
root /var/www/piggy;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
# WebSocket 代理 → xiaozhi-server
location /xiaozhi/v1/ {
proxy_pass http://127.0.0.1:8000/xiaozhi/v1/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
# OTA 接口
location /xiaozhi/ota/ {
proxy_pass http://127.0.0.1:8003/xiaozhi/ota/;
proxy_set_header Host $host;
}
}
EOF
💡 SSL 由 Cloudflare Tunnel 自动处理(Tunnel 终止 TLS),nginx 只需监听 80 端口。不需要配置 A 记录或 SSL 证书。
2. 启用站点
# 创建软链接启用站点 sudo ln -s /etc/nginx/sites-available/piggy /etc/nginx/sites-enabled/ # 测试配置语法(必须看到 "syntax is ok" 才继续) sudo nginx -t # 重载 nginx(不用 restart,不断现有连接) sudo systemctl reload nginx
3. 验证
# 在服务器上
curl -sI https://piggy.treetree.tech/ # → 200 OK
curl -s https://piggy.treetree.tech/assets/lottie/cool.json | head -c 100 # → JSON 数据
# 验证 WebSocket 代理(返回 400 说明代理通了)
curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8000/xiaozhi/v1/ # → 400
4. Cloudflare Tunnel
piggy.treetree.tech 通过 Cloudflare Tunnel 暴露,不需要 A 记录。Tunnel 配置:
# Tunnel 配置文件:/etc/cloudflared/config.yaml
# Tunnel ID:8eb7a559-55e7-4f74-9471-a44ad5c49794
tunnel: 8eb7a559-55e7-4f74-9471-a44ad5c49794
credentials-file: /home/hermes/.cloudflared/8eb7a559-55e7-4f74-9471-a44ad5c49794.json
protocol: http2
ingress:
- hostname: piggy.treetree.tech
service: http://localhost:80
- service: http_status:404
💡 在 Cloudflare Dashboard → Zero Trust → Networks → Tunnels 中管理。使用 http2 协议(QUIC 可能导致 context deadline exceeded)。
Echo Show 上只装两样东西:LineageOS + Fully Kiosk Browser。零代码,纯显示终端。
1. 越狱 + 刷 LineageOS
按教程操作:pub.treetree.tech/echo-show-jailbreak
2. 购买 Fully Kiosk Browser
官网:fully-kiosk.com,€8.90 一次性买断(一个设备一个 license)。购买后会收到 APK 下载链接和 license key。
3. ADB sideload 安装
# 确认 ADB 已连接 adb devices # 安装 Fully Kiosk APK(下载后放在当前目录) adb install fully-kiosk-browser-xxx.apk # 如果安装失败(签名冲突),先卸载旧版 adb uninstall de.ozerov.fully
4. Fully Kiosk 设置
打开 Fully Kiosk,在 Settings 中配置:
| 设置项 | 值 | 说明 |
|---|---|---|
| Start URL | https://piggy.treetree.tech | 开机后自动打开的页面 |
| Kiosk Mode → Enable Kiosk Mode | ON | 锁定全屏,隐藏状态栏,防退出 |
| Kiosk Mode → Keep Screen On | ON | 屏幕常亮 |
| Kiosk Mode → Autostart on Boot | ON | 开机自动启动 Fully Kiosk |
| Kiosk Mode → Prevent Sleep | ON | 防止设备休眠 |
| Web Content Settings → Autoplay Video/Audio | ON | 自动播放音频(TTS) |
| Permissions → Access Microphone | ON | 自动授权麦克风(PLUS 功能,€8.90 已含) |
| Permissions → Access Camera | OFF | 不需要摄像头 |
| Remote Administration → Enable Remote Admin | ON | 开启本地 REST API(用于手势切换页面) |
| Remote Administration → Remote Admin from Local Network | ON | 局域网内可调用 API |
5. 手势切换:Piggy ↔ HA Dashboard
Fully Kiosk 支持手势触发动作。配置双击切换页面,无需在 Piggy 页面上加任何按钮,全屏体验不受影响:
| 设置 | 值 | 说明 |
|---|---|---|
| Settings → Gestures → Double Tap | Action: Load URL → https://ha.treetree.tech | 双击屏幕从 Piggy 切到 HA Dashboard |
HA Dashboard 切回 Piggy:
在 HA 中使用 Fully Kiosk 集成,添加按钮调用 fully_kiosk.load_url 切回 Piggy:
# HA button card 或 automation action: fully_kiosk.load_url target: device_id: <echo-show-device-id> data: url: https://piggy.treetree.tech
6. 开发者选项(兜底)
Android 设置 → 开发者选项 → Stay Awake(充电时屏幕常亮)。万一 Fully Kiosk 没自动启动,至少屏幕不会灭。
7. 验证清单
✅ 已验证方案:Reddit/XDA 多人成功在 Echo Show + LineageOS 上用 Fully Kiosk 跑 HA Dashboard。Mark Watt Tech 有完整视频教程(14万播放)。
| 项目 | 借鉴点 | 状态 |
|---|---|---|
| xiaozhi-esp32-server | 后端核心:WebSocket 协议、ASR/LLM/TTS 管线、Docker 部署 内置 digital-human 模块可参考前端实现 |
v0.9.3 · 9.6k⭐ |
| xiaozhi-esp32 | 官方固件,定义了通信协议(JSON 状态帧 + OPUS 音频帧) | 16k⭐ |
| Duolingo Lily + Rive | 状态机驱动模式:idle → listening → thinking → speaking → emotion | 参考设计 |
| py-xiaozhi | Python WebSocket 客户端实现,可参考协议细节 | 2.7k⭐ |
| LottieFiles 表情包 | 现成的可爱表情动画(笑脸、哭脸、眨眼),Web 原生渲染 | 待挑选 |
| 等级 | 风险 | 缓解措施 |
|---|---|---|
| 中 | 服务器内存不足(剩余 ~700MB) | 纯 API 模式不跑本地 ASR/TTS;监控内存,必要时停 Piper TTS 或升级 Droplet |
| 中 | xiaozhi-server 内存占用超预期 | 先用最简化安装(无数据库),观察实际占用 |
| 低 | Echo Show Silk 浏览器不支持 WebSocket | 越狱后用 Chromium,不依赖 Silk |
| 低 | Echo Show 麦克风采集延迟 | 越狱后用标准 Android API,比 Fire OS 兼容性好 |
| 低 | Lottie 在低端设备渲染卡顿 | 备选方案 B(纯 CSS),先测 Lottie 性能 |
| 低 | Porcupine WASM 在低端设备性能 | Porcupine 极轻量(设计目标就是嵌入式),Echo Show 的 ARM Cortex-A53 够用 |
| 低 | Echo Show 麦克风权限 | Fully Kiosk PLUS 自动授权麦克风;Porcupine WASM 直接用 getUserMedia |
| 低 | xiaozhi-server WebSocket 协议浏览器兼容性 | 官方 digital-human 已有浏览器端实现,协议兼容 |
参考 xiaozhi-performance-research 的测试数据,采用流式配置可将整体响应延迟从 ~4s 降低到 ~1.5s:
| 模块 | 非流式 | 流式 | 收益 |
|---|---|---|---|
| ASR | 等整段说完 (~1s) | 边听边出文字 (~0.8s 首词) | -0.2s |
| LLM | 等完整回答 | 首 Token 到达即触发 TTS | 并行 |
| TTS | EdgeTTS ~1-2s | EdgeTTS ~0.3s 首音 | -1s+ |
| 总计 | ~3-4s | ~1.5s | -2.5s |
💡 三级流水线:ASR 边听边识别 → LLM 首 Token 即触发 TTS → TTS 边合成边发音频。不是串行等待。
openwakeword-wasm-browser(开源免费,但仅英文预设唤醒词)mem_local_short(本地短期记忆)或 mem0ai(云端,1000次/月免费)当前安全架构:
127.0.0.1 — 外网不可直达.git/ 不暴露⚠️ 潜在风险:WebSocket 端点无认证,任何人知道 URL 就能连接,消耗 Groq/OpenCode 额度。单人使用风险低,但建议加 Cloudflare 保护。
在 Cloudflare 层面拦截未授权访问,不改 nginx,不改代码。
方式一:WAF Custom Rule(精确控制)
只允许你的 Echo Show IP 访问 WebSocket 路径,其他请求直接 block:
treetree.tech| 字段 | 值 |
|---|---|
| Rule name | piggy-ws-protection |
| When incoming requests match | URI path contains "/xiaozhi/" AND IP address does not equal <你的 Echo Show IP> |
| Then | Block |
💡 Echo Show 在家里,IP 基本固定。如果有多设备,用 IP is not in {IP1, IP2} 加白名单。
方式二:Rate Limiting(防刷)
即使不知道你的 IP,也能防止脚本暴力刷接口:
| 字段 | 值 |
|---|---|
| Rule name | piggy-rate-limit |
| When incoming requests match | URI path contains "/xiaozhi/" |
| Rate | 10 requests per 1 minute |
| Action | Block for 10 minutes |
💡 正常语音对话不会超过 10 req/min(一次对话 = 1 次 WebSocket 连接)。此规则防的是脚本批量连接。
方式三:Cloudflare Access(最强,需 Zero Trust)
在 /xiaozhi/ 路径前加一层身份验证,只有通过认证的设备才能访问:
piggy.treetree.tech/xiaozhi/⚠️ 这个方案最安全,但 Echo Show 上的浏览器需要能完成 OAuth 流程。Fully Kiosk 支持。
| 层级 | 保护 | 状态 |
|---|---|---|
| 网络层 | UFW 仅开 22/80/443 | ✅ 已有 |
| 容器层 | 端口绑定 127.0.0.1 | ✅ 已有 |
| 传输层 | Cloudflare TLS | ✅ 已有 |
| 应用层 | WebSocket 认证 | ⚠️ 建议加 Cloudflare WAF |
| 速率限制 | 防暴力刷接口 | ⚠️ 建议加 Rate Limiting |
单人使用 + Echo Show 在家里:当前保护已够用。如果担心被扫到,加 Cloudflare WAF 规则(方式一)5 分钟搞定。
| 阶段 | 内容 | 预计时间 | 前置条件 |
|---|---|---|---|
| Week 1 | 后端 Docker 部署 + Nginx 配置 | 1-2 天 | 无 |
| Week 1-2 | 前端基础页面(WebSocket + 音频) | 3-5 天 | 后端可用 |
| Week 2-3 | 小猪角色动画开发 | 3-5 天 | 角色风格确定 |
| Week 3 | Echo Show 越狱 + 部署 | 1-2 天 | 设备到手 |
| Week 4 | HA 集成 + 调优 | 2-3 天 | 前端稳定 |
仓库名:piggy-display(独立仓库,方案 A)
piggy-display/ ├── index.html ← 主页面(路线 C 核心,单文件可运行) ├── css/ │ └── style.css ← 样式 + 小猪角色 CSS 动画 ├── js/ │ ├── websocket.js ← xiaozhi WebSocket 协议(音频帧/状态帧) │ ├── audio.js ← getUserMedia 麦克风采集 + Web Audio 播放 │ └── piggy.js ← 小猪角色状态机(idle/listening/thinking/speaking/emotion) ├── assets/ │ └── lottie/ ← 小猪 Lottie 动画文件 ├── wakeword/ ← 路线 B(Porcupine WASM 唤醒词) │ ├── porcupine/ ← Porcupine 模型文件 (.ppn) │ └── wakeword.js ← 浏览器端唤醒词引擎 │ └── models/ ← Porcupine .ppn 模型文件 ├── nginx/ │ └── piggy.conf ← Nginx server block 配置 └── README.md
为什么独立仓库:
xinnan-tech/xiaozhi-esp32-server,不需要改# 移除 nginx 链接(站点立即不可访问) sudo rm /etc/nginx/sites-enabled/piggy sudo systemctl reload nginx
# 恢复 nginx 链接 sudo ln -s /etc/nginx/sites-available/piggy /etc/nginx/sites-enabled/piggy sudo systemctl reload nginx
cd /var/www/piggy sudo git fetch origin sudo git reset --hard origin/main # 验证更新 sudo git log --oneline -1
# 1. 更新前端代码 cd /var/www/piggy && git pull # 2. 重启 xiaozhi-server docker restart xiaozhi-server # 3. 重启 nginx sudo systemctl restart nginx # 4. 验证服务 curl -s http://127.0.0.1:8000/xiaozhi/v1/ | head -1
# TTS 故障排查(宿主机运行) sudo bash /opt/data/scripts/piggy-tts-debug.sh
# TTS 音频问题诊断(宿主机运行) sudo bash /opt/data/scripts/piggy-audio-diagnosis.sh
# xiaozhi-server 日志 docker logs xiaozhi-server -f --tail 50 # nginx 访问日志 sudo tail -f /var/log/nginx/access.log | grep piggy