Commit Graph
3 Commits
Author SHA1 Message Date
Claude c7a80d200e Hand cron over from youtube-automate, and script the rest
Cron now calls `ytstream run` hourly and ytstream's update-ytdlp.sh weekly.
Both inherit youtube-automate's healthchecks UUIDs and keep its schedules
unchanged: a check may be configured with a cron expression rather than a
simple period, so moving to the :23/04:50 slots the fragment proposed could
have alerted on a job that ran fine. Inheriting also means the placeholder
UUIDs never needed filling in.

The old service turned out to track only 2 channels, and one of them --
The Pyramid Podcast -- was sitting unresolved in ytstream's approval queue.
Decommissioning without checking would have silently dropped half of what
the old service existed to follow. Approved and backfilled.

decommission.sh does the two steps needing root (nginx repoint, disable the
unit) and refuses until an admin password is set, because the UI fails
closed and the hostname would otherwise serve a login nobody can pass.
Deleting the 2.0 GB of old downloads and touching the Jellyfin libraries
are left out on purpose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 10:53:48 +01:00
Claude b35b6a3689 Clear the stranded tmpfs cache at startup
The session map is memory-only, so session directories surviving a restart
can never be served and never be evicted -- and the work root is a tmpfs,
so that is leaked RAM until reboot. The restart that ships the TTFB fix
would have stranded 1.56 GB.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 10:34:08 +01:00
Claude d3616e7532 Bound time-to-first-byte so a first play actually plays
Playback failed in Jellyfin the day after deployment, for uncached videos
only. The handler blocked on the full download-and-mux before sending
anything at all -- not even response headers -- so a 46-minute upload sat
silent for 79 seconds and the client gave up. The proxy counted it a
success, which is why /healthz and doctor both looked fine.

Yesterday's "DirectPlay verified" only ever ran against videos already
pulled during testing, so the first-play path was never exercised.

The output is already a fragmented MP4, so it is readable while being
written; a finished file only buys a correct duration and working seeks.
Cap the wait at --first-byte-grace (12s, explicit in the unit) and stream
whatever has not muxed by then. Measured: 156s -> 12.0s TTFB on a
66-minute upload, with ranges on a complete file unchanged.

The cost is a first play with no seek bar when the grace is missed. Every
later play of that video is perfect.

Also fixes a hang found while testing this: the streaming loop waited on
"finished and good" rather than "finished", so a producer that died after
writing some bytes held the connection for the full 45s stall timeout and
then dropped it.

The stale yt-dlp warning pointed at youtube-automate's venv, the tree we
are decommissioning; it now names ytstream's. /healthz reports the serving
mode and grace. Eight new proxy tests, 353 passing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-13 10:31:47 +01:00