Live view over WebRTC (openpanel L1, server and browser)
A device reporting a `live` port streams its camera to the browser's own
RTCPeerConnection. The flows socket carries the signalling as text, so it
crosses the portal: `live` messages on a person's socket, `signal` on a
device's (start, sdp, candidate, bye, busy). The server routes by session,
holds a device to two viewers, ends a session when either socket closes or
no answer comes within 10 s, and gives each socket an outbox of its own
that ends a session rather than drop a message. TURN credentials are
minted per session in coturn's REST scheme (STUN_URLS, TURN_URLS,
TURN_SECRET), the viewer's with the device's offer; GET /devices/{id}/ice
hands them out too. The tunnel keeps a stream's early frames instead of
dropping them past eight and forgets them when the stream or link goes.
A media tile on a device's camera, and the Devices tab's preview, play
live when tapped, pause frames meanwhile, and fall back to frames with a
short note on busy, failure or no picture within 10 s. coturn is an
optional compose service behind the `turn` profile.
This commit is contained in:
@@ -2006,6 +2006,63 @@ export const HistoryPointSchema = {
|
||||
description: 'One numeric value a message carried, and when.'
|
||||
} as const;
|
||||
|
||||
export const IceServerSchema = {
|
||||
properties: {
|
||||
urls: {
|
||||
items: {
|
||||
type: 'string'
|
||||
},
|
||||
type: 'array',
|
||||
title: 'Urls'
|
||||
},
|
||||
username: {
|
||||
anyOf: [
|
||||
{
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
type: 'null'
|
||||
}
|
||||
],
|
||||
title: 'Username'
|
||||
},
|
||||
credential: {
|
||||
anyOf: [
|
||||
{
|
||||
type: 'string'
|
||||
},
|
||||
{
|
||||
type: 'null'
|
||||
}
|
||||
],
|
||||
title: 'Credential'
|
||||
}
|
||||
},
|
||||
type: 'object',
|
||||
required: ['urls'],
|
||||
title: 'IceServer',
|
||||
description: 'One STUN or TURN server, as `RTCPeerConnection` takes it.'
|
||||
} as const;
|
||||
|
||||
export const IceServersSchema = {
|
||||
properties: {
|
||||
ice_servers: {
|
||||
items: {
|
||||
'$ref': '#/components/schemas/IceServer'
|
||||
},
|
||||
type: 'array',
|
||||
title: 'Ice Servers'
|
||||
},
|
||||
ttl: {
|
||||
type: 'integer',
|
||||
title: 'Ttl',
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
type: 'object',
|
||||
title: 'IceServers'
|
||||
} as const;
|
||||
|
||||
export const ImportArtifactSchema = {
|
||||
properties: {
|
||||
name: {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -686,6 +686,20 @@ export type HTTPValidationError = {
|
||||
detail?: Array<ValidationError>;
|
||||
};
|
||||
|
||||
/**
|
||||
* One STUN or TURN server, as `RTCPeerConnection` takes it.
|
||||
*/
|
||||
export type IceServer = {
|
||||
urls: Array<(string)>;
|
||||
username?: (string | null);
|
||||
credential?: (string | null);
|
||||
};
|
||||
|
||||
export type IceServers = {
|
||||
ice_servers?: Array<IceServer>;
|
||||
ttl?: number;
|
||||
};
|
||||
|
||||
export type ImportArtifact = {
|
||||
name: string;
|
||||
filename?: (string | null);
|
||||
@@ -1879,6 +1893,12 @@ export type DevicesDeleteDeviceData = {
|
||||
|
||||
export type DevicesDeleteDeviceResponse = (Message);
|
||||
|
||||
export type DevicesReadIceData = {
|
||||
deviceId: string;
|
||||
};
|
||||
|
||||
export type DevicesReadIceResponse = (IceServers);
|
||||
|
||||
export type DevicesPutReportData = {
|
||||
deviceId: string;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user