Skip to content

架构与数据流 ​

alldayrec 是一个 Python 服务器加几个客户端。音频从录音设备或手机进来,服务器在本机做语音检测和声纹,把语音识别和摘要交给你选的云服务,结果存进 SQLite,原始录音一直留在磁盘上。

text
BLE recorder ──BLE──▶ phone app ──HTTP(S)──▶ server (FastAPI) ──▶ web UI, MCP, CLI
                      (or the phone's mic)    │ local: VAD, voiceprints (onnxruntime)
                                              │ cloud: ASR engine, OpenAI-compatible LLM
                                              ▼
                                       SQLite + original audio

组成部分 ​

目录内容
server/服务端:上传队列、VAD 和声纹、语音识别引擎、对话、摘要、MCP(Python 3.11,uv)
web/网页:今天、对话、人物、日历、实时转写、设备页(Vue,pnpm)
app/iOS 和安卓手机 App:录手机麦克风或蓝牙录音设备、上传、固件升级(Flutter)
firmware/devkit/nRF52840 板子的蓝牙录音设备固件(Zephyr / nRF Connect SDK),基于 Omi devkit
firmware/selftest/、firmware/blerelay/板子自检固件;测试用的 ESP32 蓝牙中继
hardware/lr-p3/LR-P3 录音设备的零件、接线和 3D 打印外壳
cli/lr.py:在终端或 Agent 里读你的对话

音频怎么进来 ​

录音设备一直往 SD 卡里写,连着手机时把同一份记录同时推给手机;断开期间的部分,手机回来后从卡上读回来补齐。手机 App 把音频切成 Opus 短块上传到 POST /api/chunks;离线时块在手机上排队,之后再传。

服务器把每一块先存进磁盘,再按时间顺序交给这台设备的处理流程。所以一个断网很久的客户端回来后可以一次把积压全传上来,别的设备不受影响。能 POST 音频文件的东西都能当音源,这也是导入已有录音的方式。

两层转写 ​

服务器在本机用 FireRedVAD 找出哪里有人说话,然后分两层转写:

  • 定稿层 一直在跑。它在停顿处把音频切开,每段最长 5 分钟,每段只送一次给语音识别引擎(ENGINE),结果就是最终的转写。
  • 初稿层 只在有网页开着时跑。它在停顿处(一直没有停顿时每隔 REFINE_EVERY_S 秒)把新的音频送给 DRAFT_ENGINE,几秒内出字;DRAFT_ENGINE=qwen-stream 时改为把音频持续流式推给千问,边说边出字。初稿只在定稿还没覆盖的时间段显示,定稿到了就被替换。

文字和分句来自语音识别引擎;本机负责语音检测和说话人身份,各引擎的说话人从哪里来见下表。送给引擎之前,长于 3 秒的静音会被剪到 3 秒(SQUEEZE_KEEP_S)。

各引擎的说话人来源不同:

ENGINE服务商说话人
qwen阿里云百炼,千问 Qwen-Audio 文件转写引擎给出,再用本地声纹修正
volc火山引擎豆包 Seed-ASR 2.0本地声纹
stepfun-sse阶跃星辰流式语音识别本地声纹
stepfun、stepfun-file阶跃星辰文件模式引擎给出,再用本地声纹修正
local服务器进程里的 sherpa-onnx X-ASR 中英模型,只出文字本地声纹

本地引擎和云端引擎的准确率对比见语音识别评测。

认人 ​

声纹模型 ReDimNet2 在本机 CPU 上跑。服务器认得出「我」(录音者本人),在一段对话里把其他人分成 S1、S2…;太短、认不出来的句子标成 S?。你在网页上给某个标签起了名字,之后的对话里同一个声音就会被认出来。

对话、摘要和回顾 ​

句子按时间归成对话:5 分钟没有人说话、录音设备停了,或者一段对话满 4 小时,它就结束。说话少于 10 秒的对话不保留成一段对话(句子还在转写里)。

对话结束后,服务器用你配置的大模型写摘要:标题、摘要、每个人的要点、待办(带截止日期)、决定和标签。说话不到 60 秒的对话不调大模型,标题取第一句。每天 RECAP_AT(默认 10:00)写前一天的回顾。

「问 AI」用同一个大模型回答关于你过去的问题:最近几天的摘要放在提示词里,更早的或者更细的内容通过查询数据库的工具找到,每个说法都带出处对话的 id。

谁在读这些数据 ​

网页、App 里的网页、MCP 端点和命令行读的都是同一个租户的数据库。数据库是 SQLite,你也可以自己直接读,表结构见数据目录。

一台服务器可以服务好几个人,每个人一个 token、一个数据库和一个录音目录(tenants.json),在同一个进程里互相隔离。