Files
euzuandGitHub 16d32d1298 DVR Feature (#819)
feat: complete DVR and improve streaming, security, configuration, and UI

Complete the Digital Video Recorder subsystem and add a broad set of
reliability, security, streaming, configuration, processing, and Web UI
improvements across Tuliprox.

DVR:

* complete live recording and provider-aware VOD download support
* add recording queue, workers, scheduling, and recurring recording rules
* add conflict detection and capacity-aware scheduling
* add pause, resume, retry, edit, cancel, and delete workflows
* add recording quotas and configurable retention policies
* add crash recovery and startup reconciliation
* add durable lifecycle notifications with per-channel retries
* add DVR health monitoring and diagnostic tooling
* add secure access to recordings, thumbnails, and subtitles
* add WebSocket notifications for recording and rule changes
* add Web UI management for recordings, rules, progress, and task state
* add RBAC, configuration, documentation, and i18n support

Streaming and HLS:

* fix shared-stream idle handling and release dead provider streams correctly
* stop tee streams when both client and cache consumers are gone
* cancel provisioning probes when client streams terminate
* fix transient HLS origin work accounting and intermittent 503 responses
* make stream buffer byte limits configurable
* make shared subscriber idle timeout configurable
* make initial HLS manifest wait timeout configurable
* add configurable TS chunk packet count
* add configurable HLS refresh failure backoff
* centralize redirect limits and retry jitter handling
* improve provider DNS refresh behavior and failover tuning
* preserve UTF-8 characters in catchup templates
* improve stream history validation and persistence error handling

Security:

* use constant-time credential comparisons
* harden library and media path handling against traversal and symlink escapes
* only trust forwarded client IP headers from configured trusted proxies
* redact credentials and sensitive URL data from logs
* reject invalid authentication status-code configuration
* deny users with unresolved plans or invalid content filters
* improve authentication error handling across proxy and HLS endpoints

Configuration and reliability:

* prevent invalid api-proxy.yml reloads from terminating the running server
* fully validate API proxy configuration before persisting changes
* log configuration and EPG cleanup failures instead of silently discarding them
* keep the last valid configuration active after failed hot reloads
* align backend and shared media-server validation
* remove duplicated path and normalization logic
* improve DNS-store recovery and Windows rename fallback handling
* reject invalid duration, timestamp, and numeric conversions safely
* fix playlist bouquet save error handling
* fix provider record update detection
* fix cache boundary handling
* improve startup and persistence failure diagnostics

Filtering, search, sorting, and processing:

* add field-scoped playlist explorer search
* centralize shared stream-history search field definitions
* extend the filter DSL with string, set, and numeric operators
* add EPG ID, channel number, and detected quality as filterable fields
* add filter dry-run preview API with match statistics and samples
* report filter syntax errors with line and column information
* add natural numeric-aware sorting
* add quality-aware channel deduplication
* add accent-independent deduplication
* move natural sorting and quality detection helpers into shared code
* persist explorer search-field selection across reloads

User plans and content access:

* add reusable API user plans for capability tiers
* support inherited cluster and connection limits with per-user overrides
* add plan-level and user-level content filters
* enforce content filters across Xtream, M3U, direct playback, resource access,
  stream info, short EPG, categories, and XMLTV
* add trial plans with automatic expiry and Trial status
* add plan selection and content filtering to the user editor
* add full plan management to the API configuration Web UI
* migrate the API user database to schema V7 with plan and filter persistence

Web UI and accessibility:

* add live logging console to the stats page
* improve login error handling and prevent duplicate authentication requests
* add keyboard navigation to tabs, menus, tables, and search
* add ARIA roles, labels, validation state, and live-region feedback
* add confirmation dialogs for destructive actions
* add unsaved-change warnings and Ctrl/Cmd+S shortcuts
* add loading, progress, empty, and in-flight states across views
* improve dropdown and single-selection behavior
* add clipboard and credential-copy helpers
* persist table pagination and explorer search preferences
* improve error recovery when UI context providers are unavailable
* remove multiple panic-prone unwrap and browser API paths
* replace remaining hardcoded UI strings with translation keys

Maintenance:

* resolve backend and frontend compiler and Clippy warnings
* update packages and test fixtures
* consolidate duplicated helpers and validation logic
* improve documentation for configuration, filters, plans, DVR, and REST APIs
* add and update tests for migrations, filters, deduplication, sorting,
  configuration, streaming, and accessibility behavior
2026-08-21 14:50:12 +02:00

201 lines
6.6 KiB
YAML

# TULIPROX_HOME should point to /app for docker
process_parallel: true
api:
host: 0.0.0.0
port: 8901
web_root: ${env:TULIPROX_HOME}/web
working_dir: ${env:TULIPROX_HOME}/data
backup_dir: ${env:TULIPROX_HOME}/backup
custom_stream_response_path: ${env:TULIPROX_HOME}/resources
connect_timeout_secs: 10
interner_gc_interval_secs: 180
interner_gc_min_pool_size: 100
# Used when no `User-Agent` is provided by the client request and none is set in input headers.
# If omitted, the built-in default is used.
default_user_agent: "VLC/3.0.16 LibVLC/3.0.16"
user_access_control: false
schedules:
- schedule: 0 0 4/23 * * *
targets: []
messaging:
notify_on: []
log:
sanitize_sensitive_info: false
log_active_user: true
log_level: debug
update_on_boot: false # best not to hammer upstream during testing
web_ui:
enabled: true
user_ui_enabled: true
content_security_policy:
enabled: true
custom-attributes:
- "default-src 'self'"
- "script-src 'self' 'wasm-unsafe-eval' 'nonce-{nonce_b64}'"
- "frame-ancestors 'none'"
- "style-src 'self' 'nonce-{nonce_b64}'"
- "style-src-attr 'unsafe-inline'"
- "img-src 'self' data:"
- "font-src 'self' data:"
- "connect-src 'self' wss:"
- "object-src 'none'"
- "base-uri 'self'"
- "form-action 'self'"
path:
auth:
enabled: true
issuer: tuliprox
secret: ef9ab256a8c0abe5de92c2e05ca92baa810472ab702ff1674e9248308ceeec92
userfile: user.txt
video:
web_search: "https://www.imdb.com/search/title/?title={}"
extensions:
- mkv
- avi
- mp4
- mpeg
- divx
- mov
download:
headers:
Accept: video/*
User-Agent: |
Mozilla/5.0 (AppleTV; U; CPU OS 14_2 like Mac OS X; en-us) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.1 Safari/605.1.15
directory: ${env:TULIPROX_HOME}/downloads
organize_into_directories: false
episode_pattern: .*(?P<episode>[Ss]\d{1,2}(.*?)[Ee]\d{1,2}).*
download_priority: 1
recording_priority: 0
reserve_slots_for_users: 1
max_background_per_provider: 1
retry_backoff_initial_secs: 3
retry_backoff_multiplier: 3.0
retry_backoff_max_secs: 30
retry_backoff_jitter_percent: 20
retry_max_attempts: 5
# DVR. Every field below is optional and shown at its default value;
# see docs/src/operator/dvr.md for the full reference.
# recording:
# # Master switch. `false` stops reconciliation, retention, and the
# # notification outbox, and the DVR routes stop doing work.
# enabled: true
# # Muxer ffmpeg writes: mpegts | matroska | mp4. mpegts survives
# # truncation, so a recording killed mid-stream still plays.
# container_format: mpegts
# directory: ${env:TULIPROX_HOME}/downloads/recordings
# timezone: UTC # IANA zone; used for rule timeslots
# filename_template: "{channel}_{program_title}_{start_time}"
# default_pre_roll_secs: 0
# max_pre_roll_secs: 900 # 15 min
# default_post_roll_secs: 0
# max_post_roll_secs: 1800 # 30 min
# # Estimated size for an unknown-bitrate recording, used for the
# # quota reservation before any bytes are measured.
# fallback_bytes_per_minute: 8388608 # 8 MiB/min
# retention:
# # Both policies are off when unset. Retention is the only thing
# # bounding recording disk use, so set at least one on a shared box.
# keep_last_per_channel: 10
# delete_after_days: 30
# sweep_interval_secs: 3600 # age/count sweep cadence
# disk:
# # Used-space percentages on the recording root's filesystem. When
# # used >= high, oldest completed recordings are deleted until
# # used <= low. Active recordings are never touched.
# high_water_percent: 85
# low_water_percent: 70
# cleanup_interval_secs: 3600 # watermark-check cadence
# safety_bytes: 1073741824 # 1 GiB kept free at all times
# quota:
# # Unset means unlimited. Charged by task state; see the operator doc.
# default_private_bytes: 53687091200 # 50 GiB per user
# shared_bytes: 536870912000 # 500 GiB for shared recordings
# per_user_bytes:
# "web:user-uuid-1": 107374182400 # 100 GiB override
# notifications:
# # Lifecycle notifications are delivered by a durable outbox that
# # retries per channel. outbox_buffer is fixed at startup.
# outbox_buffer: 1024
# max_attempts: 6
# backoff_initial_secs: 5
# backoff_max_secs: 900
reverse_proxy:
resource_retry:
max_attempts: 3
backoff_millis: 250
backoff_multiplier: 1.0
# geoip:
# enabled: true
# # unavailable_policy: deny # default. If GeoIP is disabled, missing, or not loaded,
# # country-based network_access rules deny non-CIDR-matching requests.
# # allow: explicit risk acceptance. Country-based network_access rules
# # allow when GeoIP is unavailable; CIDR-only misses still deny.
# unavailable_policy: deny
stream:
shared_burst_buffer_mb: 12 # default 12 MB
# stream_history:
# stream_history_enabled: true
# stream_history_batch_size: 128
# stream_history_retention_days: 30
# stream_history_directory: ${env:TULIPROX_HOME}/stream_history
# qos_aggregation:
# enabled: true
# interval_secs: 300
# compaction_interval_secs: 86400
rewrite_secret: ${env:TULIPROX_PROXY_REWRITE_SECRET} # use openssl rand -hex 16
library:
enabled: true
scan_directories:
- path: "/media/movies"
enabled: true
- path: "/media/tvshows"
enabled: true
# You can add more directories as needed
# - path: "/mnt/videos"
# enabled: false
supported_extensions:
- "mp4"
- "mkv"
- "avi"
- "mov"
- "ts"
- "m4v"
- "webm"
# Metadata configuration
metadata:
# Location to store metadata cache (JSON files)
path: "${env:TULIPROX_HOME}/library_metadata"
# TMDB (The Movie Database) API integration
tmdb:
enabled: true
# api_key: "" # Get your API key from https://www.themoviedb.org/settings/api
rate_limit_ms: 250 # Milliseconds between API calls (default: 250ms)
# Fallback to filename parsing if no metadata found
fallback_to_filename: true
# Metadata output formats
formats:
# - "nfo" # Optionally write Kodi-compatible NFO files
# Playlist integration
playlist:
# Group name for movies in M3U/Xtream playlist
movie_category: "Local Movies"
# Group name for series in M3U/Xtream playlist
series_category: "Local Series"