show settings menu for non-restreamed cameras

This commit is contained in:
Josh Hawkins 2024-12-28 07:38:48 -06:00
parent af039f349d
commit 459283c60f

View File

@ -1031,66 +1031,108 @@ function FrigateCameraFeatures({
title={`${isRecording ? "Stop" : "Start"} on-demand recording`} title={`${isRecording ? "Stop" : "Start"} on-demand recording`}
onClick={handleEventButtonClick} onClick={handleEventButtonClick}
/> />
{isRestreamed && (
<DropdownMenu modal={false}> <DropdownMenu modal={false}>
<DropdownMenuTrigger> <DropdownMenuTrigger>
<div <div
className={cn( className={cn(
"flex flex-col items-center justify-center rounded-lg bg-secondary p-2 text-secondary-foreground md:p-0", "flex flex-col items-center justify-center rounded-lg bg-secondary p-2 text-secondary-foreground md:p-0",
)} )}
> >
<LuCog <LuCog
className={`text-secondary-foreground" size-5 md:m-[6px]`} className={`text-secondary-foreground" size-5 md:m-[6px]`}
/> />
</div> </div>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent className="max-w-96"> <DropdownMenuContent className="max-w-96">
<div className="flex flex-col gap-5 p-4"> <div className="flex flex-col gap-5 p-4">
{Object.values(camera.live.streams).length > 1 && ( {Object.values(camera.live.streams).length > 1 && (
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<Label htmlFor="streaming-method" className=""> <Label htmlFor="streaming-method" className="">
Stream Stream
</Label> </Label>
<Select <Select
value={streamName} value={streamName}
onValueChange={(value) => { onValueChange={(value) => {
setStreamName?.(value); setStreamName?.(value);
}} }}
> >
<SelectTrigger className="w-full"> <SelectTrigger className="w-full">
{Object.keys(camera.live.streams).find( {Object.keys(camera.live.streams).find(
(key) => camera.live.streams[key] === streamName, (key) => camera.live.streams[key] === streamName,
)}
</SelectTrigger>
<SelectContent>
<SelectGroup>
{Object.entries(camera.live.streams).map(
([stream, name]) => (
<SelectItem
key={stream}
className="cursor-pointer"
value={name}
>
{stream}
</SelectItem>
),
)} )}
</SelectTrigger> </SelectGroup>
</SelectContent>
</Select>
<SelectContent> {preferredLiveMode != "jsmpeg" && isRestreamed && (
<SelectGroup> <div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
{Object.entries(camera.live.streams).map( {supportsAudioOutput ? (
([stream, name]) => ( <>
<SelectItem <LuCheck className="size-4 text-success" />
key={stream} <div>Audio is available for this stream</div>
className="cursor-pointer" </>
value={name} ) : (
> <>
{stream} <LuX className="size-4 text-danger" />
</SelectItem> <div>Audio is unavailable for this stream</div>
), <Popover>
)} <PopoverTrigger asChild>
</SelectGroup> <div className="cursor-pointer p-0">
</SelectContent> <LuInfo className="size-4" />
</Select> <span className="sr-only">Info</span>
</div>
{preferredLiveMode != "jsmpeg" && isRestreamed && ( </PopoverTrigger>
<PopoverContent className="w-80 text-xs">
Audio must be output from your camera and
configured in go2rtc for this stream.
<div className="mt-2 flex items-center text-primary">
<Link
to="https://docs.frigate.video/configuration/live"
target="_blank"
rel="noopener noreferrer"
className="inline"
>
Read the documentation{" "}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div>
)}
{preferredLiveMode != "jsmpeg" &&
isRestreamed &&
supportsAudioOutput && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground"> <div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
{supportsAudioOutput ? ( {supports2WayTalk ? (
<> <>
<LuCheck className="size-4 text-success" /> <LuCheck className="size-4 text-success" />
<div>Audio is available for this stream</div> <div>Two-way talk is available for this stream</div>
</> </>
) : ( ) : (
<> <>
<LuX className="size-4 text-danger" /> <LuX className="size-4 text-danger" />
<div>Audio is unavailable for this stream</div> <div>
Two-way talk is unavailable for this stream
</div>
<Popover> <Popover>
<PopoverTrigger asChild> <PopoverTrigger asChild>
<div className="cursor-pointer p-0"> <div className="cursor-pointer p-0">
@ -1099,11 +1141,11 @@ function FrigateCameraFeatures({
</div> </div>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="w-80 text-xs"> <PopoverContent className="w-80 text-xs">
Audio must be output from your camera and Your device must suppport the feature and WebRTC
configured in go2rtc for this stream. must be configured for two-way talk.
<div className="mt-2 flex items-center text-primary"> <div className="mt-2 flex items-center text-primary">
<Link <Link
to="https://docs.frigate.video/configuration/live" to="https://docs.frigate.video/configuration/live/#webrtc-extra-configuration"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
className="inline" className="inline"
@ -1118,136 +1160,89 @@ function FrigateCameraFeatures({
)} )}
</div> </div>
)} )}
{preferredLiveMode != "jsmpeg" &&
isRestreamed &&
supportsAudioOutput && (
<div className="flex flex-row items-center gap-1 text-sm text-muted-foreground">
{supports2WayTalk ? (
<>
<LuCheck className="size-4 text-success" />
<div>
Two-way talk is available for this stream
</div>
</>
) : (
<>
<LuX className="size-4 text-danger" />
<div>
Two-way talk is unavailable for this stream
</div>
<Popover>
<PopoverTrigger asChild>
<div className="cursor-pointer p-0">
<LuInfo className="size-4" />
<span className="sr-only">Info</span>
</div>
</PopoverTrigger>
<PopoverContent className="w-80 text-xs">
Your device must suppport the feature and
WebRTC must be configured for two-way talk.
<div className="mt-2 flex items-center text-primary">
<Link
to="https://docs.frigate.video/configuration/live/#webrtc-extra-configuration"
target="_blank"
rel="noopener noreferrer"
className="inline"
>
Read the documentation{" "}
<LuExternalLink className="ml-2 inline-flex size-3" />
</Link>
</div>
</PopoverContent>
</Popover>
</>
)}
</div>
)}
{preferredLiveMode == "jsmpeg" && isRestreamed && ( {preferredLiveMode == "jsmpeg" && isRestreamed && (
<div className="flex flex-col items-center gap-3"> <div className="flex flex-col items-center gap-3">
<div className="flex flex-row items-center gap-2"> <div className="flex flex-row items-center gap-2">
<IoIosWarning className="mr-1 size-8 text-danger" /> <IoIosWarning className="mr-1 size-8 text-danger" />
<p className="text-sm"> <p className="text-sm">
Live view is in low-bandwidth mode due to buffering Live view is in low-bandwidth mode due to buffering or
or stream errors. stream errors.
</p> </p>
</div>
<Button
className={`flex items-center gap-2.5 rounded-lg`}
aria-label="Reset the stream"
variant="outline"
size="sm"
onClick={() => setLowBandwidth(false)}
>
<MdOutlineRestartAlt className="size-5 text-primary-variant" />
<div className="text-primary-variant">
Reset stream
</div>
</Button>
</div> </div>
)} <Button
</div> className={`flex items-center gap-2.5 rounded-lg`}
)} aria-label="Reset the stream"
{isRestreamed && ( variant="outline"
<div className="flex flex-col gap-1"> size="sm"
<div className="flex items-center justify-between"> onClick={() => setLowBandwidth(false)}
<Label
className="mx-0 cursor-pointer text-primary"
htmlFor="backgroundplay"
> >
Play in background <MdOutlineRestartAlt className="size-5 text-primary-variant" />
</Label> <div className="text-primary-variant">Reset stream</div>
<Switch </Button>
className="ml-1"
id="backgroundplay"
checked={playInBackground}
onCheckedChange={(checked) =>
setPlayInBackground(checked)
}
/>
</div> </div>
<p className="text-sm text-muted-foreground"> )}
Enable this option to continue streaming when the player </div>
is hidden. )}
</p> {isRestreamed && (
</div>
)}
<div className="flex flex-col gap-1"> <div className="flex flex-col gap-1">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<Label <Label
className="mx-0 cursor-pointer text-primary" className="mx-0 cursor-pointer text-primary"
htmlFor="showstats" htmlFor="backgroundplay"
> >
Show stream stats Play in background
</Label> </Label>
<Switch <Switch
className="ml-1" className="ml-1"
id="showstats" id="backgroundplay"
checked={showStats} checked={playInBackground}
onCheckedChange={(checked) => setShowStats(checked)} onCheckedChange={(checked) =>
setPlayInBackground(checked)
}
/> />
</div> </div>
<p className="text-sm text-muted-foreground"> <p className="text-sm text-muted-foreground">
Enable this option to show stream statistics as an overlay Enable this option to continue streaming when the player is
on the camera feed. hidden.
</p> </p>
</div> </div>
<div className="flex flex-col gap-1"> )}
<div className="flex items-center justify-between text-sm font-medium leading-none"> <div className="flex flex-col gap-1">
Debug View <div className="flex items-center justify-between">
<LuExternalLink <Label
onClick={() => className="mx-0 cursor-pointer text-primary"
navigate(`/settings?page=debug&camera=${camera.name}`) htmlFor="showstats"
} >
className="ml-2 inline-flex size-5 cursor-pointer" Show stream stats
/> </Label>
</div> <Switch
className="ml-1"
id="showstats"
checked={showStats}
onCheckedChange={(checked) => setShowStats(checked)}
/>
</div>
<p className="text-sm text-muted-foreground">
Enable this option to show stream statistics as an overlay on
the camera feed.
</p>
</div>
<div className="flex flex-col gap-1">
<div className="flex items-center justify-between text-sm font-medium leading-none">
Debug View
<LuExternalLink
onClick={() =>
navigate(`/settings?page=debug&camera=${camera.name}`)
}
className="ml-2 inline-flex size-5 cursor-pointer"
/>
</div> </div>
</div> </div>
</DropdownMenuContent> </div>
</DropdownMenu> </DropdownMenuContent>
)} </DropdownMenu>
</> </>
); );
} }