LunaTranslator 网络服务与 API 接口完全指南:Web 页面、HTTP 接口与 WebSocket 输出
【免费下载链接】LunaTranslator视觉小说翻译器 / Visual Novel Translator项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator
导读
LunaTranslator(视觉小说翻译器)内置了一套自研的轻量级 HTTP/WebSocket 网络服务,允许开发者在浏览器中远程查看翻译界面、调用翻译/OCR/TTS/词典查询等核心能力。本文基于 docs/vi/apiservice.md(英文版参见 docs/en/apiservice.md、中文版参见 docs/zh/apiservice.md),并结合 network/server/servicecollection.py、network/server/tcpservice.py 等源码实现,系统讲解服务如何开启、每个 Web 页面与 API 端点的作用、请求/响应格式以及 WebSocket 实时数据流的使用方式。读完本文,你将能独立在浏览器或脚本中接入 LunaTranslator 的翻译、查词、OCR、TTS 与实时文本输出能力。
1. 服务的开启与基本配置
1.1 在哪里开启
网络服务默认是关闭的,需要在设置界面中手动开启。相关配置项位于“设置 → 文本输入”区域(源码见 gui/setting/textinput.py):
- 开启(
networktcpenable):一个开关,默认值为False;打开后回调gobject.base.serviceinit()启动服务; - 端口号(
networktcpport):数值输入框,取值范围0~65535,默认端口为2333,修改后同样会触发服务重启。
设置界面还提供一个“打开”按钮,直接用默认浏览器访问http://127.0.0.1:{端口}。
1.2 服务启动的源码链路
服务启动逻辑位于 LunaTranslator.py:
@threader def serviceinit(self): gobject.base.portconflict.emit("") self.service.stop() if globalconfig.get("networktcpenable", False): try: self.service.init(globalconfig.get("networktcpport", 2333)) except OSError: gobject.base.portconflict.emit("端口冲突")关键点:
- 服务实例在应用初始化时创建,并一次性注册所有路由(
registerall(self.service),见 LunaTranslator.py); - 监听地址为
0.0.0.0(见 tcpservice.py),即局域网内其他设备也可访问,不只是本机127.0.0.1; - 端口被占用时会抛出
OSError,并在界面上提示“端口冲突”; - 可通过
globalconfig["network_service_disabled_paths"](默认空列表,见 defaultconfig/config.json)屏蔽指定路径——命中该列表的请求会被直接返回 404(见 tcpservice.py)。
1.3 路由注册一览
所有端点在 servicecollection.py 的registerall()中统一注册,完整清单如下:
| 类型 | 路径 | 处理类 |
|---|---|---|
| Web 页面 | /、/page/mainui、/page/transhist、/page/dictionary、/page/manyinone、/page/translate、/page/ocr、/page/tts | PageIndex、PageMainui、Pagetranshist、PageSearchWord、PageManyInOne、Pagetranslate、Pageocr、Pagetts |
| HTTP API | /api/translate、/api/dictionary、/api/mecab、/api/tts、/api/ocr、/api/list/dictionary、/api/list/translator、/api/textinput | APITranslate、APISearchWord、APImecab、APItts、APIocr、APIdicts、APITranslators、TextInput |
| WebSocket | /api/ws/text/origin、/api/ws/text/trans | TextOutputOrigin、TextOutputTrans |
| 内部 WebSocket | /__internalservice/mainuiws、/__internalservice/transhistws | internalservicemainuiws、internalservicetranshistws |
1.4 底层协议实现特点
这套服务没有依赖任何 Web 框架,而是直接用标准库socket实现(见 tcpservice.py),特点如下:
- 响应类型自动识别:处理器返回值可以是
dict/list(序列化为 JSON)、str(按 HTML 输出)、bytes(二进制)、FileResponse(静态文件,按 MIME 类型输出)、GeneratorType(流式输出text/event-stream),统一由ResponseInfo根据类型自动设置Content-Type(见 tcpservice.py); - CORS 支持:所有响应都带
Access-Control-Allow-Origin: *,浏览器端跨域调用无障碍; - WebSocket 握手:按 RFC 标准计算
Sec-WebSocket-Accept(SHA-1 + Base64,见 tcpservice.py); - WebSocket 帧编解码:完整实现了掩码处理、扩展长度(126/127)、Ping/Pong、Close 帧等(见 tcpservice.py)。
2. Web 页面端点
服务根路径/返回一个导航页(源码 htmlcode/service/index.html),列出所有页面链接。各页面端点说明如下:
2.1/page/mainui—— 主界面同步页
与主窗口显示的文本内容同步,包括原文、译文等渲染结果。其 HTML 由渲染模块动态生成(TextBrowser.loadex_(),见 servicecollection.py),页面数据通过内部 WebSocket/__internalservice/mainuiws推送刷新(见 gui/textbrowser.py 中大量WSForEach(mainuiwsoutputsave, ...)调用)。此外,页面还会把点击查词回调转发给主程序(calllunaclickedword=gobject.base.clickwordcallback)。
2.2/page/transhist—— 历史记录同步页
与历史文本(翻译历史)显示的文本内容同步,由wvtranshist.loadex_()生成页面(见 servicecollection.py),内部 WebSocket/__internalservice/transhistws负责推送新的句子与译文(见 gui/transhist.py)。
2.3/page/dictionary—— 词典查词页
查词页面,在/page/mainui中点击单词查词时会唤出该页面。其处理类PageSearchWord有一个细节:若 URL 查询参数中携带word且包含原型(prototype),会先做一次 302 重定向,把词形还原为原型后再打开页面(见 servicecollection.py),保证查询的是词典可识别的原形词。
2.4/page/manyinone—— 多合一页面
整合上述三个页面(主界面、历史、查词)的单一页面。其特殊交互逻辑是:在该窗口内的/page/mainui子区域点击单词查词时,不会打开新的查词窗口,而是在当前窗口的/page/dictionary子区域内显示查询结果(见 servicecollection.py)。
2.5/page/translate、/page/ocr、/page/tts
分别为翻译、OCR、TTS 三个独立功能的网页界面,页面文件存放在 htmlcode/service/ 目录下(translate.html、ocr.html、tts.html),分别由Pagetranslate、Pageocr、Pagetts返回。
3. HTTP API 服务
3.1GET /api/translate—— 翻译
- 必填查询参数:
text(待翻译文本); - 可选参数:
id(翻译器 ID)。指定后使用对应翻译器;未指定则使用当前最快的翻译接口; - 返回
application/json,包含三个字段:翻译器 IDid、翻译器名称name、翻译结果result。
实现细节(见 servicecollection.py):
- 通过
gobject.base.textgetmethod(text, False, waitforresultcallback=..., waitforresultcallbackengine=tsid, waitforresultcallbackengine_force=True, erroroutput=...)同步等待翻译结果,用threading.Event阻塞直至回调返回; - 翻译失败时返回
{"error": 错误信息, "id": 翻译器ID, "name": 翻译器名称}(id/name仅在错误携带 ID 时存在); - 翻译器 ID 与显示名通过
dynamicapiname()和_TR()解析。
示例:
curl "http://127.0.0.1:2333/api/translate?text=こんにちは" # {"id": "sakura", "name": "Sakura", "result": "你好"}3.2GET /api/dictionary—— 词典查词
- 必填查询参数:
word(要查询的单词); - 可选参数:
id(词典 ID)。
两种模式(见 servicecollection.py):
- 指定
id:返回单个词典查询结果的application/json对象,包含词典 IDid、词典名称name、HTML 内容result;查询失败(含词典不存在、无结果)时返回空对象{}; - 未指定
id:并发查询所有已启用词典,以text/event-stream流式返回,每个事件为一个 JSON 对象(id、name、result),方便前端边收边渲染。
实现上对所有词典调用cishu.safesearch(...)并发查询,用threading.Semaphore(0)统计并发计数并逐个收集结果(见 servicecollection.py)。
示例(单词典):
curl "http://127.0.0.1:2333/api/dictionary?word=日本語&id=jisho"示例(全词典流式):
curl "http://127.0.0.1:2333/api/dictionary?word=日本語" # data: {"id": "jisho", "name": "Jisho", "result": "<html>..."}3.3GET /api/mecab—— 日语分词解析
- 必填查询参数:
text; - 返回 Mecab 对
text的解析结果。实现上直接调用gobject.base.parsehira(text),并把每个解析单元通过_.as_dict()转为 JSON 数组返回(见 servicecollection.py)。LunaTranslator 内置 Mecab 封装(见 myutils/mecab.py),适合日语文本的形态素分析。
3.4GET /api/tts—— 语音合成
- 必填查询参数:
text; - 返回音频二进制数据,响应头包含由 TTS 引擎确定的
content-type(如audio/wav)与content-length;若 TTS 出错,则返回{"error": 错误信息}。
实现上通过gobject.base.reader.ttscallback(...)异步获取TTSResult,再用threading.Event等待结果后原样输出(见 servicecollection.py)。
示例:
curl -o out.wav "http://127.0.0.1:2333/api/tts?text=こんにちは"3.5POST /api/ocr—— 图片文字识别
- 请求方式为POST,
Content-Type: application/json; - 请求体包含字段
image,其值为Base64 编码的图片数据; - 返回当前 OCR 引擎的识别结果 JSON。
实现细节(见 servicecollection.py):服务端对image做base64.b64decode后加载为QImage,若图片损坏(qi.isNull())则直接报错;随后调用ocr_run(qi)(封装于 myutils/ocrutil.py)执行识别并返回结果。
示例:
IMG_B64=$(base64 -w0 screenshot.png) curl -X POST "http://127.0.0.1:2333/api/ocr" \ -H "Content-Type: application/json" \ -d "{\"image\": \"$IMG_B64\"}"3.6GET /api/list/dictionary—— 列出可用词典
返回当前可用的词典列表,每个元素为{"id": 词典ID, "name": 词典名称}。实现上遍历globalconfig["cishuvisrank"]中的词典排序,并过滤掉未实例化的项(见 servicecollection.py),因此顺序即界面上的显示顺序。
3.7GET /api/list/translator—— 列出可用翻译器
返回当前可用的翻译器列表,每个元素为{"id": 翻译器ID, "name": 翻译器名称}。实现上遍历globalconfig["fix_translate_rank_rank"]中的翻译器排序并过滤未实例化的项(见 servicecollection.py)。
3.8GET /api/textinput—— 注入文本到主程序
- 必填查询参数:
text; - 相当于远程“输入文本”:调用
gobject.base.textgetmethod(text, is_auto_run=False),把文本注入 LunaTranslator 主流程(走原文处理、翻译等管线),可用来做自动化测试或外部工具联动(见 servicecollection.py)。注意该接口没有返回值。
4. WebSocket 实时服务
两个 WebSocket 端点用于持续推送文本流,适合做实时翻译挂件、字幕同步、自动化采集等场景。
| 端点 | 推送内容 |
|---|---|
/api/ws/text/origin | 持续输出所有提取到的原文文本 |
/api/ws/text/trans | 持续输出所有翻译结果 |
实现机制(见 servicecollection.py 与 textio/textoutput/websocket.py):
- 客户端连接后,
WSHandler.parse()将自身追加到全局连接列表wsoutputsave; - 文本输出器
Outputer在收到新文本时,通过WSForEach遍历列表,把原文推送给TextOutputOrigin类型的连接、把译文推送给TextOutputTrans类型的连接(见 websocket.py); - 某连接发生
OSError(断开)时自动从列表移除,不影响其他连接。
前端接入示例(原文流):
const ws = new WebSocket("ws://127.0.0.1:2333/api/ws/text/origin"); ws.onmessage = (e) => console.log("原文:", e.data);5. 内部 WebSocket 与外部扩展
除公开端点外,主界面页与历史页还各自使用一组内部 WebSocket(/__internalservice/mainuiws、/__internalservice/transhistws)完成页面与主程序的实时同步。其消息协议为 JSON:{"function": "函数名", "args": [...]},例如主界面页支持calllunaloadready(页面加载完成)、callwheelEvent(滚轮事件)、calllunaclickedword(点击查词)等函数回调(见 servicecollection.py)。外部开发者可参考该模式实现自定义的远程界面。
6. 常见问题与注意事项
- 服务默认关闭:未在设置中开启
networktcpenable时,所有端口请求都会被拒绝,需先在设置界面开启或修改端口; - 局域网访问:服务绑定
0.0.0.0,同一局域网内的设备可通过http://<主机IP>:2333访问;如有防火墙请放行对应端口; - 端口冲突:端口被占用时界面会提示“端口冲突”,更换
networktcpport即可; - 禁用路径:可通过
network_service_disabled_paths配置禁用某些路径(返回 404),用于暴露面收敛; /api/textinput无返回:该接口只负责注入文本,调用后不要期待响应体内容;/api/dictionary的两种响应格式差异:指定id返回普通 JSON(失败为空对象{}),不指定id返回text/event-stream流,调用端需分别处理。
参考文件速查
- 关联文档:docs/vi/apiservice.md、docs/en/apiservice.md、docs/zh/apiservice.md
- 路由注册与各端点实现:network/server/servicecollection.py
- TCP/HTTP/WebSocket 底层实现:network/server/tcpservice.py
- WebSocket 连接池管理:network/server/servicecollection_1.py
- WebSocket 文本输出器:textio/textoutput/websocket.py
- 服务启动与配置:LunaTranslator.py、gui/setting/textinput.py
- 页面静态资源:htmlcode/service/
- 默认配置:defaultconfig/config.json
【免费下载链接】LunaTranslator视觉小说翻译器 / Visual Novel Translator项目地址: https://gitcode.com/GitHub_Trending/lu/LunaTranslator
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考