Show P1/A1 cameras as a refreshing picture
SnapshotView fetches one frame at a time through the backend, pauses while the tab is hidden and backs off after failures. PrinterCard picks it when /stream answers kind "snapshot".
This commit is contained in:
@@ -1,7 +1,13 @@
|
||||
/**
|
||||
* Where a printer's camera can be watched, from `GET /printers/:id/stream`.
|
||||
*/
|
||||
export interface PrinterStream {
|
||||
export type PrinterStream =
|
||||
| WebrtcStream
|
||||
// A P1/A1: no stream to negotiate, a picture to fetch again and again.
|
||||
| { kind: "snapshot"; snapshotPath: string; intervalMs: number };
|
||||
|
||||
export interface WebrtcStream {
|
||||
kind?: "webrtc";
|
||||
/** The go2rtc stream name to negotiate for. */
|
||||
cameraId: string;
|
||||
/**
|
||||
|
||||
@@ -56,6 +56,11 @@ async function signalOffer(printerId: string, sdp: string): Promise<string> {
|
||||
return answer.sdp;
|
||||
}
|
||||
|
||||
/** One camera frame (P1/A1) as an image, through the backend. */
|
||||
function fetchFrame(printerId: string): Promise<Blob> {
|
||||
return apiFetch<Blob>(`/printers/${printerId}/snapshot`, { responseType: "blob" });
|
||||
}
|
||||
|
||||
// Which farms exist, and for each whether its gateway is connected and what
|
||||
// discovery has found. Polled, because gateway presence has no push channel;
|
||||
// ten seconds is quick enough to notice an unplugged box without hammering.
|
||||
@@ -119,7 +124,7 @@ watch(
|
||||
printers,
|
||||
(list) => {
|
||||
for (const printer of list ?? []) {
|
||||
if (!printer.cameraStream || printer.id in streams.value) continue;
|
||||
if (!(printer.cameraStream || printer.cameraSnapshot) || printer.id in streams.value) continue;
|
||||
// Marked before the request resolves, so a re-render in the meantime
|
||||
// does not fire a second lookup for the same printer. `null` renders
|
||||
// no player, which is also the right thing to show while this is in
|
||||
@@ -149,6 +154,7 @@ watch(
|
||||
:printer="current(printer)"
|
||||
:stream="streams[printer.id]"
|
||||
:signal="(sdp: string) => signalOffer(printer.id, sdp)"
|
||||
:fetch-frame="() => fetchFrame(printer.id)"
|
||||
:send="(command: PrinterCommand) => sendCommand(printer.id, command)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user