Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,20 @@
"start": "node .next/standalone/apps/web/server.js"
},
"dependencies": {
"@profullstack/player": "^0.3.1",
"@profullstack/rssamplifier": "workspace:*",
"@rssamplifier/auth": "workspace:*",
"@rssamplifier/db": "workspace:*",
"@rssamplifier/feed": "workspace:*",
"@rssamplifier/ingest": "workspace:*",
"@rssamplifier/search": "workspace:*",
"next": "^16.2.4",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"@swc/helpers": "^0.5.23",
"@rssamplifier/auth": "workspace:*",
"@rssamplifier/mail": "workspace:*",
"@rssamplifier/notify": "workspace:*",
"@rssamplifier/search": "workspace:*",
"@rssamplifier/translate": "workspace:*",
"@simplewebauthn/browser": "^13.0.0"
"@simplewebauthn/browser": "^13.0.0",
"@swc/helpers": "^0.5.23",
"next": "^16.2.4",
"react": "^19.2.0",
"react-dom": "^19.2.0"
}
}
53 changes: 51 additions & 2 deletions apps/web/src/app/DockPlayer.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { useCallback, useEffect, useRef, useState } from 'react';
import { attachSource } from '@profullstack/player';
import { useRouter } from 'next/navigation';

import { dockable, embedded } from '../lib/queue.js';
Expand Down Expand Up @@ -658,6 +659,56 @@ export default function DockPlayer() {
};
}, [remember]);

/**
* Get the track's bytes into the element.
*
* Was `src={track.src}` on both the <video> and the <audio>, which is right
* until a feed's enclosure is something the browser cannot open by itself.
* The directory is a crawl of the open web, so what turns up in an enclosure
* is whatever the publisher chose -- and an HLS playlist handed straight to a
* <video> plays nothing and reports a bare media error, which reads as a
* broken episode rather than a missing library.
*
* `attachSource` picks the delivery per source: native for the ordinary MP3
* or MP4, hls.js for a playlist. Everything the dock does around it -- the
* queue, the position it remembers, the popout, surviving a soft navigation
* -- is untouched.
*
* Skipped entirely for an embed: a YouTube or PeerTube track is an <iframe>,
* and there is no media element here to attach anything to.
*
* Attaching is asynchronous, because a delivery engine is only downloaded
* when a source needs one. `cancelled` is what stops a fast walk through a
* playlist leaving an earlier attachment running under a later one.
*/
useEffect(() => {
const el = mediaRef.current;
const src = track?.src;
if (!el || !src || embedded(track.kind)) return;

let cancelled = false;
/** @type {{ destroy: () => void } | null} */
let attached = null;

void attachSource(el, { src })
.then((result) => {
if (cancelled) {
result.destroy();
return;
}
attached = result;
})
.catch(() => {
// The element keeps whatever the browser made of it; the dock's own
// error handling still applies.
});

return () => {
cancelled = true;
attached?.destroy();
};
}, [track?.src, track?.kind]);

if (!track) return null;

const embed = embedded(track.kind);
Expand Down Expand Up @@ -714,7 +765,6 @@ export default function DockPlayer() {
// not started has nothing to paint, and a black rectangle in the
// corner of the window says nothing about what is in it.
poster={track.image ?? undefined}
src={track.src}
onEnded={() => advance(1, true)}
onPause={remember}
onPlay={remember}
Expand All @@ -726,7 +776,6 @@ export default function DockPlayer() {
className="episode-audio"
controls
preload="metadata"
src={track.src}
onEnded={() => advance(1, true)}
onPause={remember}
onPlay={remember}
Expand Down
44 changes: 44 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pnpm-workspace.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ allowBuilds:
# inside the image would add a toolchain to it for a speedup nothing is
# waiting on.
msgpackr-extract: false
minimumReleaseAgeExclude:
- '@profullstack/player@0.2.0 || 0.3.1'
Loading