aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-hub/src/meshbay_hub/static/video-player.js
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-hub/src/meshbay_hub/static/video-player.js')
-rw-r--r--packages/meshbay-hub/src/meshbay_hub/static/video-player.js20
1 files changed, 15 insertions, 5 deletions
diff --git a/packages/meshbay-hub/src/meshbay_hub/static/video-player.js b/packages/meshbay-hub/src/meshbay_hub/static/video-player.js
index 2c424fb..ed1f18c 100644
--- a/packages/meshbay-hub/src/meshbay_hub/static/video-player.js
+++ b/packages/meshbay-hub/src/meshbay_hub/static/video-player.js
@@ -6,6 +6,7 @@ import { Icon } from './icon.js';
import { formatSize, CHUNK_SIZE, pipelinedDownload } from './file-utils.js';
import { loadAuth } from './hub-client.js';
import * as platform from './platform.js';
+import { castSession } from './cast-session.js';
// Seconds of already-watched video kept in the SourceBuffer, and the queue depth
// past which we start making room before being forced to.
@@ -484,17 +485,22 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose, onDownload }) {
// Where the stream the node is sending begins, in film time. The same number
// the SourceBuffer gets as its `timestampOffset`.
const streamStartRef = useRef(0);
- const [castActive, setCastActive] = useState(false);
+ // A television already chosen this session (cast-session.js) takes the film
+ // from its first segment: the cast starts as a restart would, pending until
+ // the init segment arrives, and the player opens as its remote. Read once —
+ // a television chosen while this film plays is chosen here, by the picker.
+ const [autoCast] = useState(() => (castSession.supported ? castSession.device : null));
+ const [castActive, setCastActive] = useState(Boolean(autoCast));
const [castUrl, setCastUrl] = useState(null);
const [castPickerOpen, setCastPickerOpen] = useState(false);
const [castDevices, setCastDevices] = useState([]);
const [castScanning, setCastScanning] = useState(false);
- const [castDeviceName, setCastDeviceName] = useState(null);
- const castActiveRef = useRef(false);
+ const [castDeviceName, setCastDeviceName] = useState(autoCast ? autoCast.name : null);
+ const castActiveRef = useRef(Boolean(autoCast));
const castCodecRef = useRef(null);
const initSegmentRef = useRef(null);
- const castRestartPendingRef = useRef(false);
- const castDeviceRef = useRef(null);
+ const castRestartPendingRef = useRef(Boolean(autoCast));
+ const castDeviceRef = useRef(autoCast);
const castRestartGenRef = useRef(0);
// The receiver as last polled: { playerState, position } with the position
// on the film's timeline, or null before it has answered.
@@ -1758,7 +1764,10 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose, onDownload }) {
return () => { stopped = true; clearInterval(id); };
}, [remoteMode]);
+ // Stopping here is stopping for the session: the next film or photo stays
+ // on this device until a television is chosen again.
const stopCast = async () => {
+ castSession.forget();
await platform.cast.chromecastDisconnect().catch(() => {});
await platform.cast.stop();
setCastActive(false); castActiveRef.current = false;
@@ -1896,6 +1905,7 @@ function VideoPlayer({ entry, transportRef, gekRef, onClose, onDownload }) {
${castDevices.map(d => html`
<button class="cast-picker-item" onClick=${() => {
setCastPickerOpen(false);
+ castSession.choose(d);
setCastDeviceName(d.name);
setCastActive(true); castActiveRef.current = true;
castRestartPendingRef.current = true;