航线面板视频显示 算法分析调用服务器案例

This commit is contained in:
mmc
2026-05-22 13:50:50 +08:00
parent 18e0143f70
commit e642ecbd16
4 changed files with 4303 additions and 23 deletions

View File

@@ -54,3 +54,18 @@ export function submitSegmentationAnalyze(formData: FormData) {
export function getSegmentationHistory() {
return fetch(`${SEGMENT_BASE}/api/v1/segmentation/analyses/report`).then(res => res.json());
}
//热成像调用服务器案例
export function getHotDemo() {
return fetch(`${SEGMENT_BASE}/demo/run`, {
method: 'POST',
}).then(res => res.json());
}
//目标检测 调用服务器案例
export function getTargetDemo() {
return fetch(`${DETECT_BASE}/demo/run`, {
method: 'POST',
}).then(res => res.json());
}

View File

@@ -20,6 +20,8 @@ import { getDeviceListApi, getLiveStream, getPlaneDeviceList } from '../../api/d
import { RootState } from '@/src/store';
import DroneLivePlayer from '../VolcRtcPlayer.jsx';
import AgoraTextTest from '../AgoraRtc.tsx';
import { useWebRTCPlayer } from '../useWebRTCStream.tsx';
import VideoPlayer from '../VideoPlayer.tsx.tsx';
const { Content } = Layout;
const { Text, Title } = Typography;
@@ -123,6 +125,15 @@ export default function DeviceOverviewPage({ devices, planedevices, devicesAll,
}));
}, [devicesAll]);
const [mowerView, setMowerView] = useState('front');
const isUAV = !!selectedDevice?.device_sn;
// 机器人 WebRTC 视频(和你第二个页面逻辑一致)
const { video: robotVideo, error, ready } = useWebRTCPlayer(
selectedDevice?.serialNumber || '',
`webrtc://1.95.137.212/live/livestream/${selectedDevice?.serialNumber}`,
);
const handleStart = () => message.success('任务已启动');
const handlePause = () => message.info('任务已暂停');
@@ -414,29 +425,67 @@ export default function DeviceOverviewPage({ devices, planedevices, devicesAll,
</Col>
<Col span={12}>
{/* 实时画面 */}
<div style={{ marginBottom: 8 }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
<span style={{ fontSize: 14, fontWeight: 500, color: "#666" }}>实时画面</span>
<span style={{ fontSize: 13, color: '#999' }}>实时监控</span>
{/* 角度选择下拉框 */}
{!isUAV && (
<Select
size="small"
style={{ width: 110 }}
value={mowerView}
onChange={setMowerView}
options={[
{ label: '前视', value: 'front' },
{ label: '后视', value: 'back' },
{ label: '左视', value: 'left' },
{ label: '右视', value: 'right' },
]}
/>
)}
</div>
<div style={{ width: '100%', height: 160, borderRadius: 8, position: 'relative', overflow: 'hidden', background: '#000' }}>
{/* 无人机视频 + 时间:有数据才显示,否则空 div */}
{planeVideo?.[0] ? (
<>
<DroneLivePlayer streamData={planeVideo[0]}
/>
</>
<div style={{ width: '100%', height: 160, borderRadius: 8, position: 'relative', overflow: 'hidden', background: '#000' }}>
{/* 无人机视频 */}
{isUAV ? (
planeVideo?.length > 0 ? (
<DroneLivePlayer streamData={planeVideo[0]} />
) : (
<div style={{ color: '#ccc', display: 'flex', height: '100%', alignItems: 'center', justifyContent: 'center' }}>
暂无视频流
</div>
)
) : (
<div></div>
)} {selectedDevice.device_sn && (
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, background: 'rgba(0,0,0,0.6)', color: '#fff', display: 'flex', justifyContent: 'space-between', padding: '8px 12px', fontSize: 14 }}>
// 机器人单画面 + 角度切换
robotVideo ? (
<VideoPlayer
deviceId={selectedDevice?.device_sn || selectedDevice?.serialNumber}
idx={
mowerView === 'front' ? 1
: mowerView === 'back' ? 2
: mowerView === 'left' ? 3
: 4
}
className="w-full h-full object-contain"
video={robotVideo}
error={error}
ready={ready}
/>
) : (
<div style={{ color: '#ccc', display: 'flex', height: '100%', alignItems: 'center', justifyContent: 'center' }}>
视频加载中...
</div>
)
)}
{/* 视频底部信息条 */}
{selectedDevice?.device_sn && (
<div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, background: 'rgba(0,0,0,0.6)', color: '#fff', display: 'flex', justifyContent: 'space-between', padding: '8px 12px', fontSize: 12 }}>
<span>高度 {fix2(selectedDevice.height)}m</span>
<span>风速 {fix2(selectedDevice.wind_speed)}m/s</span>
</div>
)}
</div>
</div>

View File

@@ -47,8 +47,8 @@ export function useWebRTCPlayer(deviceId: string, url: string) {
v.style.height = '100%';
v.style.objectFit = 'contain';
videoRef.current = v;
//const token = "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjY0MDVjNDgwLTAxNDYtNDAwNS1iY2RiLTFhMTM2YzlmYmFiMCJ9.V1GQiLr0xgu9LB59pGyYPFeVJfKwDsUtTacFrQDpXdEvD81uOkJO304tROF5Ewev6eXkZFuunUAEiMLWEfh2_w"
const token = localStorage.getItem('videotoken') || JSON.parse(localStorage.getItem('userInfo') || '{}')?.token;
const token = "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6IjY0MDVjNDgwLTAxNDYtNDAwNS1iY2RiLTFhMTM2YzlmYmFiMCJ9.V1GQiLr0xgu9LB59pGyYPFeVJfKwDsUtTacFrQDpXdEvD81uOkJO304tROF5Ewev6eXkZFuunUAEiMLWEfh2_w"
//const token = localStorage.getItem('videotoken') || JSON.parse(localStorage.getItem('userInfo') || '{}')?.token;
const videoUrl = `${url}?token=${token}`;
try {

File diff suppressed because it is too large Load Diff