Add camera switch button to live broadcast
- Add button to toggle front/back camera - Shows spinner while switching - Works before and during live stream 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
29e80a7f0e
commit
540f213014
|
|
@ -19,6 +19,8 @@ export default function LiveKitBroadcast({ coords, onClose, onStreamCreated }) {
|
||||||
const [localStream, setLocalStream] = useState(null);
|
const [localStream, setLocalStream] = useState(null);
|
||||||
const [showConfirm, setShowConfirm] = useState(false);
|
const [showConfirm, setShowConfirm] = useState(false);
|
||||||
const [livePostId, setLivePostId] = useState(null);
|
const [livePostId, setLivePostId] = useState(null);
|
||||||
|
const [facingMode, setFacingMode] = useState("user");
|
||||||
|
const [isSwitchingCamera, setIsSwitchingCamera] = useState(false);
|
||||||
const [liveCoords] = useState(() => {
|
const [liveCoords] = useState(() => {
|
||||||
if (coords && typeof coords === "object") {
|
if (coords && typeof coords === "object") {
|
||||||
if (Array.isArray(coords) && coords.length >= 2) {
|
if (Array.isArray(coords) && coords.length >= 2) {
|
||||||
|
|
@ -82,6 +84,42 @@ export default function LiveKitBroadcast({ coords, onClose, onStreamCreated }) {
|
||||||
}
|
}
|
||||||
}, [localStream]);
|
}, [localStream]);
|
||||||
|
|
||||||
|
// Switch between front and back camera
|
||||||
|
const switchCamera = useCallback(async () => {
|
||||||
|
if (isSwitchingCamera) return;
|
||||||
|
setIsSwitchingCamera(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const newFacingMode = facingMode === "user" ? "environment" : "user";
|
||||||
|
|
||||||
|
// Get new stream with switched camera
|
||||||
|
const newStream = await navigator.mediaDevices.getUserMedia({
|
||||||
|
video: { facingMode: newFacingMode, width: 1280, height: 720 },
|
||||||
|
audio: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Stop old tracks
|
||||||
|
if (localStream) {
|
||||||
|
localStream.getTracks().forEach((t) => t.stop());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update state
|
||||||
|
setLocalStream(newStream);
|
||||||
|
setFacingMode(newFacingMode);
|
||||||
|
|
||||||
|
// Update video element
|
||||||
|
if (videoRef.current) {
|
||||||
|
videoRef.current.srcObject = newStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("[LiveKit] Switched to", newFacingMode, "camera");
|
||||||
|
} catch (err) {
|
||||||
|
console.error("[LiveKit] Failed to switch camera:", err);
|
||||||
|
} finally {
|
||||||
|
setIsSwitchingCamera(false);
|
||||||
|
}
|
||||||
|
}, [facingMode, localStream, isSwitchingCamera]);
|
||||||
|
|
||||||
const handleGoLive = useCallback(async () => {
|
const handleGoLive = useCallback(async () => {
|
||||||
if (!authToken) {
|
if (!authToken) {
|
||||||
alert("Please log in to start a live stream.");
|
alert("Please log in to start a live stream.");
|
||||||
|
|
@ -269,6 +307,23 @@ export default function LiveKitBroadcast({ coords, onClose, onStreamCreated }) {
|
||||||
<span>LIVE on LiveKit</span>
|
<span>LIVE on LiveKit</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Camera controls overlay */}
|
||||||
|
<div className="sw-broadcast-controls-overlay">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="sw-broadcast-control-btn"
|
||||||
|
onClick={switchCamera}
|
||||||
|
disabled={isSwitchingCamera}
|
||||||
|
title={facingMode === "user" ? "Switch to back camera" : "Switch to front camera"}
|
||||||
|
>
|
||||||
|
{isSwitchingCamera ? (
|
||||||
|
<i className="fa-solid fa-spinner fa-spin" />
|
||||||
|
) : (
|
||||||
|
<i className="fa-solid fa-camera-rotate" />
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue