Consolidates the ContentProgram type with the new Program API types. A
ContentProgram now reuses the new types. This is the beginning of a
massive simplification of API types and many code paths around Tunarr
Rework the filler picker to add more randomness and better weighting
behavior. Specifically:
1. Shuffle incoming filler lists
2. Filler weights only added to sampling if they have a program that can
fit in the requested time slot
3. Once a list is chosen, we shuffle the programs within that list
4. The rest of the algorithm remains the same with weighted sampling of
programs with slight adjustments based on last-seen and duration.
This change improves bottom navigation in the following ways:
- Adds labels and proper ARIA handling
- Highlights active item (including related subpages)
- Adds badge support from System page
- Fixes to stay above page content.
Co-authored-by: Corey Vaillancourt <coreyjv@gmail.com>
* feat: serve HLS master playlist via FFmpeg -master_pl_name
Switch the primary HLS endpoint to return a master playlist(playlist.m3u8)
generated by FFmpeg, with the variant playlist(stream.m3u8) served from
the /{sessionType}/stream.m3u8 sub-path.
This is a prerequisite for adding WebVTT subtitle tracks via
#EXT-X-MEDIA tags in the master playlist.
- Add -master_pl_name playlist.m3u8 to HlsOutputFormat and
HlsDirectOutputFormat so FFmpeg writes both playlists
- Track masterPlaylistPath in BaseHlsSession
- Add HlsSession.getMasterPlaylist() which reads playlist.m3u8
and rewrites the relative stream.m3u8 URI to an absolute server path
- streamApi: serve master playlist at /:id.m3u8; serve trimmed variant
playlist when clients request /:id/:sessionType/stream.m3u8
- Add unit tests for both output format classes and getMasterPlaylist()
* fix: use hls options instead of hardcoded stream name
---------
Co-authored-by: Corey Vaillancourt <coreyjv@gmail.com>
Logging wasn't working because they were using a static field initializer
which ran before the logger factory was initialized. Switch to a lazy
initialization so it's initialized on first use and logs with
the defined root logger.
Adds `shell.nix` with dependencies required for local development, so I
don't need to have them installed globally.
Launch using `nix-shell`.
on linux:
```bash
% nix-shell
Tunarr dev environment
node: v22.22.0
pnpm: 10.28.0
ffmpeg: ffmpeg version n7.1.1-56-gc2184b65d2-20250716 Copyright (c) 2000-2025 the FFmpeg developers
[nix-shell:~/code/tunarr]$
```
on mac:
```bash
% nix-shell
Tunarr dev environment
node: v22.22.1
pnpm: 10.28.0
ffmpeg: ffmpeg version 7.1.3 Copyright (c) 2000-2025 the FFmpeg developers
[nix-shell:~/code/tunarr]$
```
* Navigate back to custom shows table page after creating new custom
show
* Properly clear form state after saving new custom show
* Properly update form state after updating existing custom show