LeLab / src /components /control /CameraFeed.tsx
GitHub CI
Sync from leLab @ 39fcfee669f0b98e7a1fc4dde23025ea8cc7e5ce
df3ef41
Raw
History Blame Contribute Delete
1.46 kB
import React from "react";
import { VideoOff } from "lucide-react";
import { useCameraStream } from "@/hooks/useCameraStream";
interface CameraFeedProps {
/** Browser deviceId to stream. Empty string renders the "no camera" state. */
deviceId: string;
/** Optional caption shown under the feed. */
label?: string;
}
/** Live browser-camera feed bound to a deviceId via getUserMedia. */
const CameraFeed: React.FC<CameraFeedProps> = ({ deviceId, label }) => {
const { videoRef, hasError } = useCameraStream(deviceId, false);
const showVideo = deviceId && !hasError;
return (
<div className="bg-gray-900 rounded-lg border border-gray-700 overflow-hidden">
<div className="aspect-[4/3] bg-gray-800 relative">
{showVideo ? (
<video
ref={videoRef}
autoPlay
muted
playsInline
className="w-full h-full object-cover"
/>
) : (
<div className="w-full h-full flex flex-col items-center justify-center">
<VideoOff className="w-8 h-8 text-gray-500 mb-2" />
<span className="text-gray-500 text-sm">
{deviceId ? "Preview failed" : "No camera selected"}
</span>
</div>
)}
</div>
{label && (
<div className="p-2 text-sm text-gray-300 truncate border-t border-gray-800">
{label}
</div>
)}
</div>
);
};
export default CameraFeed;