Skip to content

Releases

v2.3.0

Choose a tag to compare

@github-actions github-actions released this 12 Nov 10:48

Full Changelog: v2.2.1...v2.3.0

MAGI v2.2.1

Choose a tag to compare

@github-actions github-actions released this 25 Oct 05:55

MAGI v2.2.1 — 把「视频没法看」修掉

2.2.0 有一个能把视频彻底变废的回归:鼠标指针在画面上划过就快进/倒退,靠左竖滑还会一路改亮度。 这一版修掉它,另外补了两处相关的东西。

根因

两个播放器(libVLC 覆盖层 VideoOverlay、libVLC 不可用时的内置 <video> 回退层 VideoPlayer)都犯同一个错:手势处理里没有判断「鼠标是否按下」。

React 的 onPointerMove 挂的是 pointermove,指针只是划过、没有任何按键时也会连续触发。而手势状态里 x0 / y0 初始值是 0,于是 dx = clientX - 0 直接等于屏幕横坐标——鼠标随便挪一下就是几百像素的「位移」,一超过 14px 阈值就被判成「拖动进度」。竖向同理,左侧三分之一的竖滑被判成调亮度。

更糟的是 pointerup 只在真正按下后才来,所以这个错误的 seek 模式会一直挂着,直到你点一下鼠标才把累积的 dx 一次性提交——就是你看到的「视频自己跳走」。

修法

  • 手势判定抽成纯模块 src/video/gestureCore.ts,两个播放器共用。第一条规则就写在函数第一行:if (!g.down) return { type: 'ignore' }。没按下 = 什么都不许改。
  • 起判阈值 8px,防手抖误触。
  • 方向判定改对:原来是「谁的位移先超过 14px 谁赢」,斜着划一下就被判成 seek;现在要求横向幅度 大于纵向的 1.2 倍 才算拖动进度。
  • 状态复位统一走 gestureUp(),pointerup / pointercancel 都覆盖,手势不会残留到下一次。
  • 删掉 onDoubleClick:它和 pointerup 里的双击分区逻辑重复,双击一次会跳两次。
  • 新增 npm run test:gesture:28 条断言,纯 node 跑(--experimental-strip-types),不需要 Electron 也不需要浏览器。CI 已接入,回归会当场变红。

顺带

  • 内核降级不再静默:libVLC 加载失败时会退回内置 <video> 播放器(画面、手势都不同),以前一点提示都没有,用户只会觉得播放器坏了。现在右下角有角标「未加载 libVLC · 已退回内置播放器」,悬停能看到该检查哪个路径。
  • 自己遇到这个问题时先看一眼:如果视频是内置播放器(能看到左上角标题栏是网页样式、底部控制条也不一样),说明 resources/vlc/libvlc.dll 或开发期的 vendor/vlc/ 不在。跑一次 node scripts/fetch-vlc.mjs 就回来了。

现在的鼠标行为

操作 结果
不按键,随便划过 什么都不发生(只会把控制条唤出来)
按下 + 横向拖 拖动进度,松手提交
按下 + 竖向拖(右侧) 音量
按下 + 竖向拖(左侧三分区) 亮度(仅内置播放器,libVLC 层没有这一项)
单击 显示 / 隐藏控制条
双击左 / 右三分区 −10s / +10s
双击中间 全屏切换
按住不动 600ms 2x 快进,松开恢复

验证

  • npm run test:gesture → 28 / 28 通过
  • npx tsc --noEmit → 0 error
  • vite build → 通过
  • 未做:Electron 内的端到端手势验收(本机沙箱里 GPU 进程起不来,CDP 连上后 renderer 立刻崩)。scripts/probe-gesture.mjs 已经写好,在有桌面会话的机器上 npm run probe:gesture 可以直接跑那套 AI 验收。

MAGI v2.2.0 — 音乐换 foobar 范式,视频换 libVLC

Choose a tag to compare

@github-actions github-actions released this 25 Oct 05:18

MAGI v2.2.0 — 音乐换 foobar 范式,视频换 libVLC

