Skip to content

Commit b8f5f55

Browse files
author
richardson
committed
feat: 改进视频流组件和构建流程
- 优化摄像头控制和视频显示组件的性能和用户体验 - 更新 GitHub Actions 工作流以支持不同 macOS 版本的构建 - 添加对 macOS Big Sur 和更早版本的兼容性支持 - 改进错误处理和权限管理机制
1 parent 3f9f635 commit b8f5f55

File tree

4 files changed

+45
-21
lines changed

4 files changed

+45
-21
lines changed

.github/workflows/build-and-release.yml

+3-3
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ jobs:
8282

8383
- name: 构建 Tauri 应用 (现代 macOS)
8484
if: matrix.target == 'macos-modern'
85-
uses: tauri-apps/tauri-action@v1.4.3
85+
uses: tauri-apps/tauri-action@v0
8686
env:
8787
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
8888
with:
@@ -91,7 +91,7 @@ jobs:
9191

9292
- name: 构建 Tauri 应用 (Big Sur)
9393
if: matrix.target == 'macos-bigsur'
94-
uses: tauri-apps/tauri-action@v1.4.3
94+
uses: tauri-apps/tauri-action@v0
9595
env:
9696
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
9797
with:
@@ -110,7 +110,7 @@ jobs:
110110
111111
- name: 构建 Tauri 应用 (Windows)
112112
if: matrix.target == 'windows'
113-
uses: tauri-apps/tauri-action@v1.4.3
113+
uses: tauri-apps/tauri-action@v0
114114
env:
115115
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
116116

src/components/VideoFeed/CameraControls.tsx

+16-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ interface CameraControlsProps {
1313
onCameraSelect: (deviceId: string) => void;
1414
onToggleCamera: (active: boolean) => void;
1515
onRefresh: () => void;
16+
isLocked: boolean;
17+
onLockChange?: (locked: boolean) => void;
1618
}
1719

1820
const CameraControls: React.FC<CameraControlsProps> = ({
@@ -22,7 +24,9 @@ const CameraControls: React.FC<CameraControlsProps> = ({
2224
isCameraActive,
2325
onCameraSelect,
2426
onToggleCamera,
25-
onRefresh
27+
onRefresh,
28+
isLocked,
29+
onLockChange
2630
}) => {
2731
return (
2832
<div className="mb-4 flex items-center justify-between flex-wrap gap-4">
@@ -45,6 +49,17 @@ const CameraControls: React.FC<CameraControlsProps> = ({
4549
{isCameraActive ? '关闭摄像头' : '开启摄像头'}
4650
</span>
4751
</div>
52+
53+
<div className="flex items-center space-x-2">
54+
<Switch
55+
checked={isLocked}
56+
onCheckedChange={onLockChange}
57+
disabled={!isCameraActive}
58+
/>
59+
<span className="text-sm font-medium">
60+
{isLocked ? '锁定位置' : '跟踪模式'}
61+
</span>
62+
</div>
4863
</div>
4964

5065
<Button

src/components/VideoFeed/VideoDisplay.tsx

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface VideoDisplayProps {
1313
// 添加舵机位置的状态
1414
currentServoX?: number;
1515
currentServoY?: number;
16+
isLocked: boolean;
1617
}
1718

1819
const VideoDisplay: React.FC<VideoDisplayProps> = ({
@@ -24,7 +25,8 @@ const VideoDisplay: React.FC<VideoDisplayProps> = ({
2425
currentResult,
2526
currentServoX = 90,
2627
currentServoY = 90,
27-
debug = false
28+
debug = false,
29+
isLocked
2830
}) => {
2931
const drawRef = useRef<number>();
3032
const lastDrawnPosition = useRef<{x: number, y: number} | null>(null);
@@ -89,7 +91,7 @@ const VideoDisplay: React.FC<VideoDisplayProps> = ({
8991
const statusText = [
9092
`Servo X: ${currentServoX.toFixed(1)}°`,
9193
`Servo Y: ${currentServoY.toFixed(1)}°`,
92-
`Status: ${detectionActive ? 'Tracking' : 'Searching'}`,
94+
`Status: ${isLocked ? 'Locked' : (detectionActive ? 'Tracking' : 'Searching')}`,
9395
...(detectionActive && currentResult ? [
9496
`Confidence: ${(currentResult.confidence * 100).toFixed(1)}%`,
9597
`Size: ${currentResult.size.width.toFixed(0)}x${currentResult.size.height.toFixed(0)}`
@@ -164,7 +166,7 @@ const VideoDisplay: React.FC<VideoDisplayProps> = ({
164166
cancelAnimationFrame(drawRef.current);
165167
}
166168
};
167-
}, [canvasRef, currentResult, isActive, debug, currentServoX, currentServoY]);
169+
}, [canvasRef, currentResult, isActive, debug, currentServoX, currentServoY, isLocked]);
168170

169171
return (
170172
<div className="relative w-full h-[360px] bg-gray-900 rounded-lg overflow-hidden">

src/components/VideoFeed/index.tsx

+21-14
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,19 @@ interface VideoFeedProps {
1515
debug?: boolean;
1616
currentServoX?: number;
1717
currentServoY?: number;
18+
isLocked?: boolean;
19+
onLockChange?: (locked: boolean) => void;
1820
}
1921

20-
const VideoFeed: React.FC<VideoFeedProps> = ({ onFaceDetected, debug = false, currentServoX = 90, currentServoY = 90 }) => {
22+
const VideoFeed: React.FC<VideoFeedProps> = ({ onFaceDetected, debug = false, currentServoX = 90, currentServoY = 90, isLocked = true, onLockChange }) => {
2123
const [currentResult, setCurrentResult] = useState<FaceDetectionResult | null>(null);
2224

2325
const handleFaceDetected = useCallback((result: FaceDetectionResult, size: { width: number, height: number }) => {
2426
setCurrentResult(result);
25-
onFaceDetected(result, size);
26-
}, [onFaceDetected]);
27+
if (!isLocked) {
28+
onFaceDetected(result, size);
29+
}
30+
}, [onFaceDetected, isLocked]);
2731

2832
const {
2933
isCameraActive,
@@ -78,19 +82,22 @@ const VideoFeed: React.FC<VideoFeedProps> = ({ onFaceDetected, debug = false, cu
7882
onCameraSelect={handleCameraSelect}
7983
onToggleCamera={toggleCamera}
8084
onRefresh={fetchCameras}
85+
isLocked={isLocked}
86+
onLockChange={onLockChange}
8187
/>
8288

83-
<VideoDisplay
84-
videoRef={videoRef}
85-
canvasRef={canvasRef}
86-
isActive={isCameraActive}
87-
isLoading={isLoading}
88-
hasCameras={cameras.length > 0}
89-
currentResult={currentResult}
90-
currentServoX={currentServoX} // 从props传入
91-
currentServoY={currentServoY} // 从props传入
92-
debug={debug}
93-
/>
89+
<VideoDisplay
90+
videoRef={videoRef}
91+
canvasRef={canvasRef}
92+
isActive={isCameraActive}
93+
isLoading={isLoading}
94+
hasCameras={cameras.length > 0}
95+
currentResult={currentResult}
96+
currentServoX={currentServoX}
97+
currentServoY={currentServoY}
98+
debug={debug}
99+
isLocked={isLocked}
100+
/>
94101

95102
{debug && streamInfo && (
96103
<div className="mt-2 text-sm text-gray-500">

0 commit comments

Comments
 (0)