Commit Graph

517 Commits

Author SHA1 Message Date
truewhile f20c9c3234 fix(web): STRM 直连失败后回退 HLS 转码
不再把 STRM/云盘媒体锁死为直连,解析远端源后允许 ffmpeg 转码播放。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 22:52:54 +08:00
truewhile 38b85bb487 feat(strm): 同名多版本择优 / keep_ext,并支持合并展示与播放切换 (#30)
* feat(strm): 同名多版本择优/keep_ext,并支持合并展示与播放切换

默认对同名不同扩展(如 .mkv/.mp4)按体积→mtime→扩展名优先级择优生成一条 strm,冲突打日志;开启 keep_ext 则分别生成 name.ext.strm。媒体详情与播放器可切换版本,列表继续合并同片多版本,Emby MediaSources 名称区分容器/分辨率。

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* fix(meta): 边车匹配忽略 .mkv.strm 中间扩展,同片共享 NFO/海报/字幕

NFO、海报、字幕与刮削写出统一使用 mediaSidecarBase 词干,使竞女01.mkv.strm
与竞女01.mp4.strm 配对同一套 竞女01.nfo / 竞女01-poster / 竞女01.srt;
仍兼容历史上的 name.mkv.nfo 命名。

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* fix(emby): People NFO 按共享词干匹配 keep_ext strm

resolveMediaPeople 改为查找竞女01.nfo(并兼容旧的竞女01.mkv.nfo),
同时修正把 decodeNFOFile 的 partial 误当 ok 导致完整 NFO 被跳过的问题。

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-07 13:56:30 +08:00
truewhile 6bf8a6878a fix(strm): 115 元数据上传幂等,避免重复上传 (#29)
上传/重试前按父目录+文件名+SHA1 探活,已有同内容副本则跳过并清脏副本;
成功后回写新 file_id;同步扫描认可 30 分钟内同路径同大小的 done 任务,
缩短「任务已完成但列表未反映」导致的再入队窗口。

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-07 09:01:58 +08:00
truewhile 28aa466107 feat: 支持临时登录密码并完善 Emby 媒体详情兼容
- 新增 6 位临时密码生成与验证接口,支持 TV 及客户端快速登录
- 媒体及剧集详情补充 People 演职员信息解析与返回
- 优化剧集背景图与海报标签继承机制及播放时长兜底逻辑
- 增加临时密码登录相关的单元测试
2026-09-06 22:58:41 +08:00
truewhile f1b8010496 bug处理+emby客户端兼容 2026-09-06 22:10:23 +08:00
truewhile 465e98a792 bug 2026-09-06 19:02:53 +08:00
truewhile 292ae22dcd fix(sync): deduplicate remoteMeta by file ID to prevent deleting valid remote metadata copies 2026-09-06 17:36:54 +08:00
truewhile bc7e5fc79d 内网挂载emby封面无法加载问题处理 2026-09-06 17:35:33 +08:00
truewhile f7fec93d44 fix(upload): eliminate concurrent temp file name collision and support direct local file upload for 115 2026-09-06 17:05:56 +08:00
truewhile 3150971f10 feat(sync): implement 115 adaptive hierarchical flat scan to bypass deep paging limit 2026-09-06 16:15:26 +08:00
truewhile a71a18ce82 fix(upload): 删旧元数据失败时不中止任务,继续上传新文件
旧逻辑:DeleteFiles 失败 → uploadTaskFailWithRetry → 任务重试 →
再次 DeleteFiles 失败 → 永远无法上传,形成死循环。

新逻辑:DeleteFiles 失败时记录 warn 日志后继续上传新文件。
旧副本由下次同步的 scanLocalMetaForUpload 检测(新旧两个副本,
命中新版本后把旧版本 cid 收入 pendingDeletes)并通过
cleanupBatchRedundantFiles 异步批量清理。

这修复了小姐姐库在 115 限流环境下每次增量同步都重复上传
大量元数据的问题(Heyzo 等目录文件被上传了 7 次以上)。
2026-09-06 13:42:20 +08:00
truewhile 5a189a44fc Merge pull request #27 from gaodyoffice/fix/strm-sync-metadata
fix: OpenList metadata download 401 - use API instead of WebDAV
2026-09-06 12:30:40 +08:00
truewhile fb84c62e9a fix(sync): fallback to recursive traversal when 115 flat list hits deep-paging limit
115 API's flat list (search under the hood) enforces a hard limit of offset+limit <= 10000.
When syncing huge directories (e.g. >10000 files), this silently truncates results,
causing remote files to appear as missing locally, leading to infinite metadata
re-upload loops and potential wrongful deletion of strm files.

This patch auto-detects if the total file count >= 9500 and dynamically
falls back to the standard recursive concurrent traversal (walkRemote).
2026-09-06 12:27:56 +08:00
Gaodaiyang 355fd06036 fix: OpenList metadata download using API instead of WebDAV
OpenList 同步目录下载元数据(nfo/jpg/png/srt 等)全部失败,错误 http 401。

根因:Resolve() 中非视频文件走 WebDAV 直接下载,用 API token 作为 Authorization。
但 AList WebDAV 端点不接受 API token 认证,需要 Basic Auth。

修复:OpenList 在有 apiBase 时,所有文件都走 API /api/fs/get 获取直链,
不再走 WebDAV。API 失败时非视频文件可回退到 WebDAV。

影响范围:
- 只影响 OpenList 类型的非视频文件下载
- 不影响 115、CloudDrive2 等其他网盘
- 不影响视频播放/strm 生成
2026-09-06 11:41:12 +08:00
truewhile 4173caac5d bug处理 2026-09-06 01:16:30 +08:00
truewhile 2aeedcc182 bug处理 2026-09-06 00:01:40 +08:00
truewhile d96782622d bug处理 2026-09-05 23:02:26 +08:00
truewhile 28551c7883 清理qBittorrent接入残留:删除死schema分组与前端下载类型,下载器保存目录键改为downloader.savepath并兼容旧键 2026-09-05 18:08:52 +08:00
truewhile 5404e7773f 优化 2026-09-05 16:21:58 +08:00
truewhile 0e9fb2c937 优化,添加115接口文档 2026-09-05 14:32:58 +08:00
truewhile 1407b9b5c4 优化,排查项目问题 2026-09-05 12:34:17 +08:00
truewhile 4790f7753e bug处理 2026-09-05 01:15:11 +08:00
truewhile 203abd106a 优化 2026-09-04 11:56:29 +08:00
truewhile 1b611a6181 bug处理 2026-09-03 22:48:02 +08:00
truewhile 086c0307c3 bug处理 2026-09-03 20:51:24 +08:00
truewhile b9dd09a5d2 bug处理 2026-09-03 20:19:31 +08:00
truewhile e422ecce53 优化 2026-09-03 19:37:29 +08:00
truewhile a7eeb8fbeb 优化 2026-09-03 17:42:52 +08:00
truewhile c702a68cfb 优化 2026-09-03 16:53:12 +08:00
truewhile a79bbb80a8 Remove unused recycle bin and add optional local file delete (#26)
Soft-delete restore/purge/list and the recycle_purge job are gone.
Admin delete now removes library index rows, with an optional
delete_files query that also deletes local media + sidecar NFO.
UI copy is renamed from 移入回收站 to 删除, with a confirm checkbox.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-03 14:12:52 +08:00
truewhile 2b99f5f108 fix: enforce user library ACL on mounted Emby libraries (#25)
Mounted Emby libraries were always appended to web/Emby library lists and
detail/play routes without checking allowed_library_ids, so restricted
users could still see and open them. Filter remotes with the same
visibility policy as local libraries across list/detail/series/stream and
Emby Views/Items/search/playback, and label mounts in the admin ACL UI.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-03 10:39:44 +08:00
truewhile e872223b4e feat: honor pinned libraries in Emby client Views order (#24)
Sort /Users/.../Views so libraries the user pinned on the web appear
first for Infuse/Emby/Jellyfin clients. Unpinned libraries keep their
existing sort_order / remote-mount order.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-03 10:26:04 +08:00
truewhile ea732e5bd7 fix: allow pinning mounted Emby libraries without wiping local pins (#22)
accessibleLibraryIDSet only consulted the local libraries table, so
embyremote~ mount IDs were stripped on every GET/PUT. Saving a pin that
included a remote library could then persist a filtered list and clear
existing local pins from the client state. Include enabled Emby mounts in
the accessible set, and refuse pin toggles until the server list has
loaded successfully.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-03 09:40:52 +08:00
truewhile e8c710c261 fix: sync mounted Emby favourites across web and Emby clients (#21)
Unify favourite writes through SyncUserFavorite so remote mounted media is
stored locally and proxied to the upstream Emby server. Emby clients now
query favourites from the local table (including remote pseudo IDs), and
remote item payloads merge local IsFavorite state.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-03 08:50:46 +08:00
truewhile 1e291df647 feat: persist pinned libraries per user with cross-device sync (#20)
Store pinned library IDs on the user record and expose GET/PUT
/me/pinned-libraries endpoints. The web client now loads and saves pins
through the API, migrates legacy localStorage data once, and applies
pinned ordering on both the libraries and home pages.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-03 08:47:06 +08:00
truewhile ba27d48d10 优化 2026-09-02 23:05:38 +08:00
truewhile 32ae1aeba9 优化 2026-09-02 20:56:09 +08:00
truewhile a02583ee7d 优化 2026-09-02 19:00:01 +08:00
truewhile 5cd1aa3e91 优化 2026-09-02 18:26:31 +08:00
truewhile bbb512760a feat: make user limit configurable from admin user management (#18)
Store the per-instance user cap in settings (default 20) and expose
GET/PUT /admin/users/limit endpoints. The user management page now lets
admins view and update the limit without touching system settings.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-02 17:10:07 +08:00
truewhile b0fe40142a Rebrand MMTL to MeBox (name, logo, Docker image) (#17)
* Rebrand MMTL to MeBox across codebase and assets

Rename the project display name, Go module path, environment variable
prefix (MEBOX_*), Docker image references, and UI branding from MMTL/mmtl
to MeBox/mebox. Replace logo assets with the new MeBox icon and keep
legacy SQLite migration support for existing mmtl.db deployments.

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix logo icons: use cube-only crop without truncated text

Previous icon generation cropped too much of the source image, including
partial MeBox wordmark text that was cut off in square icon containers.
Regenerate logo-64/192/512, favicon, and SVG from cube-only region.

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-02 16:26:28 +08:00
truewhile 67b85840dc perf(strm): 优化 OpenList 元数据下载速度 (#15)
* Add favourite buttons to library list and series detail pages

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix favourites list for remote Emby mounted media

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Route favourites to library series detail when appropriate

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix favourites link to library series for remote anime paths

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix remote Emby playback history and continue watching

- Preserve duration_ms when web player reports duration=0
- Add GET /playback/:id/resume for reliable per-item resume
- Switch home continue watching to /watch-history/continue API
- Set library_id on remote media for play-profile visibility
- Keep continue-watching rows when remote metadata hydration fails

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix mobile sort dropdown overflowing off-screen

Align dropdown to button left edge on small screens and cap width
to viewport so sort options stay fully visible on mobile.

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Remove stale Windows binary backup files

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix STRM account edit form not echoing saved config

Return config_preview from account API for server/url/username and
secret flags. Merge partial config updates so empty password/token
fields do not wipe stored credentials.

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* perf(strm): speed up OpenList metadata downloads with provider-aware concurrency

- Split download semaphore: 115 stays capped at 3 for WAF safety; OpenList/CloudDrive2
  WebDAV metadata uses strm.download_threads (default raised to 6, max 16)
- Scope 115 WAF cooldown to 115 tasks only so OpenList downloads are not paused
- Requeue claimed tasks back to pending when slot acquisition fails or 115 is cooling
- Add tests for separate semaphores and requeue behavior

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-02 15:15:49 +08:00
truewhile 04fc50a4b0 Add library favourite buttons and fix remote favourites list (#14)
* Add favourite buttons to library list and series detail pages

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix favourites list for remote Emby mounted media

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Route favourites to library series detail when appropriate

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

* Fix favourites link to library series for remote anime paths

Co-authored-by: truewhile <truewhile@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-02 14:14:32 +08:00
truewhile 97b3a7bd7f feat(emby): support multiple connection lines for remote mount (#9)
Add account-level multi-line configuration for emby_remote mounts.
Lines are stored in strm_accounts.config as a urls JSON array with
backward compatibility for the legacy single url field. The backend
automatically fails over to the next line on connection errors and
persists the working active_line index.

Frontend: multi-line editor on Emby mount page and STRM account dialog
with add/remove/reorder, line names, and URL validation.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-02 11:19:56 +08:00
Cursor Agent 077458df31 Update Docker images to ghcr.io/truewhile/mmtl
Replace legacy shukebta/shukbet image references across all compose
templates, system update defaults, and security docs.

Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-02 01:59:48 +00:00
Cursor Agent ba621cfc4a Optimize home/library loading and SQLite query performance
- Replace home preview N+1 queries with a single window-function batch query
- Cache library previews and series card lists (15s TTL, shared with media cache)
- Tune SQLite: larger page cache, mmap, wal_autocheckpoint, ANALYZE on migrate
- Defer history fetch on library page until last_played sort is selected
- Yield to browser between paginated library loads to keep UI responsive

Co-authored-by: truewhile <truewhile@users.noreply.github.com>
2026-09-02 01:39:28 +00:00
truewhile b503fdee7a 优化续播 2026-09-01 23:16:11 +08:00
truewhile d3233a62c0 优化 2026-09-01 22:43:30 +08:00
truewhile 78526afc9c 优化 2026-09-01 21:24:55 +08:00
truewhile db64a6c093 优化 2026-09-01 18:55:05 +08:00