破坏性变更。 这一版把「整合」时期留下的两条技术债一次性砍了:音乐层不再是 folia-major 的源码移植,视频层不再随包塞一个 mpv.exe。阅读器(EPUB / TXT)一行没动。

为什么非砍不可:folia 那一层是把上游 1039 个文件按 import 闭包原样搬进来的,它的在线账号、歌词 provider、封面 CDN 在纯本地场景全是空实现,任何一处 noop 兜不住就整块崩——这就是「整合之后一堆 bug」的来源。mpv 则是另一个方向的债:115 MB 的可执行文件随包分发,靠命名管道传 JSON,还得为它单独维护一套「找不到就降级」的分支。

音乐:foobar2000 / MusicBee 范式

src/folia/ 整体删除,src/music/ 从零写。取值取向是桌面音乐管理器,不是网页播放器:信息密度优先,动效让位。

  • 左侧媒体库树 —— 全部 / 最近添加 / 最常播放 / 从未播放,加上按 艺术家 / 专辑 / 流派 / 年份 / 文件夹 五种维度实时聚合。聚合是从曲目数组现算的,不落索引,导入完立刻就有。分组默认收起,点标题展开。
  • 右侧多列表格 —— # / 标题 / 艺术家 / 专辑 / 年份 / 时长 / 规格,每一列都能点表头排序。# 列默认按专辑内曲序而不是文件名(foobar 语义);「规格」列把 codec + 采样率 + 位深 + 声道压成一行 FLAC 44.1k 24bit,一眼看出无损还是转码。
  • 底部传输条 —— 扁平一条,常驻,是全应用唯一的 <audio> 元素宿主,所以切页面不会断音、也不会出现两条进度互相打架。顶部一条细线就是进度条,直接拖拽 seek。
  • 队列跟随筛选 —— 双击某一行时,队列用的是当前筛选后的列表,不是全库。在「2024 年」里双击第一首,下一首就是同一年的下一首。

视觉参数都是按桌面软件的密度调的:行高 27px、数字等宽、斑马纹、播放中那行用强调色而不是换背景。屏外行用 content-visibility: auto 跳过渲染,53 首和 5000 首的滚动开销差别很小。

视频:libVLC 3.0.21

electron/mpv.cjs → electron/vlc.cjs,用 koffi(N-API 预编译绑定)直接 FFI 加载 libvlc.dll——不需要 MSVC,不需要 node-gyp,Windows 上 npm i 完就能跑。

窗口结构沿用上一版那套(因为它是对的):videoWin(focusable: false,只负责提供一个 HWND)+ overlayWin(透明覆盖,承载控制条 UI)。libvlc_media_player_set_hwnd() 把 vout 挂进前者,原生子窗口永远画在网页内容之上,所以 UI 必须放在另一个窗口里。

状态回推改了做法:不再解析 libvlc_event_t——那是带 union 的 C 结构体,跨 FFI 读字段极易错位,一个字段偏移错了就是整块状态乱跳。改成 10Hz 轮询 get_state / get_time / get_length / audio_get_volume,稳定、可预期,代价可以忽略。

硬解默认 --avcodec-hw=d3d11va;--file-caching=1200 + --drop-late-frames + --skip-frames 保证本地大码率片源不追帧。

这一版踩到的三个坑(都记进 README 了):

症状 根因 修法
open 返回 false,media-new-failed libvlc_media_new_path 在 Windows 上不认 D:/x.mp4 这种正斜杠路径,直接返回 NULL toVlcPath() 统一归一反斜杠
视频跑到独立窗口里去了 set_hwnd 写在 play() 之后,VLC 已经建好 vout 顺序固定为 new_path → new_player → set_hwnd → play
插件加载失败 / 解码器缺失 --plugin-path 在 libvlc 3.x 已废弃,传了也没用 改走环境变量 VLC_PLUGIN_PATH + dll 同级 plugins/

另外 libvlc_media_player_set_aspect_ratio 是 2.x 的 API,3.0 里根本没这个符号,比例控制要拆成 video_set_aspect_ratio + video_set_crop_geometry + video_set_scale 三件套。

体积

2.1.1 2.2.0
直接依赖 34 8
node_modules 顶层项 1000+ 437
渲染层产物 dist/ 数十 MB 0.85 MB(3 files)
安装包 146 MB 138 MB

