add ability to continue playing stream in background

This commit is contained in:
Josh Hawkins 2024-12-20 09:42:55 -06:00
parent 9aa81f3e08
commit 1309cb0d7f
3 changed files with 46 additions and 3 deletions

View File

@ -32,6 +32,7 @@ type LivePlayerProps = {
useWebGL: boolean;
windowVisible?: boolean;
playAudio?: boolean;
playInBackground: boolean;
micEnabled?: boolean; // only webrtc supports mic
iOSCompatFullScreen?: boolean;
pip?: boolean;
@ -53,6 +54,7 @@ export default function LivePlayer({
useWebGL = false,
windowVisible = true,
playAudio = false,
playInBackground = false,
micEnabled = false,
iOSCompatFullScreen = false,
pip,
@ -202,6 +204,7 @@ export default function LivePlayer({
camera={streamName}
playbackEnabled={cameraActive || liveReady}
audioEnabled={playAudio}
playInBackground={playInBackground}
onPlaying={playerIsPlaying}
pip={pip}
setFullResolution={setFullResolution}

View File

@ -15,6 +15,7 @@ type MSEPlayerProps = {
className?: string;
playbackEnabled?: boolean;
audioEnabled?: boolean;
playInBackground?: boolean;
pip?: boolean;
onPlaying?: () => void;
setFullResolution?: React.Dispatch<SetStateAction<VideoResolutionType>>;
@ -26,6 +27,7 @@ function MSEPlayer({
className,
playbackEnabled = true,
audioEnabled = false,
playInBackground = false,
pip = false,
onPlaying,
setFullResolution,
@ -508,12 +510,22 @@ function MSEPlayer({
}
};
document.addEventListener("visibilitychange", listener);
if (!playInBackground) {
document.addEventListener("visibilitychange", listener);
}
return () => {
document.removeEventListener("visibilitychange", listener);
if (!playInBackground) {
document.removeEventListener("visibilitychange", listener);
}
};
}, [playbackEnabled, visibilityCheck, onConnect, onDisconnect]);
}, [
playbackEnabled,
visibilityCheck,
playInBackground,
onConnect,
onDisconnect,
]);
// control pip

View File

@ -55,6 +55,7 @@ import {
FaMicrophone,
FaMicrophoneSlash,
} from "react-icons/fa";
import { CiStreamOff, CiStreamOn } from "react-icons/ci";
import { GiSpeaker, GiSpeakerOff } from "react-icons/gi";
import { TbViewfinder, TbViewfinderOff } from "react-icons/tb";
import { IoIosWarning, IoMdArrowRoundBack } from "react-icons/io";
@ -220,6 +221,11 @@ export default function LiveCameraView({
const [pip, setPip] = useState(false);
const [lowBandwidth, setLowBandwidth] = useState(false);
const [playInBackground, setPlayInBackground] = usePersistence<boolean>(
`${camera.name}-background-play`,
false,
);
const [fullResolution, setFullResolution] = useState<VideoResolutionType>({
width: 0,
height: 0,
@ -481,6 +487,8 @@ export default function LiveCameraView({
streamName={streamName ?? ""}
setStreamName={setStreamName}
preferredLiveMode={preferredLiveMode}
playInBackground={playInBackground ?? false}
setPlayInBackground={setPlayInBackground}
/>
</div>
</TooltipProvider>
@ -513,6 +521,7 @@ export default function LiveCameraView({
showStillWithoutActivity={false}
cameraConfig={camera}
playAudio={audio}
playInBackground={playInBackground ?? false}
micEnabled={mic}
iOSCompatFullScreen={isIOS}
preferredLiveMode={preferredLiveMode}
@ -779,6 +788,8 @@ type FrigateCameraFeaturesProps = {
streamName: string;
setStreamName?: (value: string | undefined) => void;
preferredLiveMode: string;
playInBackground: boolean;
setPlayInBackground: (value: boolean | undefined) => void;
};
function FrigateCameraFeatures({
camera,
@ -789,6 +800,8 @@ function FrigateCameraFeatures({
streamName,
setStreamName,
preferredLiveMode,
playInBackground,
setPlayInBackground,
}: FrigateCameraFeaturesProps) {
const { payload: detectState, send: sendDetect } = useDetectState(
camera.name,
@ -853,6 +866,14 @@ function FrigateCameraFeatures({
}
/>
)}
<CameraFeatureToggle
className="p-2 md:p-0"
variant={fullscreen ? "overlay" : "primary"}
Icon={playInBackground ? CiStreamOn : CiStreamOff}
isActive={playInBackground ?? false}
title={`${playInBackground ? "Disable" : "Enable"} Background Playback`}
onClick={() => setPlayInBackground(!playInBackground)}
/>
{Object.values(camera.live.streams).length > 1 && (
<Select
value={streamName}
@ -952,6 +973,13 @@ function FrigateCameraFeatures({
}
/>
)}
<FilterSwitch
label="Play in Background"
isChecked={playInBackground}
onCheckedChange={(checked) => {
setPlayInBackground(checked);
}}
/>
{Object.values(camera.live.streams).length > 1 && (
<div className="mt-1 p-2">
<div className="mb-1 text-sm">Live stream selection</div>