mirror of
https://github.com/legop3/MultiRoombaRover.git
synced 2026-09-17 01:50:47 -04:00
pass 2
This commit is contained in:
@@ -16,6 +16,7 @@ media:
|
|||||||
preview:
|
preview:
|
||||||
enabled: false
|
enabled: false
|
||||||
codec: "av1"
|
codec: "av1"
|
||||||
|
transport: "rtsp"
|
||||||
fps: 10
|
fps: 10
|
||||||
width: 640
|
width: 640
|
||||||
roomBitrateKbps: 200
|
roomBitrateKbps: 200
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ metricsAddress: 0.0.0.0:9998
|
|||||||
pprof: no
|
pprof: no
|
||||||
pprofAddress: 127.0.0.1:9999
|
pprofAddress: 127.0.0.1:9999
|
||||||
|
|
||||||
rtsp: no
|
rtsp: yes
|
||||||
rtmp: no
|
rtmp: no
|
||||||
hls: no
|
hls: no
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const previewConfig = mediaConfig.preview || {};
|
|||||||
|
|
||||||
const ENABLED = Boolean(previewConfig.enabled);
|
const ENABLED = Boolean(previewConfig.enabled);
|
||||||
const PREVIEW_CODEC = String(previewConfig.codec || 'av1').toLowerCase();
|
const PREVIEW_CODEC = String(previewConfig.codec || 'av1').toLowerCase();
|
||||||
|
const PREVIEW_TRANSPORT = String(previewConfig.transport || 'rtsp').toLowerCase();
|
||||||
const PREVIEW_FPS = Number(previewConfig.fps || 10);
|
const PREVIEW_FPS = Number(previewConfig.fps || 10);
|
||||||
const PREVIEW_WIDTH = Number(previewConfig.width || 640);
|
const PREVIEW_WIDTH = Number(previewConfig.width || 640);
|
||||||
const ROOM_BITRATE_KBPS = Number(previewConfig.roomBitrateKbps || 200);
|
const ROOM_BITRATE_KBPS = Number(previewConfig.roomBitrateKbps || 200);
|
||||||
@@ -36,6 +37,10 @@ function buildSrtPublishUrl(streamId) {
|
|||||||
return `srt://127.0.0.1:9000?streamid=#!::r=${encoded},m=publish&latency=10&mode=caller&transtype=live&pkt_size=1316`;
|
return `srt://127.0.0.1:9000?streamid=#!::r=${encoded},m=publish&latency=10&mode=caller&transtype=live&pkt_size=1316`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildRtspPublishUrl(streamId) {
|
||||||
|
return `rtsp://127.0.0.1:8554/${streamId}`;
|
||||||
|
}
|
||||||
|
|
||||||
function sanitizeCodec(codec) {
|
function sanitizeCodec(codec) {
|
||||||
return String(codec || '').toLowerCase().replace(/[^a-z0-9]/g, '') || 'av1';
|
return String(codec || '').toLowerCase().replace(/[^a-z0-9]/g, '') || 'av1';
|
||||||
}
|
}
|
||||||
@@ -91,6 +96,17 @@ function buildArgs(source) {
|
|||||||
const gop = Math.max(1, Math.round(GOP_SECONDS * PREVIEW_FPS));
|
const gop = Math.max(1, Math.round(GOP_SECONDS * PREVIEW_FPS));
|
||||||
const maxrate = Math.floor(source.bitrateKbps * 1.1);
|
const maxrate = Math.floor(source.bitrateKbps * 1.1);
|
||||||
const bufsize = Math.max(1, source.bitrateKbps * 2);
|
const bufsize = Math.max(1, source.bitrateKbps * 2);
|
||||||
|
const codec = PREVIEW_CODEC === 'av1' ? 'libsvtav1' : 'libx264';
|
||||||
|
const extraCodecArgs =
|
||||||
|
codec === 'libx264'
|
||||||
|
? ['-tune', 'zerolatency', '-profile:v', 'baseline', '-sc_threshold', '0']
|
||||||
|
: [];
|
||||||
|
const outputUrl =
|
||||||
|
PREVIEW_TRANSPORT === 'rtsp' ? buildRtspPublishUrl(source.outputId) : buildSrtPublishUrl(source.outputId);
|
||||||
|
const outputArgs =
|
||||||
|
PREVIEW_TRANSPORT === 'rtsp'
|
||||||
|
? ['-f', 'rtsp', '-rtsp_transport', 'tcp']
|
||||||
|
: ['-f', 'mpegts'];
|
||||||
return [
|
return [
|
||||||
'-hide_banner',
|
'-hide_banner',
|
||||||
'-loglevel',
|
'-loglevel',
|
||||||
@@ -105,9 +121,10 @@ function buildArgs(source) {
|
|||||||
'-vf',
|
'-vf',
|
||||||
`fps=${PREVIEW_FPS},scale=${PREVIEW_WIDTH}:-1`,
|
`fps=${PREVIEW_FPS},scale=${PREVIEW_WIDTH}:-1`,
|
||||||
'-c:v',
|
'-c:v',
|
||||||
PREVIEW_CODEC === 'av1' ? 'libsvtav1' : 'libx264',
|
codec,
|
||||||
'-preset',
|
'-preset',
|
||||||
PRESET,
|
PRESET,
|
||||||
|
...extraCodecArgs,
|
||||||
'-g',
|
'-g',
|
||||||
String(gop),
|
String(gop),
|
||||||
'-keyint_min',
|
'-keyint_min',
|
||||||
@@ -120,9 +137,8 @@ function buildArgs(source) {
|
|||||||
`${bufsize}k`,
|
`${bufsize}k`,
|
||||||
'-pix_fmt',
|
'-pix_fmt',
|
||||||
'yuv420p',
|
'yuv420p',
|
||||||
'-f',
|
...outputArgs,
|
||||||
'mpegts',
|
outputUrl,
|
||||||
buildSrtPublishUrl(source.outputId),
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export default function DriverVideoPanel({layoutFormat = 'desktop'}) {
|
|||||||
return () => clearInterval(timer);
|
return () => clearInterval(timer);
|
||||||
}, [session?.mode]);
|
}, [session?.mode]);
|
||||||
const roverId = session?.assignment?.roverId;
|
const roverId = session?.assignment?.roverId;
|
||||||
const av1Supported = supportsAv1WebRtc();
|
|
||||||
const rosterEntry =
|
const rosterEntry =
|
||||||
roverId && session?.roster ? session.roster.find((item) => String(item.id) === String(roverId)) : null;
|
roverId && session?.roster ? session.roster.find((item) => String(item.id) === String(roverId)) : null;
|
||||||
const hasAudio = Boolean(rosterEntry?.media?.audioPublishUrl);
|
const hasAudio = Boolean(rosterEntry?.media?.audioPublishUrl);
|
||||||
@@ -71,6 +70,7 @@ export default function DriverVideoPanel({layoutFormat = 'desktop'}) {
|
|||||||
const sources = useVideoRequests(entries);
|
const sources = useVideoRequests(entries);
|
||||||
const info = roverId && shouldShowVideo ? sources[roverId] : null;
|
const info = roverId && shouldShowVideo ? sources[roverId] : null;
|
||||||
const audioInfo = roverId && hasAudio ? sources[`${roverId}-audio`] : null;
|
const audioInfo = roverId && hasAudio ? sources[`${roverId}-audio`] : null;
|
||||||
|
const av1Supported = supportsAv1WebRtc();
|
||||||
const previewEntries = roverId
|
const previewEntries = roverId
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ export default function RoomCameraPanel({
|
|||||||
feed={feed}
|
feed={feed}
|
||||||
label={camera.name || camera.id}
|
label={camera.name || camera.id}
|
||||||
videoSession={previewSession}
|
videoSession={previewSession}
|
||||||
preferVideo={av1Supported}
|
preferVideo={Boolean(previewSession?.url)}
|
||||||
/>
|
/>
|
||||||
</article>
|
</article>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -36,13 +36,13 @@ function MiniSummaryContent() {
|
|||||||
enabled: !inLockdown,
|
enabled: !inLockdown,
|
||||||
version: session?.mode,
|
version: session?.mode,
|
||||||
});
|
});
|
||||||
const av1Supported = supportsAv1WebRtc();
|
|
||||||
const [index, setIndex] = useState(0);
|
const [index, setIndex] = useState(0);
|
||||||
|
|
||||||
const snapshotFeeds = useRoverSnapshots(
|
const snapshotFeeds = useRoverSnapshots(
|
||||||
roster.map((rover) => rover.id),
|
roster.map((rover) => rover.id),
|
||||||
{ enabled: !inLockdown, version: session?.mode },
|
{ enabled: !inLockdown, version: session?.mode },
|
||||||
);
|
);
|
||||||
|
const av1Supported = supportsAv1WebRtc();
|
||||||
const previewEntries = roster.map((rover) => ({
|
const previewEntries = roster.map((rover) => ({
|
||||||
type: 'rover',
|
type: 'rover',
|
||||||
id: rover.id,
|
id: rover.id,
|
||||||
@@ -162,7 +162,12 @@ function MiniSummaryContent() {
|
|||||||
</FitViewportFrame>
|
</FitViewportFrame>
|
||||||
) : activeCamera ? (
|
) : activeCamera ? (
|
||||||
<FitViewportFrame>
|
<FitViewportFrame>
|
||||||
<RoomCameraFrame camera={activeCamera} feed={activeFeed} videoSession={activeRoomPreview} preferVideo={av1Supported} />
|
<RoomCameraFrame
|
||||||
|
camera={activeCamera}
|
||||||
|
feed={activeFeed}
|
||||||
|
videoSession={activeRoomPreview}
|
||||||
|
preferVideo={Boolean(activeRoomPreview?.url)}
|
||||||
|
/>
|
||||||
</FitViewportFrame>
|
</FitViewportFrame>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-full w-full items-center justify-center text-sm text-slate-500">
|
<div className="flex h-full w-full items-center justify-center text-sm text-slate-500">
|
||||||
|
|||||||
@@ -103,11 +103,11 @@ function SpectatorContent() {
|
|||||||
useSpectatorMode();
|
useSpectatorMode();
|
||||||
const frames = useTelemetryFrames();
|
const frames = useTelemetryFrames();
|
||||||
const roster = session?.roster ?? [];
|
const roster = session?.roster ?? [];
|
||||||
const av1Supported = supportsAv1WebRtc();
|
|
||||||
const snapshotFeeds = useRoverSnapshots(
|
const snapshotFeeds = useRoverSnapshots(
|
||||||
roster.map((rover) => rover.id),
|
roster.map((rover) => rover.id),
|
||||||
{ enabled: !inLockdown, version: session?.mode },
|
{ enabled: !inLockdown, version: session?.mode },
|
||||||
);
|
);
|
||||||
|
const av1Supported = supportsAv1WebRtc();
|
||||||
const previewEntries = roster.map((rover) => ({
|
const previewEntries = roster.map((rover) => ({
|
||||||
type: 'rover',
|
type: 'rover',
|
||||||
id: rover.id,
|
id: rover.id,
|
||||||
|
|||||||
Reference in New Issue
Block a user