dist/ 这一项差了两个数量级,主要是 pixi + three + folia 的样式与字体资源一起走了。

安装包反而小了 8 MB,这点和直觉相反:解压后的 libVLC(180 MB)确实比 mpv.exe(115 MB)大,但 VLC 那堆小 DLL 在 NSIS 里压缩率极高,而 mpv 是一个已经压过的 115 MB 单文件、几乎压不动。真正省下来的是 folia 那层渲染资源。

libVLC 不入库(解压后 180 MB,超 GitHub 单文件上限),自建时先跑 node scripts/fetch-vlc.mjs,它会按 清华 → 中科大 → 官方 三镜像回退下载 3.0.21 并解压到 vendor/vlc/,electron-builder 自动复制成包内 resources/vlc。

验收

三个无头 CDP 探针,跑在真实运行的应用里,不是静态 DOM 断言。

视频 11 项(开发版与生产打包版都跑了一遍):

available=true   engine=libvlc 3.0.21
open=true (620ms / 生产版 455ms)   time advancing=YES
seek → 120s 生效    volume=45 → 0.42   mute=true   rate=1.5
pause → resume 正常    轨道列表 1 video / 1 audio
aspect: fit / fill / 16:9 三态切换正常
snapshot → 1376×768 真实视频帧(确认 vout 真的在画,不是黑窗)
close → buffered/width/height 全部归零
console errors = 0

音乐全项:.mu-page 渲染、58 行、7 列表头齐全、点「时长」排序后 0:01 → 7:12、展开专辑分组筛出 2 行、双击播放 currentId=b2 playing=true queue=2、传输条暂停/继续、音量 0.42、进度 seek 生效。注入的测试曲目跑完自动清理,残留 0。

整体冒烟 8 项:标题、preload 桥接 25 个方法、左侧三分区、canvas=0、#root 挂载、语言包 IPC、控制台无错误、无未捕获异常。

tsc --noEmit 与 vite build 均 exit 0。

