this ended up being a large refactoring of the way pixel formats are
handled in the new ffmpeg pipeline. This was done to make reasoning
about which format to use when a bit easier -- it's still complicated.
The main issue here was for 10-bit output: when the incoming video was
using something like yuv420p10le, but we were using hwaccel, we have to
be sure to use the equivalent p010 format when reformatting frames from
hardware; p010le and yuv420p10le, for instance, are equivalent.
The way this is done now is by keeping the notion of "wrapper" pixel
format types while also introducing a delineation between
software/hardware pixel formats. While the naming isn't technically
"correct" (we could use p010le on hardware, if we wanted) it is meant to
be clear about which formats can be used on the boundaries between
software/hardware and when.
This commit features a major rewrite and refactoring of the streaming
pipeline and class hierachy in Tunarr. It introduces new default
streaming modes in an attempt to stabilize transitions between program
streams, reuse underlying resources (e.g. ffmpeg processes), reduce the
complexity of interaction between various streaming class components,
and increase flexibility for future development.
Some notable changes:
* The default MPEG-TS stream is now backed by HLS. IPTV and Web
streaming sessions are shared
* Transcode readahead implementation. This should create smoother
streams. For FFMPEG 7 (and future versions) we use the native
"readrate_initial_burst" option. For earlier versions we use an
artificial readahead. **NOTE**: FFMPEG <7 artificial readahead might
have unintended side effects (e.g. loudness normalization issues) and
as such FFMPEG 7+ is recommended
* Separation between building an ffmpeg process, spawning the process,
and the notion of a 'transcode session'. These are all separate
classes now with narrow concerns
* Other misc refactoring to cleanup code and remove leftover superfluous
logic from DTV
Plex will blindly append query parameters on the end of channel URLs
(e.g. ?transcode=heavy), instead of first checking if the URL has a
query param. It seems that Express (DTV) handled this differently than
Fastify; the latter seems to take the _last_ query string from the URL,
resulting in a 404.
This also hooks up dotenv for the server, making it much easier to set
env variables for different run modes (e.g. using
TUNARR_BIND_ADDR=0.0.0.0 to have Plex auto discover the HDHR tuner when
running the dev server)
* Cleaning up scary code - checkpoint 1
* Massive server cleanup + optimizations - Part 1
* Bump mikro-orm versions
* Pilot using tagged types (type branding) on FillerShow.uuid for
(maybe) better type checking
* Start hacking away at the 'helperFuncs' file inherited from DTV
* Optimizations in getCurrentProgramAndTimeElapsed to reuse the
precalculated 'startTimeOffsets' from the channel lineup
* More type checks
* Untangling some of the crazier types I added earlier on to make
sense of the original code
* General cleanup + best practices
* Move util.ts to util/index.ts
* No longer using req.hijack() to send raw video stream to frontend -
this cleaned up a lot of code
* Introduce VideoStream + ConcatStream classes which hold functionality
related to streaming that used to be in the monolithic video.ts
* Simplify ChannelCache and break dependence on Plex IDs. This now
caches using our internal DB IDs
Left TODO:
* Completely remove helperFuncs.ts and put the functions in a more
appropriate place
* Subdirectories for Plex files
* Subdirectories for 'Player' classes
* Subdirectories for 'ffmpeg' classes
* Persist channel cache to disk periodically so that server restarts
preserve that information about streaming
* Update lockfile
* Fix build
* Checkpoint - dynamic channels
* Yet another checkpoint
* Bump versions - makes a ton of stuff work magically; needed a patch for ts-essentials because of https://github.com/ts-essentials/ts-essentials/issues/381
* Checkpointing
* Checkpoint