Compare commits

..

10 Commits

Author SHA1 Message Date
1651188051 类型:开发
描述:
2026-04-27 16:58:11 +08:00
224fa546bf 类型:开发
描述:
2026-02-09 12:20:57 +08:00
7eaa48e2cb 类型:开发
描述:
2026-02-09 10:28:57 +08:00
e21e9999c7 类型:开发
描述:
2026-02-03 23:50:29 +08:00
bc827e1cc8 类型:开发
描述:
2026-02-03 23:38:44 +08:00
5301a74ec9 类型:开发
描述:
2026-02-03 10:29:49 +08:00
duanliang
c0012f5305 fix bug修改 2026-01-28 18:54:27 +08:00
d10e504db9 类型:开发
描述:
2026-01-28 18:50:45 +08:00
01586539db 类型:开发
描述:
2026-01-28 18:42:42 +08:00
duanliang
970795110d fix bug修复 2026-01-28 12:02:22 +08:00
12 changed files with 132 additions and 48 deletions

35
package-lock.json generated
View File

@@ -25,7 +25,7 @@
"vue-router": "^4.4.5", "vue-router": "^4.4.5",
"vue3-seamless-scroll": "^2.0.1", "vue3-seamless-scroll": "^2.0.1",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",
"whepts": "^1.0.2" "whepts": "^1.1.12"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue": "^5.2.1",
@@ -3335,6 +3335,12 @@
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/eventemitter3": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
"integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
"license": "MIT"
},
"node_modules/events": { "node_modules/events": {
"version": "3.3.0", "version": "3.3.0",
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
@@ -4324,6 +4330,21 @@
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
} }
}, },
"node_modules/nanostores": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/nanostores/-/nanostores-1.1.0.tgz",
"integrity": "sha512-yJBmDJr18xy47dbNVlHcgdPrulSn1nhSE6Ns9vTG+Nx9VPT6iV1MD6aQFp/t52zpf82FhLLTXAXr30NuCnxvwA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"license": "MIT",
"engines": {
"node": "^20.0.0 || >=22.0.0"
}
},
"node_modules/neo-async": { "node_modules/neo-async": {
"version": "2.6.2", "version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
@@ -6167,10 +6188,14 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/whepts": { "node_modules/whepts": {
"version": "1.0.2", "version": "1.1.12",
"resolved": "https://registry.npmjs.org/whepts/-/whepts-1.0.2.tgz", "resolved": "https://registry.npmjs.org/whepts/-/whepts-1.1.12.tgz",
"integrity": "sha512-9P0OP514Z2ZR2ev7qMOApplw6ERMChqgPi6eWWn6HTlTpDV0gW7Zqs4kLAKIV7xqxXCDNDCorxNz8ekOYAEp5g==", "integrity": "sha512-KllGslriMAhD6BDBbG6X653M8XgeYqxnjuEyaB7U/1nIZN6NoAGSWP3Av46g690r2UaaI69bNzfPn4efJBd+kA==",
"license": "MIT" "license": "MIT",
"dependencies": {
"eventemitter3": "^5.0.4",
"nanostores": "^1.1.0"
}
}, },
"node_modules/which": { "node_modules/which": {
"version": "2.0.2", "version": "2.0.2",

View File

@@ -26,7 +26,7 @@
"vue-router": "^4.4.5", "vue-router": "^4.4.5",
"vue3-seamless-scroll": "^2.0.1", "vue3-seamless-scroll": "^2.0.1",
"vuedraggable": "^4.1.0", "vuedraggable": "^4.1.0",
"whepts": "^1.0.2" "whepts": "^1.1.12"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.2.1", "@vitejs/plugin-vue": "^5.2.1",

View File

@@ -159,20 +159,26 @@ export default {
initializePlayer() { initializePlayer() {
if (!this.isActive || !this.url) return if (!this.isActive || !this.url) return
// 如果是重新初始化播放器,先清理已存在的资源 // 如果是重新初始化播放器,先清理已存在的资源
if (this.hls) {
this.immediateCleanup()
}
if(this.url.startsWith('http://192.168.77.200:8050/')){ if(this.url.startsWith('http://192.168.77.200:8050/')){
this.hls = new WebRTCWhep({ this.hls = new WebRTCWhep({
url: this.url, // WHEP 服务器地址 url: this.url, // WHEP 服务器地址
container: this.video, // 视频播放容器 container: this.video, // 视频播放容器
onError: (error) => { iceServers: [{ urls: 'turn:192.168.77.200:3478',username: 'ZLMediaKit',credential: 'ZLMediaKit'}]
console.error('播放错误:', error) })
this.hls.on('error', (error) => {
console.error('错误:', error.message, error.type)
if(error.type ==='REQUEST_ERROR' || error.type ==='NOT_FOUND_ERROR'){
this.initializePlayer();
} }
}) })
this.hls.on('play:failed', (err) => {
// this.initializePlayer();
})
}else{ }else{
if (this.hls) {
this.immediateCleanup()
}
this.hls = new Hls({ this.hls = new Hls({
// 内存优化配置 // 内存优化配置
maxBufferSize: 0, // 降低缓冲区大小15MB maxBufferSize: 0, // 降低缓冲区大小15MB

View File

@@ -16,7 +16,7 @@
<style scoped lang="scss"> <style scoped lang="scss">
.title-3 { .title-3 {
position: relative; position: relative;
min-width: vw(400); // min-width: vw(400);
height: vh(22); height: vh(22);
margin-top: vh(20); margin-top: vh(20);
background-image: url('@/assets/images/title-6.png'); background-image: url('@/assets/images/title-6.png');

View File

@@ -122,17 +122,25 @@
const createPlayer = (cameraIndexCode,videoElement) => { const createPlayer = (cameraIndexCode,videoElement) => {
getPreviewUrlApi({ getPreviewUrlApi({
type: 'hls', type: 'hls',
cameraIndexCode: cameraIndexCode cameraIndexCode: cameraIndexCode,
subStream:1
}).then(res=>{ }).then(res=>{
const url = res.data.url; const url = res.data.url;
if(url.startsWith('http://192.168.77.200:8050/')){ if(url.startsWith('http://192.168.77.200:8050/')){
const player = new WebRTCWhep({ const player = new WebRTCWhep({
url: url, // WHEP 服务器地址 url: url, // WHEP 服务器地址
container: videoElement, // 视频播放容器 container: videoElement, // 视频播放容器
onError: (error) => { iceServers: [{ urls: 'turn:192.168.77.200:3478',username: 'ZLMediaKit',credential: 'ZLMediaKit'}]
console.error('播放错误:', error) })
player.on('error', (error) => {
console.error('错误:', error.message, error.type)
if(error.type ==='REQUEST_ERROR' || error.type ==='NOT_FOUND_ERROR'){
createPlayer(cameraIndexCode,videoElement);
} }
}) })
player.on('play:failed', (err) => {
// createPlayer(cameraIndexCode,videoElement);
})
webrtcRefs.push(player) webrtcRefs.push(player)
} }
else{ else{

View File

@@ -92,7 +92,8 @@ let isCollect = ref(0)
const getPreviewUrl = async (code) => { const getPreviewUrl = async (code) => {
let res = await getPreviewUrlApi({ let res = await getPreviewUrlApi({
cameraIndexCode: code, cameraIndexCode: code,
type: 'hls' type: 'hls',
subStream:1
}) })
src.value = res.data.url src.value = res.data.url
videoShow.value = true videoShow.value = true

View File

@@ -246,7 +246,8 @@ const handleCamera = async (itemCode,resource,index) => {
show.value = true show.value = true
let res = await getPreviewUrlApi({ let res = await getPreviewUrlApi({
type: 'hls', type: 'hls',
cameraIndexCode:itemCode cameraIndexCode:itemCode,
sub_stream: 0
}) })
cameraIndexCode.value = itemCode; cameraIndexCode.value = itemCode;
isCollect.value = resource.isCollect isCollect.value = resource.isCollect
@@ -297,17 +298,25 @@ const handleItemVideo = (url, type, code,item) => {
const createPlayer = (cameraIndexCode,videoElement) => { const createPlayer = (cameraIndexCode,videoElement) => {
getPreviewUrlApi({ getPreviewUrlApi({
type: 'hls', type: 'hls',
cameraIndexCode: cameraIndexCode cameraIndexCode: cameraIndexCode,
subStream:1
}).then(res=>{ }).then(res=>{
const url = res.data.url; const url = res.data.url;
if(url.startsWith('http://192.168.77.200:8050/')){ if(url.startsWith('http://192.168.77.200:8050/')){
const player = new WebRTCWhep({ const player = new WebRTCWhep({
url: url, // WHEP 服务器地址 url: url, // WHEP 服务器地址
container: videoElement, // 视频播放容器 container: videoElement, // 视频播放容器
onError: (error) => { iceServers: [{ urls: 'turn:192.168.77.200:3478',username: 'ZLMediaKit',credential: 'ZLMediaKit'}]
console.error('播放错误:', error) })
player.on('error', (error) => {
console.error('错误:', error.message, error.type)
if(error.type ==='REQUEST_ERROR' || error.type ==='NOT_FOUND_ERROR'){
createPlayer(cameraIndexCode,videoElement);
} }
}) })
player.on('play:failed', (err) => {
// createPlayer(cameraIndexCode,videoElement);
})
webrtcRefs.push(player) webrtcRefs.push(player)
} }
else{ else{

View File

@@ -31,8 +31,9 @@
<span v-else class="statistic-value">暂无</span> <span v-else class="statistic-value">暂无</span>
</div> </div>
</div> </div>
<div class="flex rela"> <div class=" rela">
<Title3 title="景区排队人数" /> <Title3 title="景区排队人数"/>
</div> </div>
<div class="pt-20"> <div class="pt-20">
<Line <Line

View File

@@ -65,7 +65,7 @@
</div> </div>
<div style="display: flex;"> <div style="display: flex;">
<!-- 车船信息 --> <!-- 车船信息 -->
<div class="flex" style="flex:1;margin-left: 14px;"> <div class="flex" style="flex:1;">
<div class="car-ship"> <div class="car-ship">
<div class="mb-6"> <div class="mb-6">
<div class="car"> <div class="car">
@@ -149,8 +149,7 @@
</div> </div>
<!-- 酒店入住 --> <!-- 酒店入住 -->
<div class="hotel" > <div class="hotel" >
<div>
<div >
<div class="item"> <div class="item">
<div class="label">接入总数</div> <div class="label">接入总数</div>
<countup class="value" :end-val="homeStore.hotelData?.info?.hotel_count || 0" /> <countup class="value" :end-val="homeStore.hotelData?.info?.hotel_count || 0" />
@@ -895,8 +894,8 @@
top:vh(110); top:vh(110);
} }
.header { .header {
height: vh(128); height: vh(128);
padding: 0 vw(40); padding: 0 vw(40);
box-sizing: border-box; box-sizing: border-box;
@@ -1113,11 +1112,11 @@
} }
&-tag--important { &-tag--important {
@extend .item-tag; @extend .item-tag;
background: #feae00; background: #d9011b;
} }
&-tag--warn { &-tag--warn {
@extend .item-tag; @extend .item-tag;
background: #d9011b; background: #feae00;
} }
&-tag--normal { &-tag--normal {
@extend .item-tag; @extend .item-tag;

View File

@@ -146,7 +146,7 @@
class="item" class="item"
v-for="(item, index) in videoList" v-for="(item, index) in videoList"
:key="index" :key="index"
@click="handleItemVideo(item.hlsUrl, 101, item.handleItemVideo,item)" @click="handleItemVideo(item.hlsUrl, 101, item.cameraIndexCode,item)"
> >
<div> <div>
<p class="item-title--primary"> <p class="item-title--primary">
@@ -303,7 +303,8 @@ const handleCamera = async (itemCode,resource) => {
show.value = true show.value = true
let res = await getPreviewUrlApi({ let res = await getPreviewUrlApi({
type: 'hls', type: 'hls',
cameraIndexCode:itemCode cameraIndexCode:itemCode,
subStream:0
}) })
cameraIndexCode.value = itemCode; cameraIndexCode.value = itemCode;
isCollect.value = resource.isCollect isCollect.value = resource.isCollect
@@ -339,17 +340,25 @@ const currentChange = (e) => {
const createPlayer = (cameraIndexCode,videoElement) => { const createPlayer = (cameraIndexCode,videoElement) => {
getPreviewUrlApi({ getPreviewUrlApi({
type: 'hls', type: 'hls',
cameraIndexCode: cameraIndexCode cameraIndexCode: cameraIndexCode,
subStream:1
}).then(res=>{ }).then(res=>{
const url = res.data.url; const url = res.data.url;
if(url.startsWith('http://192.168.77.200:8050/')){ if(url.startsWith('http://192.168.77.200:8050/')){
const player = new WebRTCWhep({ const player = new WebRTCWhep({
url:url, // WHEP 服务器地址 url:url, // WHEP 服务器地址
container: videoElement, // 视频播放容器 container: videoElement, // 视频播放容器
onError: (error) => { iceServers: [{ urls: 'turn:192.168.77.200:3478',username: 'ZLMediaKit',credential: 'ZLMediaKit'}]
console.error('播放错误:', error) })
player.on('error', (error) => {
console.error('错误:', error.message, error.type)
if(error.type ==='REQUEST_ERROR' || error.type ==='NOT_FOUND_ERROR'){
createPlayer(cameraIndexCode,videoElement);
} }
}) })
player.on('play:failed', (err) => {
// createPlayer(cameraIndexCode,videoElement);
})
webrtcRefs.push(player) webrtcRefs.push(player)
} }
else{ else{
@@ -419,7 +428,8 @@ let thisVideo = ref(null)
const handleItemVideo = async (url, type, code, item) => { const handleItemVideo = async (url, type, code, item) => {
let res = await getPreviewUrlApi({ let res = await getPreviewUrlApi({
cameraIndexCode: code, cameraIndexCode: code,
type: 'hls' type: 'hls',
subStream:0
}) })
url = res.data.url url = res.data.url
thisVideo.value = item thisVideo.value = item
@@ -430,10 +440,17 @@ const handleItemVideo = async (url, type, code, item) => {
hlsRef = new WebRTCWhep({ hlsRef = new WebRTCWhep({
url: url, // WHEP 服务器地址 url: url, // WHEP 服务器地址
container: videoRef.value, // 视频播放容器 container: videoRef.value, // 视频播放容器
onError: (error) => { iceServers: [{ urls: 'turn:192.168.77.200:3478',username: 'ZLMediaKit',credential: 'ZLMediaKit'}]
console.error('播放错误:', error) })
hlsRef.on('error', (error) => {
console.error('错误:', error.message, error.type)
if(error.type ==='REQUEST_ERROR' || error.type ==='NOT_FOUND_ERROR'){
handleItemVideo(url, type, code, item);
} }
}) })
hlsRef.on('play:failed', (err) => {
// handleItemVideo(url, type, code, item);
})
} else { } else {
hlsRef = new Hls({ hlsRef = new Hls({
maxBufferLength: 10, // 最大缓冲长度(秒) maxBufferLength: 10, // 最大缓冲长度(秒)

View File

@@ -165,7 +165,7 @@
class="item" class="item"
v-for="(item, index) in videoList" v-for="(item, index) in videoList"
:key="index" :key="index"
@click="handleItemVideo(item.hlsUrl, 101, item.handleItemVideo,item)" @click="handleItemVideo(item.hlsUrl, 101, item.cameraIndexCode,item)"
> >
<div> <div>
<p class="item-title--primary"> <p class="item-title--primary">
@@ -258,17 +258,25 @@
const createPlayer = (cameraIndexCode,videoElement) => { const createPlayer = (cameraIndexCode,videoElement) => {
getPreviewUrlApi({ getPreviewUrlApi({
type: 'hls', type: 'hls',
cameraIndexCode: cameraIndexCode cameraIndexCode: cameraIndexCode,
subStream:1
}).then(res=>{ }).then(res=>{
const url = res.data.url; const url = res.data.url;
if(url.startsWith('http://192.168.77.200:8050/')){ if(url.startsWith('http://192.168.77.200:8050/')){
const player = new WebRTCWhep({ const player = new WebRTCWhep({
url: url, // WHEP 服务器地址 url: url, // WHEP 服务器地址
container: videoElement, // 视频播放容器 container: videoElement, // 视频播放容器
onError: (error) => { iceServers: [{ urls: 'turn:192.168.77.200:3478',username: 'ZLMediaKit',credential: 'ZLMediaKit'}]
console.error('播放错误:', error) })
player.on('error', (error) => {
console.error('错误:', error.message, error.type)
if(error.type ==='REQUEST_ERROR' || error.type ==='NOT_FOUND_ERROR'){
createPlayer(cameraIndexCode,videoElement);
} }
}) })
player.on('play:failed', (err) => {
// createPlayer(cameraIndexCode,videoElement);
})
webrtcRefs.push(player) webrtcRefs.push(player)
} }
else{ else{
@@ -389,7 +397,8 @@
const handleItemVideo = async (url, type, code, item) => { const handleItemVideo = async (url, type, code, item) => {
let res = await getPreviewUrlApi({ let res = await getPreviewUrlApi({
cameraIndexCode: code, cameraIndexCode: code,
type: 'hls' type: 'hls',
subStream:0
}) })
url = res.data.url url = res.data.url
thisVideo.value = item thisVideo.value = item
@@ -400,10 +409,17 @@
hlsRef = new WebRTCWhep({ hlsRef = new WebRTCWhep({
url: url, // WHEP 服务器地址 url: url, // WHEP 服务器地址
container: videoRef.value, // 视频播放容器 container: videoRef.value, // 视频播放容器
onError: (error) => { iceServers: [{ urls: 'turn:192.168.77.200:3478',username: 'ZLMediaKit',credential: 'ZLMediaKit'}]
console.error('播放错误:', error) })
hlsRef.on('error', (error) => {
console.error('错误:', error.message, error.type)
if(error.type ==='REQUEST_ERROR' || error.type ==='NOT_FOUND_ERROR'){
handleItemVideo(url, type, code, item);
} }
}) })
hlsRef.on('play:failed', (err) => {
// handleItemVideo(url, type, code, item);
})
} else { } else {
hlsRef = new Hls({ hlsRef = new Hls({
maxBufferLength: 10, // 最大缓冲长度(秒) maxBufferLength: 10, // 最大缓冲长度(秒)
@@ -451,7 +467,8 @@
show.value = true show.value = true
let res = await getPreviewUrlApi({ let res = await getPreviewUrlApi({
type: 'hls', type: 'hls',
cameraIndexCode: itemCode cameraIndexCode: itemCode,
subStream: 0
}) })
cameraIndexCode.value = itemCode; cameraIndexCode.value = itemCode;
isCollect.value = resource.isCollect isCollect.value = resource.isCollect
@@ -708,7 +725,7 @@
.tree-box { .tree-box {
position: relative; position: relative;
// height: vh(490); height: vh(1080);
padding: 0 vw(20); padding: 0 vw(20);
padding-right:0; padding-right:0;
padding-bottom:vw(10); padding-bottom:vw(10);

View File

@@ -191,7 +191,8 @@
const getPreviewUrl = async (code) => { const getPreviewUrl = async (code) => {
let res = await getPreviewUrlApi({ let res = await getPreviewUrlApi({
cameraIndexCode: code, cameraIndexCode: code,
type: 'hls' type: 'hls',
subStream:0
}) })
src.value = res.data.url src.value = res.data.url
videoShow.value = true videoShow.value = true