需求完整分析 & 改造方案
现状问题汇总
- 当前提词器界面简陋,只有播放/暂停/退出;缺少大量专业提词器基础能力。
- 稿件列表缺少文件夹归档分类管理,草稿无法归类。
- 现有提词器页面逻辑:退出可以返回草稿列表(代码已经支持,之前闪退是ticker协程bug,修复后可正常返回)。
- 需要双模式切换:固定速度滚动模式(现有) / 语音识别智能跟随台词模式(新增)。
- 本地离线语音识别,不依赖云端接口;麦克风收音,识别朗读内容驱动文稿滚动。
- 参考网页
teleprompteronline.org/zh提取标准提词器功能集。
一、参考网页版提词器提取核心功能清单
📺提词播放界面(Play UI)
- 基础播放控制:播放 / 暂停 / 重置回到顶部;播放结束自动停止。
- 两种模式切换开关
- 【匀速滚动模式】传统定时滚动(当前代码已有,优化平滑滚动,不再直接跳到底部)
- 【语音智能跟随模式】麦克风收音,识别读到哪里滚到哪里;停顿自动暂停滚动,说话继续滚动。
- 显示样式设置(运行时可实时调整,不用退回编辑页)
- 字号调节、行间距调节
- 字体颜色、背景色(深色/浅色主题)
- 镜像翻转(水平镜像,硬件提词器设备必备)
- 全屏模式
- 阅读辅助
- 阅读居中指示线(标记当前朗读位置)
- 倒计时开场(3秒倒计时再开始滚动)
- 快捷键支持(空格播放暂停,R重置)
- 退出按钮,安全停止ticker、停止麦克风、释放资源,返回稿件列表。
📂稿件列表页面新增:文件夹归档管理
- 文件夹:新建文件夹,稿件可以移入文件夹;支持「全部稿件」「未归档草稿」视图。
- 数据库需要新增文件夹表,每个稿件归属folder_id;UI可以拖拽/选择移动稿件至文件夹。
- 区分:本地草稿、云端同步稿件标签。
🎤本地语音识别(智能跟随模式)
- 技术选型:Go+Fyne,集成 whisper.cpp 本地离线语音识别,无需联网,隐私优先。
- 工作流程:开启智能跟随模式 → 打开麦克风采集音频 → 本地Whisper实时转文字 → 和稿件文本做文本匹配,计算读到的位置,驱动UI滚动。
限制:实时语音识别CPU开销较高;安静环境识别效果好,嘈杂环境准确率下降,需要给用户提示。
🧩两种模式对比
| 项目 | 匀速滚动模式(原有) | 语音智能跟随模式(新增) |
|---|---|---|
| 驱动来源 | 定时器定时滚动 | 麦克风+本地语音识别结果匹配文稿 |
| 节奏 | 人适配机器设置的速度 | 软件跟随人的说话速度,停顿自动停滚,说快滚快 |
| 适用场景 | 排练、台词固定、录制节奏稳定 | 直播、口播、允许即兴发挥,双手解放 |
| 资源消耗 | CPU占用极低 | CPU占用高,依赖本地AI模型 |
| 依赖设备 | 不需要麦克风 | 必须麦克风设备 |
二、整体架构改动拆解
1.数据库层改动(sqlite)
- 新增表
script_folder文件夹表:id,name,created_at local_script增加字段folder_id int,外键关联文件夹;0=未归档草稿。
用于实现草稿归档进文件夹。
2.model层新增结构体
go
// model/model.go
type ScriptFolder struct {
ID int
Name string
CreatedAt string
}
3.业务层 app.go
- 文件夹CRUD接口:新建文件夹、删除文件夹、移动稿件到文件夹。
- 封装whisper本地语音识别的初始化、启动采集、停止采集接口;智能模式下回调返回识别文本片段。
注意:语音模型文件较大,程序首次启动提示用户下载中文小模型ggml‑base‑zh.bin。
4.UI层两大模块改造
A. script_list.go(稿件列表)
- 增加文件夹选择侧边栏;切换文件夹筛选稿件;新建文件夹按钮;移动稿件弹窗。
- UI条目显示标签:【本地草稿】【云端同步】。
B. teleprompter.go(重点改造,完整新版提词器界面)
原有逻辑缺陷:之前是直接
ScrollToBottom(),是跳到最底部,不是逐行平滑滚动,需要改成按像素持续偏移滚动 。界面布局:
顶部:模式切换开关【匀速滚动 / 语音智能跟随】、镜像开关、全屏、3秒倒计时开关。
中间:大文本提词阅读区域,居中指示线。
底部控制面板:字号滑块、行间距、速度滑块;播放/暂停、重置、退出;麦克风开关(智能模式才启用)。
5.边界与异常处理
- 语音识别异常处理:麦克风打不开弹窗提示;模型文件缺失弹窗提示;嘈杂识别匹配失败给提示,自动降级回匀速模式。
- 资源安全释放:退出提词界面,必须关闭ticker、停止麦克风录音、释放whisper上下文,防止后台持续占用CPU,避免闪退。
- JSON解析异常:稿件content损坏,友好弹窗提示,使用默认配置,不直接panic崩溃。
三、开发优先级(分3期落地,建议分步实现,不要一次性堆全部功能)
✅第一期【高优先级,先把基础体验做好,不碰语音识别】
目标:修复现有闪退;完善提词器基础UI;实现文件夹归档;平滑滚动替换跳到底部。
- 重构
teleprompter.go:- 替换
ScrollToBottom()为像素平滑滚动; - 增加:镜像翻转、字号实时调节、行间距、颜色主题、重置回到顶部、3秒倒计时;
- 完善退出逻辑,全部goroutine、资源释放彻底;
- 替换
- sqlite增加文件夹表;稿件列表支持文件夹归档,草稿分类管理。
- 修复全部panic,完善所有json解析、IO错误弹窗提示,不再静默兜底。
⏳第二期:双模式切换,增加开关,实现【匀速滚动】与【预留智能跟随UI入口】
UI层面完成模式切换按钮;智能跟随模式界面显示麦克风按钮,但是后台功能暂不实现。先把交互、布局全部调试完毕。
⏳第三期【重工作量:本地离线语音识别】
集成 whisper.cpp go绑定,实现麦克风实时音频采集,本地转写,文本匹配驱动滚动;
⚠️风险提醒:whisper实时识别对CPU有一定消耗,Windows需要gcc编译cgo,打包发布会附带模型文件,程序体积会增大几十MB。
四、关键技术难点说明
- Fyne canvas.Text不支持镜像翻转 :canvas原生没有水平镜像。
实现方案:使用widget.RichText或者自己用canvas.Image绘制镜像文字;或者使用容器缩放X=-1做翻转。 - 平滑滚动 :不能再用ScrollToBottom,维护一个scrollY像素偏移量,定时器每次增加少量像素,调用
scroll.ScrollToOffset(fyne.NewPos(0,scrollY))实现匀速上移滚动。 - whisper.cpp cgo编译:Windows需要MinGW‑w64环境;交叉编译发布版本比较麻烦。如果开发阶段,可以把语音识别作为可选编译tag,不需要时关闭。
- 文本匹配算法(智能跟读):拿到语音识别出的片段文本,与稿件全文做子串匹配,定位当前读到的字符偏移,换算滚动Y坐标;存在识别错字,需要容错。
五、下一步交付选择
你可以选择下面其中一种,我输出对应完整代码:
- 输出【第一期完整代码】:完善提词器界面+平滑滚动+镜像、倒计时、文件夹归档,暂不做语音识别(优先解决当前产品体验,工作量可控)。
- 如果你希望直接全部实现,我会输出完整设计+whisper集成示例代码,同时标注cgo编译、模型部署注意事项。