* fix: accept ranged VOD responses mislabeled text/html
Skip the HTML content-type rejection for 206 and Content-Range
responses so valid media from providers with a wrong Content-Type
plays in reverse proxy mode.
* add playback_provider to bind provider profile
Lets mapped provider:// playback URLs resolve on inputs whose url and
aliases are plain http(s), fixing 503 "Provider config not found".
* hls: add origin transfer telemetry
Measure existing shared-HLS origin fetches (segment, map, key,
manifest) and expose per-input availability and transfer quality at
GET /api/v1/hls/origin-telemetry and via the MCP tool
get_hls_origin_telemetry. Off by default via
reverse_proxy.hls_origin_telemetry, configurable in the Web UI.
Also split the reverse proxy config page into tabs.
* hls: add origin transfer telemetry
Measure existing shared-HLS origin fetches (segment, map, key,
manifest) and expose per-input availability and transfer quality at
GET /api/v1/hls/origin-telemetry and via the MCP tool
get_hls_origin_telemetry. Off by default via
reverse_proxy.hls_origin_telemetry, configurable in the Web UI.
Also split the reverse proxy config page into tabs.
* hls: add origin transfer telemetry
Measure existing shared-HLS origin fetches (segment, map, key,
manifest) and expose per-input availability and transfer quality at
GET /api/v1/hls/origin-telemetry and via the MCP tool
get_hls_origin_telemetry. Off by default via
reverse_proxy.hls_origin_telemetry, configurable in the Web UI.
Also split the reverse proxy config page into tabs.
---------
Co-authored-by: euzu <euzu@proton.me>
The provider:// origin rewrite called get_user_info() before checking
whether a credential rewrite is needed. Token-only M3U accounts have no
username/password, so the media manifest failed with 503 before
Media-server items shared one UUID in duplicate_filter, so Jellyfin
catalogs collapsed to a single entry. Derive the UUID from the stable
media-server id. Set header.logo for movies, series and episodes so
Xtream and M3U clients show posters.
* Added
- MCP server with Web UI config, stdio bridge and docs
Fixes
- GET /api/v1/stream-history rejected the `search_field` parameter the Web UI
sends (400), because axum's Query cannot read repeated keys into a list.
Add a FormQuery extractor (serde_html_form) and use it there.
- hls tests were flaky: HlsProxyManager::new() put every test manager's
segment cache into the shared /tmp/tuliprox/cache/hls, and the orphan
session cleanup of one manager deleted the files of parallel tests
(surfacing as MissingTimestampAnchor / TerminalUnavailable). Each manager
now owns a private cache directory that is removed on drop.
* fixed documentation: db dump paths and flag usage in operations-debugging
* Logs is a standalone Web UI view.
* mcp playlist iterator
* mcp playlist iterator
* media server import uses own categories
* mcp playlist iterator
* Playlit Update view layout changed
* media-server scheme or jellyfin_emby_plex
select_provider_stream_url now accepts a media-server:// reference when
the input type is Emby, Jellyfin or Plex. Other input types still reject
it.
* fix (hls): recover shared HLS retries and stream the first lease segment
* fix (hls): select fast-start live windows from the stripped live edge
Plan each lease's three-segment entry after applying strip to the full
origin window. Share the plan across rendering, required fetches and
publication, then grow activated windows forwards while preserving cached
predecessors.
Retain current-origin mappings during cache eviction and retire obsolete,
unprotected metadata during GC. Add window-selection, lease-boundary and
metadata-lifecycle regression tests and document the live entry behavior.
Validation: 1,238 HLS tests passed (2 ignored); 5 manifest API tests passed;
the independent 100-window metadata probe passed.
* fix (hls): preserve startup fallback and scope metadata cleanup
* fix (hls): wake fast-start fetches from provider fallback
* test (hls): cover unpublished fallback during lease recovery
Plan each lease's three-segment entry after applying strip to the full
origin window. Share the plan across rendering, required fetches and
publication, then grow activated windows forwards while preserving cached
predecessors.
Retain current-origin mappings during cache eviction and retire obsolete,
unprotected metadata during GC. Add window-selection, lease-boundary and
metadata-lifecycle regression tests and document the live entry behavior.
Validation: 1,238 HLS tests passed (2 ignored); 5 manifest API tests passed;
the independent 100-window metadata probe passed.
* fix (hls): preserve playback reserve across cache eviction
keep a stable session media clock and completed segment timings so cache
eviction and origin rollovers cannot reset playback reserve.
update segment fixtures and cover reserve stability after collection.
* fix (hls): prevent playback stalls during origin manifest retries
mark the origin as degraded on the first retryable manifest failure, cap
retry-after delays, and reevaluate reserve independently of client polling.
use a bounded state commit after an expired splice deadline instead of
leaving the lease live when terminal media cannot be published safely.
* fix (hls): serve custom responses after the live splice deadline
publish a finite lease-bound channel_unavailable playlist on the existing
manifest route when a safe live splice is no longer possible.
renew lease and session activity on successful custom-segment requests
and retain concrete preparation failure diagnostics.
* fix(hls): persist origin qualification for short playlists
Share qualification and retry receipts across leases, preserve them while media publication is pending, and allow controlled recovery after expired acceptance episodes. Prefer eligible regular candidates before short fallbacks.
Add startup, revalidation, replay, cookie and endpoint regression coverage, and document short-window behavior.
Validation during implementation: Linux make test (7009 passed, 23 ignored), focused HLS and endpoint suites, format checks, Clippy and Markdown lint. Offline production library and backend checks passed after the import fix.
* fix(hls): reconcile cache write budgets and revision reclamation
Transfer reserved bytes atomically through staging and publication, preserve cleanup ownership across cancellation, and retire unpinned revisions during local and global reclamation.
Version temp registrations during inventory scans, remove production panic calls, and isolate debug diagnostics from admission results.
Validation: 1,162 HLS tests and 7,038 workspace tests passed; fmt-check, lint, test, markdown-lint and isolated production Clippy passed with dev-slim.
* feat (ai): add local codex files
* fix (hls): replace invalid origin accounts in shared HLS sessions
* fix (hls): synchronize origin account handovers across WebUI viewers
* fix (hls): preserve same-account resume work and backpressure
* fix (hls): resume reduced retries without crossing generations
Allow eligible exhausted acceptance episodes to select reduced retry candidates
while preserving generation, candidate, workload and timing guards. Keep
recovery chains bound to their generation, including changes between selection
and commit.
Add regressions for repaired and persistent resource conflicts, generation
isolation and media delivery through the app's local HTTP origin. Keep shared
manifest fixtures under test/fixtures/hls/reduced-retry.
With startup.mode = optimistic, session.startup stays set for the whole
session lifetime on clear MPEG-TS sources. select_window's startup branch
returned before retain_published_predecessors, so the v3.3.153
three-target-duration retention never ran in that mode. A 3-segment
origin window was served unchanged (e.g. 17.96 s with target 7), both on
retained-session return entries and during steady playback.
Apply the retention after the startup branch's MIN_VISIBLE_SEGMENTS check.
The retention rules are unchanged: only contiguous Ready, renderable,
non-provisioning predecessors are added, never before the previously
rendered first segment, and the window is capped at
TARGET_VISIBLE_SEGMENTS.