其余

  • 顺带修掉几处过期配置:release.yml 里还在拉便携 mpv、产物目录还写着 ../nr_out;tsconfig.json 的 @/* 还指向被删掉的 src/folia/*;LICENSE 的第三方声明还写着「因移植 folia 而必须 AGPL」——现在删了移植层,继续用 AGPL 是选择而不是义务,声明里如实改了。
  • 许可证不变:AGPL-3.0-or-later。libVLC 是 LGPL-2.1+,以未修改的独立 DLL 随包分发、运行时 FFI 加载,可按 LGPL 要求自行替换。
  • folia 带走的还有 14 种可视化与 Lattice 歌曲墙。它们依赖在线歌词 provider 与账号态,本地跑起来只有空壳——想要可视化的话,Web Audio 那条通路还留着(src/lib/visualizer.ts),只是暂时没有消费者。
  • 这一版起有了真正的 CI:ci.yml 在每次 push / PR 上跑 node --check electron/*.cjs + tsc --noEmit + vite build;release.yml 在推 v* 标签时自动拉 libVLC、构建 NSIS 与 portable、发 Release。下面这个包就是它产出的。
  • 顺手记一个 CI 上的坑:unzipper 的 Extract() 在 GitHub runner 上解 74 MB 的 VLC zip 会抛 Premature close,本地却正常。改成优先调 Windows 自带的 bsdtar(必须显式写 System32\tar.exe——CI 的 bash 步骤里 PATH 首位是 Git Bash 的 /usr/bin,那里是 GNU tar,不认 zip)。

MAGI v2.1.1 — 补齐 folia 播放页(封面 / 歌词 / 桌面播放形式)

Choose a tag to compare

@noemoe5 noemoe5 released this 15 Oct 09:27

MAGI v2.1.1 — 补上 folia 的播放页(封面 / 歌词 / 桌面播放形式)

v2.1.0 把 folia 的播放层搬进来了,但只搬到了「歌曲墙」那一档:currentView === 'player' 的整块播放页从没进过闭包。所以点开一首歌只有海报墙,没有大封面、没有歌词、也不是 folia 的桌面播放形式。这一版把缺的那一块补齐。

修了什么

  • 播放页(player 档)补齐 —— 闭包新增 PlayerPanel.tsx + buildPlayerPanelModel.ts(闭包从 4 个入口长到 6 个,340 个文件 / 64925 行),外加 UnifiedPanel 的 MAGI 适配层 src/media/MagiPlayerPanel.tsx。
  • 歌曲封面出来了 —— folia 的封面位只有一个,就在 UnifiedPanel 侧栏里(img alt="Art",512px 请求尺寸 / 320px 展示)。之前侧栏被 AnimatePresence {isOpen && …} 挡着,封面根本没渲染。现在进播放页默认展开侧栏:大封面 + 五个标签页(封面 / 在线歌词 / 控制 / 队列 / 账户)+ 歌名 / 艺人 / 专辑。
  • 歌词出来了 —— 根因不在音频数据,而在视图档位:可视化器画不画歌词只认 resolveVisualizerShowText,它的唯一放行条件是 useAppViewStore.view === 'player',而这个 store 在 v2.1.0 里从没被写过(恒为 'home'),于是 showText 恒为 false,歌词浮层直接返回 shouldRenderOverlay: false。现在 MAGI 的 nowPlayingOpen / playView 会同步进 useAppViewStore.view(并给该 store 补了 module-level 的 setView,对齐它自己已有的导出风格)。
  • 「桌面播放形式」回来了 —— 分层按 folia 原样:可视化器 z-0 全屏铺底(封面取色背景 + 逐字大歌词 + 底部后续行预览)→ 歌曲墙 z-10(只在 lattice 档出现)→ 侧栏 z-60。

现在的交互

操作 结果
点底部播放条胶囊 进播放页:可视化器铺底 + 侧栏大封面(folia 的默认档)
播放条 / 侧栏里的「歌曲墙」 进 Lattice 海报墙(叠在可视化器之上)
侧栏右下 × 收起侧栏,只剩纯可视化器(歌照样唱、歌词照样走)

验收

无头 CDP 探针(静态服 dist/ → Edge headless + Emulation.setDeviceMetricsOverride 1600×900),走真实路径(对 [data-ponder="player-bar"] 派发真点击,而不是直接改 store):

B/PLAYER   view=player  isPanelOpen=true  panel=1  coverVisible=true(320×320)
           tabs=[cover,onlineLyrics,controls,queue,account]
           panelTitle=少女☆歌劇 レヴュースタァライト | アメリカ民謡研究会 | 永遠に違うよ。
           visActiveLine=僕の今日まで  glowWordCount=15  (主歌词行真的画出来了)
D/NOPANEL  view=player  isPanelOpen=false  visActiveLine=抱きしめて  glowWordCount=15
C/LATTICE  view=lattice  lattice=1  panel=0
E/CLOSED   view=home     playerSurface=0

14 种可视化模式巡览:全部有 canvas;封面作为画内图像出现的只有 monet(莫奈),其余模式的封面走侧栏与背景取色 —— 与上游一致。

探针踩到的坑:假的音源播不动,<audio>.currentTime 钉在 0,而 GlowWord 的词态迁移靠 useMotionValueEvent(currentTime, 'change'),值不变就一次都不触发,所有词卡在 waiting 初态(DOM 里有、肉眼看不见)。探针里把 currentTime 换成可拨动的墙钟才验出真结果 —— 这不是产品缺陷。

其余

  • 版本号 2.1.0 → 2.1.1;README 的音频段补上「播放页 / 歌曲墙」两档说明与第三处移植改动。
  • tsc --noEmit 0 error。
  • 构建与打包参数不变:CODEBUDDY_SAFE_DELETE_ENABLED=0,每个 target 用全新输出目录、串行跑。

MAGI v2.1.0 - folia 一比一移植 + 内嵌 mpv 真 HDR 视频

Choose a tag to compare

@noemoe5 noemoe5 released this 15 Oct 08:00

MAGI v2.1.0 — folia 一比一移植 + 内嵌 mpv 真 HDR 视频

这一版把上一版"参考 folia 做的形态"整个换掉了:音频播放界面现在是folia-major 的源码本身。

音频:folia 一比一移植

不再仿写,而是按 import 闭包整体搬运 —— 把 folia-major 的播放相关代码 1039 个文件原样复制进 src/folia/,再用别名 @ → src/folia 让 folia 内部的 @/xxx 与相对引用原样成立(folia 的 src/ ≡ MAGI 的 src/folia/)。没有重写一行 UI 代码,所以界面、动效、状态机、样式都与上游一致。

  • 底部播放条:folia 原版 Folium 胶囊进度条,全局常驻;首页态收成一条细进度胶囊,悬停展开
  • Lattice 全屏舞台:大封面海报墙 + 世界层 + 逐行歌词 + 铬层工具 + 播放队列,framer-motion 转场
  • 逐字歌词:pixi 8 渲染,标准 LRC 与增强型逐字都支持(同名 .lrc 或 ID3 内嵌),带歌词快慢微调与译文字幕叠加
  • 14 种可视化模式:cadenza cappella claddagh classic diorama fume lumiere monet partita pendolo sonnet still tempera tilt,另有 6 种背景模式;每种独立分包按需加载
  • 样式用 Tailwind 4 分层引入并跳过 preflight,避免 reset 冲掉既有的手写样式

移植时的两处必要改动:① folia 的 3 处 Web Worker 路径在 MAGI 里被禁用(打包后渲染层走 file://,Worker 脚本加载不可靠;这三处在 MAGI 都是死代码——元数据改由主进程提供,歌词解析改为同步就地计算,automix 分析退回主线程跑同一套数学)。② folia 依赖 file-type@^21 的 ./core 导出,MAGI 的 music-metadata@12 带的是 file-type@22,已改为根导入。

视频:内嵌 mpv,真 HDR

Chromium 的 <video> 在 Windows 上拿不到 HDR 色彩直通,所以视频改由随包分发的便携 mpv(v0.41.0 + libplacebo v7.375.0)解码:

  • 真 HDR 直通:--vo=gpu-next --gpu-api=d3d11 --target-colorspace-hint=yes,并走 --hwdec=auto-safe 硬解
  • 全格式:mpv/FFmpeg 支持的容器与编码基本都能放,不再受 Chromium 内核限制
  • 窗口结构:mpv 用 --wid 嵌进一个专用的原生视频窗口(原生子窗口永远画在网页内容之上,UI 压不住它),控制 UI 由另一个透明覆盖窗口承载,两层尺寸位置始终跟随主窗口 —— 观感仍是「视频在 MAGI 里」
  • 通信:mpv JSON IPC over Windows 命名管道,observe_property 实时回推 时间轴 / 时长 / 缓冲 / 暂停 / 音量 / 静音 / 倍速 / 分辨率 / EOF
  • 控制 UI:左右拖动快进快退(OSD 提示)、双击左右 ±10s、双击中间全屏、长按 2 倍速、滚轮调音量;控制栏 3 秒无操作自动隐藏;倍速 0.5x–2x;画面比例(适应/裁剪/拉伸);截图保存;外挂 .srt/.vtt/.ass(自动优先挂中文字幕)+ 内封字幕轨道选择、字号位置可调;队列连播、断点续播、播完自动下一集;键盘 空格 / ←→ / ↑↓ / F / M / Esc
  • 降级:机器上找不到 mpv 会自动退回 Chromium <video> 播放器,功能不丢、只是没有 HDR 直通

说明

  • 安装包体积明显变大(安装版 146 MB / 便携版 125 MB)是因为 115 MB 的 mpv 随包分发。从源码自建时按 README「打包」一节把 mpv 放到 resources/mpv/ 即可;不放也能构建,视频会降级。
  • mpv.exe 超过 GitHub 单文件 100 MB 上限,因此不入库(.gitignore 已排除 resources/mpv/),但随下面两个安装包分发。

文件

文件 说明
MAGI Setup 2.1.0.exe NSIS 安装版,可选安装目录、建桌面快捷方式
MAGI-portable-2.1.0.exe 免安装单文件

Windows x64。 当前仅构建 Windows 安装包。

MAGI v2.0.0

Choose a tag to compare

@noemoe5 noemoe5 released this 15 Oct 06:05

MAGI v2.0.0 — 从阅读器到影音综合体

项目正式改名 NovelReader → MAGI(书 / 乐 / 影三区一体),本次是第 2 个大版本。

🎵 新增:音乐播放(Folia 形态)

  • 本地音乐库:单文件导入 / 递归扫描文件夹;ID3v2 / FLAC / Vorbis / MP4 元数据(标题、艺人、专辑、年份、流派、Hi-Res 标识)与内嵌封面
  • 常驻底部播放条:封面 + 传输控制 + 进度拖拽 + 顺序 / 随机 / 单曲 + 音量
  • 全屏播放台:大封面 + 环形频谱 + 逐字歌词 + 播放队列 + 歌词快慢微调 + 睡眠定时
  • 歌词:同名 .lrc 或 ID3 内嵌,标准 LRC 与增强型逐字均支持
  • 断点续播:每首歌记住位置;队列 / 音量 / 模式跨会话保留
  • 支持 Windows SMTC 媒体键(Media Session)

🎬 新增:视频播放(Vivid Player 形态)

  • 视频库:单文件 / 文件夹导入,断点进度显示
  • 手势播放器:左右拖动快进快退(OSD 提示)、左上上下拖动调亮度、右上上下拖动调音量、双击左右 ±10s、双击中间全屏、长按 2 倍速、滚轮缩放 + 缩放后拖动平移
  • 字幕:外挂 .srt / .vtt / .ass(支持 视频名.zh-cn.srt 多语言标记)+ 内封字幕轨道,字号 / 位置 / 底色可调
  • 播放控制:倍速 0.5x–2x、画面比例、截图保存、画中画、队列连播、断点续播
  • 控制栏 3 秒自动隐藏;键盘空格 / ←→ / ↑↓ / F / M / Esc

📖 保留并增强

  • 阅读器:EPUB / TXT、双阅读模式、多主题、目录 / 书签 / 标注 / 进度
  • 文献查阅中心:划词即查 + 搜索台 + 学术文献库 + 本地词库
  • GPT-SoVITS 语音朗读
  • 左侧分区导航(书架 / 音乐 / 视频),旧书库数据完全兼容

🛠 工程

  • 主进程本地媒体 HTTP 服务:127.0.0.1 随机端口 + Range 支持 + CORS + 导入路径白名单(音视频拖动进度必需)
  • music-metadata 元数据解析(ESM 动态 import)
  • 新增模块:lib/lrc.ts、lib/subtitle.ts、lib/visualizer.ts、lib/mediaImport.ts、lib/useAudioEngine.ts、lib/audioGraph.ts

📦 安装

文件 说明
MAGI Setup 2.0.0.exe 安装版(NSIS),可改安装目录、建桌面快捷方式
MAGI-portable-2.0.0.exe 免安装单文件,双击即用

仅构建 Windows x64。macOS / Linux 可自行 npm run dist。

NovelReader v1.1.1

Choose a tag to compare

@noemoe5 noemoe5 released this 14 Sep 10:17

NovelReader v1.1.1

一个纯修复版本:修掉「查阅中心 / 文献库在书库页完全看不到」的入口缺失问题。


🐛 修复:文献查阅功能「装了但看不见」

1.1.0 里功能代码是全的(百度百科 / 萌娘百科联网链、主进程 lookup 代理、内置词库都在包里),但书库页(Home)压根没有渲染任何入口 —— 之前的代码只导入了图标、解构了 setLookupOpen / setLiteratureOpen,JSX 里一个按钮都没写,属于死代码。

结果就是:打开应用停在书库页时,看起来和旧版一模一样,唯一入口只剩阅读器顶部悬浮栏里两个没有文字的图标(而且悬浮栏平时是隐藏的,鼠标移动才出现)。

本版修复:

  • 书库页新增常驻入口条,不随书籍列表滚动,两张带图标 + 标题 + 说明的卡片:
    • 查阅中心 —— 划词即查 · 联网 + 本地词库
    • 文献库 —— 学术文献 · 引用生成
  • 即使不打开任何书,也能直接从首页进入这两个面板。

🌐 补齐英文语言包

英文词典整块缺少 research / lookup / literature 共 37 个 key,之前切到 English 界面会直接显示 research、tabLookup 这种原始 key 名。本版已补全。


📦 下载

文件 说明
NovelReader-portable-1.1.1.exe 免安装便携版,双击即用,适合先试
NovelReader Setup 1.1.1.exe 安装版(NSIS),支持覆盖安装升级

两个包内容一致,按习惯选一个即可。

✅ 验证

  • tsc --noEmit 零错误
  • vite build 通过
  • 打包产物 app.asar 已确认包含新入口的 JS / CSS 与中英文案

💡 入口速查

场景 位置
书库页(首页) 顶部常驻入口条 → 查阅中心 / 文献库
阅读中 顶部悬浮栏(鼠标移到顶部出现)→ 查阅 / 文献 图标
选中正文文字 划词浮条 → 查阅 / 收藏

NovelReader v1.1.0 — 文献查阅中心 + 大文件 EPUB 支持

Choose a tag to compare

@noemoe5 noemoe5 released this 14 Sep 09:51

NovelReader v1.1.0

沉浸式桌面小说阅读器 · Electron + React + EPUB.js · 免费开源 · 无需登录


🆕 文献查阅中心(本次主打)

阅读时选中任意文字 → 底部浮条弹出 查阅 / 收藏,一键调出资料卡片。

  • 三 Tab 查阅面板
    • 查阅:本地词库命中 + 联网摘要,可收藏为笔记、复制、打开原文、译成中/英
    • 收藏:所有查阅结果的收藏夹
    • 本地词库:搜索 / 新增 / 导入 JSON / 导出 JSON / 恢复内置(内置 16 条文学·出版·学术词条,断网可用)
  • 学术文献库:录入文献(标题/作者/年份/来源/链接/标签/备注),按标签筛选,一键生成并复制 GB/T 7714-2015 或 APA 7th 著录,可关联到某本书、导入导出 JSON
  • 离线兜底:无网络时自动降级到本地词库,不阻塞阅读

数据源(已实测)

数据源 状态
百度百科 openapi ✅ 200 / 约 280ms
萌娘百科(站内 API) ✅ 200 / 约 1s(轻小说·ACG·角色名极准)
MyMemory 翻译 ✅ 200 / 约 730ms

联网链按「可达源优先、被墙源降为末位兜底」排序,避免每次查阅先干等超时。


🐛 大文件 EPUB 加载修复

彻底解决 数百 MB ~ GB 级 EPUB 无法导入/打开 的问题。

  • 旧行为:导入与打开都把整本书读成 base64 → EPUB.js 底层 JSZip 在内存里整包解压(600MB 解压后数 GB)→ 渲染进程 OOM / 卡死。
  • 新方案:主进程用 unzipper 流式解压到临时目录(内存 O(1)),再起本地 HTTP 服务暴露解压目录,EPUB.js 走目录模式按需读取单文件,不再创建 JSZip。
  • 实测:657.6 MB / 394 章的书,流式解压 7.7s,EPUB.js 解析 0.2s,394 章全部正常。

📦 下载

文件 说明
NovelReader Setup 1.1.0.exe 安装版(推荐)
NovelReader-portable-1.1.0.exe 便携版,双击即用,无需安装

Windows 10 / 11 x64。


✨ 完整功能

  • 📚 书架管理:导入 EPUB / TXT,封面墙展示,删除后可从原路径重新导入
  • 📖 双阅读模式:竖向滚动 / 横向翻页,一键切换
  • 🎨 多主题、字体 / 字号 / 行距 / 边距可调
  • 📑 目录、书签、标注、阅读进度自动保存
  • 🔊 GPT-SoVITS 本地 AI 语音朗读:逐句朗读、自动续读下一章
  • 🔍 文献查阅中心:划词查询、笔记收藏、学术文献库
  • 🌐 中英双语界面

NovelReader v1.0.0

Choose a tag to compare

@noemoe5 noemoe5 released this 11 Aug 00:42

??????:Windows NSIS ???? portable ???????