视频成功 原因 token原因

This commit is contained in:
mmc
2026-05-22 08:03:30 +08:00
parent 2fcc5a13ea
commit 021d3cf384
6 changed files with 108 additions and 40 deletions

2
env.js
View File

@@ -14,7 +14,7 @@ const envConfig = {
WS_URL: 'ws://192.168.2.59:9002/ws/',
},
[ENV.PROD]: {
// baseURL: 'http://192.168.2.56:8081',
//baseURL: 'https://pvcloudservice.satabot.com',
baseURL: 'http://1.95.137.212:59015',//http://192.168.2.56:8081
//baseURL: 'https://serviceri.satabot.com',
WS_URL: 'ws://1.95.137.212:59017/ws/'

View File

@@ -21,6 +21,8 @@
<link rel="stylesheet"
href="https://lf-unpkg.volccdn.com/obj/vcloudfe/sdk/@volcengine/veplayer/2.11.2/umd/veplayer.production.css"
media="print" onload="this.media='all'">
<script src="/js/jswebrtc.min.js"></script>
<script src="/js/jswebrtcnew.js"></script>
</head>
<body>
@@ -44,8 +46,8 @@
// 按顺序加载
Promise.resolve()
.then(() => loadScript('/js/jswebrtc.min.js'))
.then(() => loadScript('/js/jswebrtcnew.js'))
//.then(() => loadScript('/js/jswebrtc.min.js'))
//.then(() => loadScript('/js/jswebrtcnew.js'))
.then(() => loadScript('https://unpkg.com/leaflet@1.9.4/dist/leaflet.js'))
.then(() => loadScript('https://cdn.jsdelivr.net/npm/cesium@latest/Build/Cesium/Cesium.js'))
.then(() => loadScript('https://cdn.jsdelivr.net/npm/hls.js@1.5.8/dist/hls.min.js'))

View File

@@ -107,7 +107,7 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices =
id,
position: window.Cesium.Cartesian3.fromDegrees(p.lon, p.lat),
point: {
color: window.Cesium.Color.SKYBLUE,
color: window.Cesium?.Color.SKYBLUE,
pixelSize: 10,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
},
@@ -115,7 +115,7 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices =
text: `${i + 1}`,
font: '12px sans-serif',
pixelOffset: new window.Cesium.Cartesian2(0, -15),
fillColor: window.Cesium.Color.WHITE
fillColor: window.Cesium?.Color.WHITE
}
});
pointEntitiesRef.current.push(id);
@@ -133,7 +133,7 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices =
polyline: {
positions: positions,
width: 4,
material: window.Cesium.Color.SKYBLUE,
material: window.Cesium?.Color.SKYBLUE,
clampToGround: true,
}
});
@@ -202,9 +202,9 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices =
positions: positions,
width: 3,
material: new Cesium.PolylineDashMaterialProperty({
color: Cesium.Color.BLUE,
color: Cesium?.Color.BLUE,
dashLength: 16,
gapColor: Cesium.Color.TRANSPARENT,
gapColor: Cesium?.Color.TRANSPARENT,
}),
clampToGround: true,
disableDepthTestDistance: Number.POSITIVE_INFINITY,
@@ -656,9 +656,9 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices =
text: robot.name,
font: "14px sans-serif",
pixelOffset: new window.Cesium.Cartesian2(0, -40),
fillColor: window.Cesium.Color.WHITE,
fillColor: window.Cesium?.Color.WHITE,
showBackground: true,
backgroundColor: window.Cesium.Color.BLACK.withAlpha(0.6)
backgroundColor: window.Cesium?.Color.BLACK.withAlpha(0.6)
}
});
entity.robotData = robot;
@@ -685,7 +685,7 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices =
})
});
viewerRef.current = viewer;
viewer.scene.globe.baseColor = window.Cesium.Color.BLACK;
viewer.scene.globe.baseColor = window.Cesium?.Color.BLACK;
viewer.scene.globe.depthTestAgainstTerrain = false;
viewer.scene.requestRenderMode = true; // 👈 加这个(只在需要时渲染)
viewer.scene.globe.enableLighting = false;
@@ -854,9 +854,9 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices =
text: device.name || "",
font: "12px sans-serif",
pixelOffset: new Cesium.Cartesian2(0, -40),
fillColor: Cesium.Color.WHITE,
fillColor: Cesium?.Color.WHITE,
showBackground: true,
backgroundColor: Cesium.Color.BLACK.withAlpha(0.6)
backgroundColor: Cesium?.Color.BLACK.withAlpha(0.6)
},
properties: {
@@ -1259,7 +1259,7 @@ export default function CesiumMap({ realtimePosition, pathPoints = [], devices =
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.25,
color: Cesium.Color.LIME
color: Cesium?.Color.LIME
}),
clampToGround: true,

View File

@@ -151,13 +151,13 @@ const VideoCanvas: React.FC<Props> = ({ video, idx, title, className, noCrop })
/>
<div className="absolute inset-0 pointer-events-none">
<div className="absolute top-5 left-12 px-2 py-0.5 bg-black/60 rounded text-[10px] text-cyan-400">
{/*<div className="absolute top-5 left-12 px-2 py-0.5 bg-black/60 rounded text-[10px] text-cyan-400">
{title}
</div>
<div className="absolute top-5 right-12 text-cyan-400 text-[8px] flex items-center gap-1">
</div>*/}
{/*<div className="absolute top-5 right-12 text-cyan-400 text-[8px] flex items-center gap-1">
<span className="w-1.5 h-1.5 rounded-full bg-cyan-400 animate-pulse" />
LIVE
</div>
</div>*/}
</div>
</div>
);

