aboutsummaryrefslogtreecommitdiffstats
path: root/src/hls-player.js
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-18 07:53:03 -0700
committerAdam Soltys <[email protected]>2026-10-18 07:53:03 -0700
commit8b64ecab1a289b055bad3cb4b4427dc5a8a0ff96 (patch)
treede3047d6abd0ec15c865e103c4fc1f30f60659ef /src/hls-player.js
parent972f668f669976317ac4b92fadb49c7a085aac30 (diff)
downloadcoinosv3-8b64ecab1a289b055bad3cb4b4427dc5a8a0ff96.tar.gz
coinosv3-8b64ecab1a289b055bad3cb4b4427dc5a8a0ff96.zip
Live streams (NIP-53), to watch: a row of what's on above a feed (Following: your follows' streams; Everything and Popular: all), a stream's own page at /naddr1… (the HLS stream playing — hls.js where the browser has no HLS — its chat and zaps as they come, a chat line sent as kind 1311, ⚡ to the host), a card for a post linking a stream, and a LIVE line on a streamer's profile. A stream quiet for an hour is over; one that drops is retried; zaps on a stream carry its a tag. Also: the single-file build's video stub gains streamVideo (its uploads threw since the HLS uploads).
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
Diffstat (limited to 'src/hls-player.js')
-rw-r--r--src/hls-player.js17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/hls-player.js b/src/hls-player.js
new file mode 100644
index 0000000..d0878e2
--- /dev/null
+++ b/src/hls-player.js
@@ -0,0 +1,17 @@
+// HLS where the browser has none of its own (Firefox): hls.js feeds the
+// <video> through Media Source. Chrome and Safari play the playlist as a
+// plain src, so this file is fetched only when needed. The single-file
+// build replaces it with a stub (attachHls → null): no stream there.
+export async function attachHls(video, src) {
+ const { default: Hls } = await import('hls.js');
+ if (!Hls.isSupported()) return null;
+ const hls = new Hls({ lowLatencyMode: true, backBufferLength: 30 });
+ hls.loadSource(src);
+ hls.attachMedia(video);
+ hls.on(Hls.Events.ERROR, (_, d) => {
+ if (!d.fatal) return;
+ if (d.type === Hls.ErrorTypes.MEDIA_ERROR) { hls.recoverMediaError(); return; }
+ video.dispatchEvent(new Event('hlsfatal'));
+ });
+ return hls;
+}