File size: 1,463 Bytes
df3ef41 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 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;
|