View File

@@ -42,6 +42,9 @@ import { RootState } from '@/src/store/index.ts';
import { useWebRTCPlayer } from '../useWebRTCStream.tsx';
import VideoPlayer from '../VideoPlayer.tsx';
import DeviceController from './DeviceController';
import { DatePicker } from 'antd';
import dayjs from 'dayjs';
const { RangePicker } = DatePicker;
const { Text } = Typography;
@@ -62,6 +65,13 @@ export default function DeviceStatusPage({
const [connecting, setConnecting] = useState(false);
const [wsStatus, setWsStatus] = useState('disconnected');
const [wsDeviceInfo, setWsDeviceInfo] = useState({});
const [selectedDrone, setSelectedDrone] = useState(null);
const [taskList, setTaskList] = useState([]);
// 👇 加上这两个
const [queryTimeRange, setQueryTimeRange] = useState([]); // 时间范围
const [startTimestamp, setStartTimestamp] = useState(''); // 开始时间戳
const [endTimestamp, setEndTimestamp] = useState(''); // 结束时间戳
const [isModalOpen, setIsModalOpen] = useState(false);
const [modalContent, setModalContent] = useState({
@@ -303,7 +313,7 @@ export default function DeviceStatusPage({
<Button type={mowerView === 'back' ? 'primary' : 'default'} onClick={() => setMowerView('back')}>后视</Button>
<Button type={mowerView === 'left' ? 'primary' : 'default'} onClick={() => setMowerView('left')}>左视</Button>
<Button type={mowerView === 'right' ? 'primary' : 'default'} onClick={() => setMowerView('right')}>右视</Button>
<Button type={mowerView === 'top' ? 'primary' : 'default'} onClick={() => setMowerView('top')}>顶视</Button>
{/*<Button type={mowerView === 'top' ? 'primary' : 'default'} onClick={() => setMowerView('top')}>顶视</Button>*/}
<Button type={mowerView === 'all' ? 'primary' : 'default'} onClick={() => setMowerView('all')}>全景</Button>
</Space>
)}
@@ -311,10 +321,10 @@ export default function DeviceStatusPage({
<div
style={{
height: 450,
background: '#000',
borderRadius: 8,
overflow: 'hidden',
display: 'flex',
flexWrap: 'wrap', // 允许换行
}}
>
{isUAV ? (
@@ -325,11 +335,10 @@ export default function DeviceStatusPage({
style={{
position: 'relative',
flex: 1,
height: '100%',
}}
>
<DroneLivePlayer streamData={s} />
</div>
))
) : (
@@ -338,22 +347,79 @@ export default function DeviceStatusPage({
</div>
)
) : robotVideo ? (
<VideoPlayer
deviceId={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}
/>
// 全景模式 = 4 分屏
mowerView === 'all' ? (
<div style={{
display: 'grid',
gridTemplateColumns: '1fr 1fr',
width: '100%',
height: '100%'
}}>
{/* 前 */}
<div style={{ position: 'relative', border: '1px solid #222' }}>
<VideoPlayer
deviceId={serialNumber}
idx={1}
className="w-full h-full object-contain"
video={robotVideo}
error={error}
ready={ready}
/>
<div style={{ position: 'absolute', top: 4, left: 8, color: '#fff', fontSize: 12, background: '#0006', padding: '2px 6px', borderRadius: 4 }}>前视</div>
</div>
{/* 后 */}
<div style={{ position: 'relative', border: '1px solid #222' }}>
<VideoPlayer
deviceId={serialNumber}
idx={2}
className="w-full h-full object-contain"
video={robotVideo}
error={error}
ready={ready}
/>
<div style={{ position: 'absolute', top: 4, left: 8, color: '#fff', fontSize: 12, background: '#0006', padding: '2px 6px', borderRadius: 4 }}>后视</div>
</div>
{/* 左 */}
<div style={{ position: 'relative', border: '1px solid #222' }}>
<VideoPlayer
deviceId={serialNumber}
idx={3}
className="w-full h-full object-contain"
video={robotVideo}
error={error}
ready={ready}
/>
<div style={{ position: 'absolute', top: 4, left: 8, color: '#fff', fontSize: 12, background: '#0006', padding: '2px 6px', borderRadius: 4 }}>左视</div>
</div>
{/* 右 */}
<div style={{ position: 'relative', border: '1px solid #222' }}>
<VideoPlayer
deviceId={serialNumber}
idx={4}
className="w-full h-full object-contain"
video={robotVideo}
error={error}
ready={ready}
/>
<div style={{ position: 'absolute', top: 4, left: 8, color: '#fff', fontSize: 12, background: '#0006', padding: '2px 6px', borderRadius: 4 }}>右视</div>
</div>
</div>
) : (
// 单画面模式
<VideoPlayer
deviceId={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', margin: 'auto' }}>
视频加载中...

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 = localStorage.getItem('videotoken') || JSON.parse(localStorage.getItem('userInfo') || '{}')?.token;
const token = "eyJhbGciOiJIUzUxMiJ9.eyJsb2dpbl91c2VyX2tleSI6Ijk2ZTQyYzJlLTYwNWMtNGU5MS05ZTJkLWE2NWUxM2VjZTMyZiJ9.l-F0LGxnfUD2WuATaHK7bYlguorGpGkkOR3Qpga7CWU1S_GiRI6U3At0gjOqx7DasZS7ChVsC_Csp6DX6HfArw"
//const token = localStorage.getItem('videotoken') || JSON.parse(localStorage.getItem('userInfo') || '{}')?.token;
const videoUrl = `${url}?token=${token}`;
try {