|
@ -6,6 +6,8 @@ VITE_DROP_CONSOLE=true
|
|||
# axios
|
||||
VITE_APP_BASE_API=/api
|
||||
VITE_APP_PROXY_URL=http://175.6.124.250:8083
|
||||
# VITE_APP_PROXY_URL=https://www.hndyjqrh.cn
|
||||
|
||||
|
||||
#crypto js 前后端需保持一致
|
||||
VITE_APP_CRYPTO_JS_SECRET_KEY=f0234d57c311beb2
|
||||
|
|
8758
analyze.html
|
@ -13,10 +13,9 @@
|
|||
<div id="app"></div>
|
||||
<script
|
||||
src="https://webapi.amap.com/maps?v=1.4.15&key=8910226d8d36a41d856262b1a588850c&plugin=AMap.MarkerClusterer"></script>
|
||||
<!-- <script src="./public/jquery-3.4.1.min.js"></script>
|
||||
<script src="./public/h5player.min.js"></script> -->
|
||||
<script src="./jquery-3.4.1.min.js"></script>
|
||||
<script src="./h5player.min.js"></script>
|
||||
|
||||
<script src="/haikang/h5player.min.js"></script>
|
||||
|
||||
<script type="module" src="/src/main.ts">
|
||||
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"liveServer.settings.port": 5501
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
export const mqttUrl = ''
|
||||
|
||||
|
||||
// export const mqttUrl = 'http://localhost:9527/api/multialarm/video/keep'
|
||||
// export const mqttUrl = 'https://www.hndyjqrh.cn/multialarm/video/keep'
|
||||
// export const mqttUrl = 'https://www.hnjinglian.cn:2563/api_8083/firectrl/client/notice/sendmqtt'
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,286 @@
|
|||
html,body{
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:#000;
|
||||
overflow: hidden;
|
||||
}
|
||||
#video{
|
||||
float:left;
|
||||
width:100%;
|
||||
height:100%;
|
||||
position: absolute;
|
||||
background-image:url("../walkBgVideo.png");
|
||||
background-repeat:no-repeat;
|
||||
background-size:100% 100%;
|
||||
z-index:100;
|
||||
}
|
||||
#agora_local,
|
||||
.player{
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
#video>p{
|
||||
width:360px;
|
||||
height:120px;
|
||||
color:#fff;
|
||||
font-size:32px;
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:50%;
|
||||
margin-left:-180px;
|
||||
margin-top:-100px;
|
||||
}
|
||||
#video>p:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
#video>p>span{
|
||||
display: block;
|
||||
width:100%;
|
||||
height:45px;
|
||||
line-height:45px;
|
||||
}
|
||||
#video>p>img{
|
||||
display:block;
|
||||
width:60px;
|
||||
height:60px;
|
||||
margin:8px 120px;
|
||||
}
|
||||
|
||||
body:hover .videoNav{
|
||||
display: block;
|
||||
}
|
||||
.videoNav{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.videoNav{
|
||||
position:absolute;
|
||||
width:100%;
|
||||
bottom:0px;
|
||||
left:0;
|
||||
z-index:9999999;
|
||||
}
|
||||
.videoNav>p{
|
||||
float:left;
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
background:rgba(0, 0, 0, 0.44);
|
||||
width:100%;
|
||||
|
||||
}
|
||||
.videoNav>p>img{
|
||||
height:18px;
|
||||
padding:3px 5px;
|
||||
border-radius: 3px;
|
||||
border:1px solid #ccc;
|
||||
}
|
||||
.videoNav>p>img:last-child{
|
||||
margin:7px;
|
||||
padding:2px;
|
||||
float:right;
|
||||
}
|
||||
|
||||
.videoNav>p>img:first-child{
|
||||
margin-left:5px;
|
||||
}
|
||||
.videoNav>p:last-child>img{
|
||||
border:0;
|
||||
padding:0;
|
||||
}
|
||||
.videoNav>p:last-child>span{
|
||||
color:#fff;
|
||||
}
|
||||
.layui-slider{
|
||||
float:left;
|
||||
width:70px;
|
||||
margin-top:18px;
|
||||
}
|
||||
.layui-slider-bar{
|
||||
background-color:#1296DB !important;
|
||||
}
|
||||
.layui-slider-wrap-btn{
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.canvasImg{
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height:100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000000;
|
||||
background: rgba(0, 0, 0, 0.44);
|
||||
}
|
||||
.canvasImgBox{
|
||||
position: absolute;
|
||||
background: #000;
|
||||
right:10px;
|
||||
bottom:90px;
|
||||
font-size: 14px;
|
||||
}
|
||||
canvas{
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
.canvasImgBox>p{
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
}
|
||||
.canvasImgBox>p>a,
|
||||
.canvasImgBox>p>button{
|
||||
display: inline-block;
|
||||
height:36px;
|
||||
line-height:36px;
|
||||
border:1px solid #ccc;
|
||||
color:#fff;
|
||||
border-radius: 2px;
|
||||
padding:0 16px;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.inTheVideo{
|
||||
width:100px;
|
||||
height:40px;
|
||||
z-index:99999999;
|
||||
right:10px;
|
||||
top:10px;
|
||||
position:absolute;
|
||||
line-height:40px;
|
||||
color:#000;
|
||||
font-size:20px;
|
||||
animation:mymove 6s infinite;
|
||||
display:none;
|
||||
background:#fff;
|
||||
padding:0px 10px;
|
||||
border-radius: 6px;
|
||||
|
||||
}
|
||||
.inTheVideo>img{
|
||||
width:22px;
|
||||
height:22px;
|
||||
float:left;
|
||||
margin:9px 5px;
|
||||
}
|
||||
@keyframes mymove
|
||||
{
|
||||
0% {opacity:0;}
|
||||
25% {opacity:0.5;}
|
||||
50% {opacity:1;}
|
||||
75% {opacity:0.5;}
|
||||
100% {opacity:0;}
|
||||
}
|
||||
.videoRotate{
|
||||
position:absolute;
|
||||
z-index:9999999999999999999;
|
||||
width:200px;
|
||||
height:90px;
|
||||
right:0%;
|
||||
top:0%;
|
||||
margin-top:0px;
|
||||
margin-left:-70px;
|
||||
font-size:14px;
|
||||
border-radius:4px;
|
||||
color:#000;
|
||||
text-align: center;
|
||||
}
|
||||
.videoRotate>p{
|
||||
line-height:40px;
|
||||
height:40px;
|
||||
margin:10px 0;
|
||||
}
|
||||
.videoRotate>p>button{
|
||||
padding:5px 10px;
|
||||
margin:0 5px;
|
||||
border:0;
|
||||
}
|
||||
.videoRotate>p>button:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.videoRotate>p:nth-child(2)>button:nth-child(2){
|
||||
width:40px;
|
||||
height:40px;
|
||||
border-radius:50%;
|
||||
|
||||
}
|
||||
.videoRotate>p>.bgColor{
|
||||
color:#fff;
|
||||
background:#003c71;
|
||||
}
|
||||
.videoTitle{
|
||||
position:absolute;
|
||||
z-index:9999999999999999999;
|
||||
background:#ccc;
|
||||
width:300px;
|
||||
height:140px;
|
||||
left:50%;
|
||||
top:50%;
|
||||
margin-top:-70px;
|
||||
margin-left:-150px;
|
||||
font-size:14px;
|
||||
border-radius:4px;
|
||||
border:1px solid #fff;
|
||||
display:none;
|
||||
}
|
||||
.videoTitle>p{
|
||||
text-align:center;
|
||||
}
|
||||
.videoTitle>p:nth-child(1){
|
||||
border-radius:4px 4px 0 0;
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
text-align: center;
|
||||
background:#ccc;
|
||||
font-size:16px;
|
||||
font-weight: bold;
|
||||
border-bottom:1px solid #fff;
|
||||
}
|
||||
|
||||
.videoTitle>p:nth-child(2){
|
||||
height:50px;
|
||||
line-height:50px;
|
||||
}
|
||||
|
||||
.videoTitle>p:nth-child(3)>button{
|
||||
height:32px;
|
||||
line-height:28px;
|
||||
padding:0 12px;
|
||||
color:#000;
|
||||
border:0;
|
||||
font-size:14px;
|
||||
margin-right:5px;
|
||||
}
|
||||
|
||||
|
||||
.videoInfo,
|
||||
#qrcode{
|
||||
display:none;
|
||||
width:100%;
|
||||
z-index:99999999;
|
||||
|
||||
bottom:0px;
|
||||
position:absolute;
|
||||
color:#fff;
|
||||
font-size:14px;
|
||||
background:#000;
|
||||
opacity:0.6;
|
||||
}
|
||||
.videoInfo{
|
||||
left:0px;
|
||||
}
|
||||
#qrcode{
|
||||
width:150px;
|
||||
height:150px;
|
||||
border:1px solid #ccc;
|
||||
right:0px !important;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.videoInfo>p{
|
||||
float:left;
|
||||
height:36px;
|
||||
line-height:36px;
|
||||
margin-left:10px;
|
||||
}
|
|
@ -0,0 +1,281 @@
|
|||
html,body{
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:#000;
|
||||
overflow: hidden;
|
||||
}
|
||||
#video{
|
||||
float:left;
|
||||
width:100%;
|
||||
height:720px;
|
||||
position: absolute;
|
||||
background-image:url("../walkBgVideo.png");
|
||||
background-repeat:no-repeat;
|
||||
background-size:100% 100%;
|
||||
z-index:100;
|
||||
}
|
||||
#agora_local,
|
||||
.player{
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
#video>p{
|
||||
width:360px;
|
||||
height:120px;
|
||||
color:#fff;
|
||||
font-size:32px;
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:50%;
|
||||
margin-left:-180px;
|
||||
margin-top:-100px;
|
||||
}
|
||||
#video>p:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
#video>p>span{
|
||||
display: block;
|
||||
width:100%;
|
||||
height:45px;
|
||||
line-height:45px;
|
||||
}
|
||||
#video>p>img{
|
||||
display:block;
|
||||
width:60px;
|
||||
height:60px;
|
||||
margin:8px 120px;
|
||||
}
|
||||
.videoNav{
|
||||
position:absolute;
|
||||
width:100%;
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
bottom:0px;
|
||||
left:0;
|
||||
background:#000;
|
||||
z-index:9999999;
|
||||
}
|
||||
.videoNav>p{
|
||||
float:left;
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
margin-right:10px;
|
||||
}
|
||||
.videoNav>p>img{
|
||||
height:24px;
|
||||
padding:3px 5px;
|
||||
border-radius: 3px;
|
||||
border:1px solid #ccc;
|
||||
}
|
||||
.videoNav>p>img:last-child{
|
||||
margin-right:10px;
|
||||
padding:2px;
|
||||
}
|
||||
.videoNav>p:last-child{
|
||||
margin-left:5px;
|
||||
}
|
||||
.videoNav>p>img:first-child{
|
||||
margin-left:5px;
|
||||
}
|
||||
.videoNav>p:last-child>img{
|
||||
border:0;
|
||||
padding:0;
|
||||
margin-top:-2px;
|
||||
}
|
||||
.videoNav>p:last-child>span{
|
||||
color:#fff;
|
||||
}
|
||||
.layui-slider{
|
||||
float:left;
|
||||
width:70px;
|
||||
margin-top:18px;
|
||||
}
|
||||
.layui-slider-bar{
|
||||
background-color:#1296DB !important;
|
||||
}
|
||||
.layui-slider-wrap-btn{
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.canvasImg{
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height:100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000000;
|
||||
background: rgba(0, 0, 0, 0.44);
|
||||
}
|
||||
.canvasImgBox{
|
||||
position: absolute;
|
||||
background: #000;
|
||||
right:10px;
|
||||
bottom:90px;
|
||||
font-size: 14px;
|
||||
}
|
||||
canvas{
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
.canvasImgBox>p{
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
}
|
||||
.canvasImgBox>p>a,
|
||||
.canvasImgBox>p>button{
|
||||
display: inline-block;
|
||||
height:36px;
|
||||
line-height:36px;
|
||||
border:1px solid #ccc;
|
||||
color:#fff;
|
||||
border-radius: 2px;
|
||||
padding:0 16px;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.inTheVideo{
|
||||
width:100px;
|
||||
height:40px;
|
||||
z-index:99999999;
|
||||
right:10px;
|
||||
top:10px;
|
||||
position:absolute;
|
||||
line-height:40px;
|
||||
color:#000;
|
||||
font-size:20px;
|
||||
animation:mymove 6s infinite;
|
||||
display:none;
|
||||
background:#fff;
|
||||
padding:0px 10px;
|
||||
border-radius: 6px;
|
||||
|
||||
}
|
||||
.inTheVideo>img{
|
||||
width:22px;
|
||||
height:22px;
|
||||
float:left;
|
||||
margin:9px 5px;
|
||||
}
|
||||
@keyframes mymove
|
||||
{
|
||||
0% {opacity:0;}
|
||||
25% {opacity:0.5;}
|
||||
50% {opacity:1;}
|
||||
75% {opacity:0.5;}
|
||||
100% {opacity:0;}
|
||||
}
|
||||
.videoRotate{
|
||||
position:absolute;
|
||||
z-index:9999999999999999999;
|
||||
width:200px;
|
||||
height:90px;
|
||||
right:0%;
|
||||
top:0%;
|
||||
margin-top:0px;
|
||||
margin-left:-70px;
|
||||
font-size:14px;
|
||||
border-radius:4px;
|
||||
color:#000;
|
||||
text-align: center;
|
||||
}
|
||||
.videoRotate>p{
|
||||
line-height:40px;
|
||||
height:40px;
|
||||
margin:10px 0;
|
||||
}
|
||||
.videoRotate>p>button{
|
||||
padding:5px 10px;
|
||||
margin:0 5px;
|
||||
border:0;
|
||||
}
|
||||
.videoRotate>p>button:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.videoRotate>p:nth-child(2)>button:nth-child(2){
|
||||
width:40px;
|
||||
height:40px;
|
||||
border-radius:50%;
|
||||
|
||||
}
|
||||
.videoRotate>p>.bgColor{
|
||||
color:#fff;
|
||||
background:#003c71;
|
||||
}
|
||||
.videoTitle{
|
||||
position:absolute;
|
||||
z-index:9999999999999999999;
|
||||
background:#ccc;
|
||||
width:300px;
|
||||
height:140px;
|
||||
left:50%;
|
||||
top:50%;
|
||||
margin-top:-70px;
|
||||
margin-left:-150px;
|
||||
font-size:14px;
|
||||
border-radius:4px;
|
||||
border:1px solid #fff;
|
||||
display:none;
|
||||
}
|
||||
.videoTitle>p{
|
||||
text-align:center;
|
||||
}
|
||||
.videoTitle>p:nth-child(1){
|
||||
border-radius:4px 4px 0 0;
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
text-align: center;
|
||||
background:#ccc;
|
||||
font-size:16px;
|
||||
font-weight: bold;
|
||||
border-bottom:1px solid #fff;
|
||||
}
|
||||
|
||||
.videoTitle>p:nth-child(2){
|
||||
height:50px;
|
||||
line-height:50px;
|
||||
}
|
||||
|
||||
.videoTitle>p:nth-child(3)>button{
|
||||
height:32px;
|
||||
line-height:28px;
|
||||
padding:0 12px;
|
||||
color:#000;
|
||||
border:0;
|
||||
font-size:14px;
|
||||
margin-right:5px;
|
||||
}
|
||||
|
||||
|
||||
.videoInfo,
|
||||
#qrcode{
|
||||
display:none;
|
||||
width:100%;
|
||||
z-index:99999999;
|
||||
|
||||
bottom:0px;
|
||||
position:absolute;
|
||||
color:#fff;
|
||||
font-size:14px;
|
||||
background:#000;
|
||||
opacity:0.6;
|
||||
}
|
||||
.videoInfo{
|
||||
left:0px;
|
||||
}
|
||||
#qrcode{
|
||||
width:150px;
|
||||
height:150px;
|
||||
border:1px solid #ccc;
|
||||
right:0px !important;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.videoInfo>p{
|
||||
float:left;
|
||||
height:36px;
|
||||
line-height:36px;
|
||||
margin-left:10px;
|
||||
}
|
|
@ -0,0 +1,281 @@
|
|||
html,body{
|
||||
width:100%;
|
||||
height:100%;
|
||||
background:#000;
|
||||
overflow: hidden;
|
||||
}
|
||||
#video{
|
||||
float:left;
|
||||
width:100%;
|
||||
height:720px;
|
||||
position: absolute;
|
||||
background-image:url("../walkBgVideo.png");
|
||||
background-repeat:no-repeat;
|
||||
background-size:100% 100%;
|
||||
z-index:100;
|
||||
}
|
||||
#agora_local,
|
||||
.player{
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
#video>p{
|
||||
width:360px;
|
||||
height:120px;
|
||||
color:#fff;
|
||||
font-size:32px;
|
||||
position:absolute;
|
||||
left:50%;
|
||||
top:50%;
|
||||
margin-left:-180px;
|
||||
margin-top:-100px;
|
||||
}
|
||||
#video>p:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
#video>p>span{
|
||||
display: block;
|
||||
width:100%;
|
||||
height:45px;
|
||||
line-height:45px;
|
||||
}
|
||||
#video>p>img{
|
||||
display:block;
|
||||
width:60px;
|
||||
height:60px;
|
||||
margin:8px 120px;
|
||||
}
|
||||
.videoNav{
|
||||
position:absolute;
|
||||
width:100%;
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
bottom:0px;
|
||||
left:0;
|
||||
background:#000;
|
||||
z-index:9999999;
|
||||
}
|
||||
.videoNav>p{
|
||||
float:left;
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
margin-right:10px;
|
||||
}
|
||||
.videoNav>p>img{
|
||||
height:24px;
|
||||
padding:3px 5px;
|
||||
border-radius: 3px;
|
||||
border:1px solid #ccc;
|
||||
}
|
||||
.videoNav>p>img:last-child{
|
||||
margin-right:10px;
|
||||
padding:2px;
|
||||
}
|
||||
.videoNav>p:last-child{
|
||||
margin-left:5px;
|
||||
}
|
||||
.videoNav>p>img:first-child{
|
||||
margin-left:5px;
|
||||
}
|
||||
.videoNav>p:last-child>img{
|
||||
border:0;
|
||||
padding:0;
|
||||
margin-top:-2px;
|
||||
}
|
||||
.videoNav>p:last-child>span{
|
||||
color:#fff;
|
||||
}
|
||||
.layui-slider{
|
||||
float:left;
|
||||
width:70px;
|
||||
margin-top:18px;
|
||||
}
|
||||
.layui-slider-bar{
|
||||
background-color:#1296DB !important;
|
||||
}
|
||||
.layui-slider-wrap-btn{
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.canvasImg{
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height:100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000000;
|
||||
background: rgba(0, 0, 0, 0.44);
|
||||
}
|
||||
.canvasImgBox{
|
||||
position: absolute;
|
||||
background: #000;
|
||||
right:10px;
|
||||
bottom:90px;
|
||||
font-size: 14px;
|
||||
}
|
||||
canvas{
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
.canvasImgBox>p{
|
||||
height:40px;
|
||||
line-height:40px;
|
||||
}
|
||||
.canvasImgBox>p>a,
|
||||
.canvasImgBox>p>button{
|
||||
display: inline-block;
|
||||
height:36px;
|
||||
line-height:36px;
|
||||
border:1px solid #ccc;
|
||||
color:#fff;
|
||||
border-radius: 2px;
|
||||
padding:0 16px;
|
||||
background-color: #000;
|
||||
}
|
||||
|
||||
.inTheVideo{
|
||||
width:100px;
|
||||
height:40px;
|
||||
z-index:99999999;
|
||||
right:10px;
|
||||
top:10px;
|
||||
position:absolute;
|
||||
line-height:40px;
|
||||
color:#000;
|
||||
font-size:20px;
|
||||
animation:mymove 6s infinite;
|
||||
display:none;
|
||||
background:#fff;
|
||||
padding:0px 10px;
|
||||
border-radius: 6px;
|
||||
|
||||
}
|
||||
.inTheVideo>img{
|
||||
width:22px;
|
||||
height:22px;
|
||||
float:left;
|
||||
margin:9px 5px;
|
||||
}
|
||||
@keyframes mymove
|
||||
{
|
||||
0% {opacity:0;}
|
||||
25% {opacity:0.5;}
|
||||
50% {opacity:1;}
|
||||
75% {opacity:0.5;}
|
||||
100% {opacity:0;}
|
||||
}
|
||||
.videoRotate{
|
||||
position:absolute;
|
||||
z-index:9999999999999999999;
|
||||
width:200px;
|
||||
height:90px;
|
||||
right:0%;
|
||||
top:0%;
|
||||
margin-top:0px;
|
||||
margin-left:-70px;
|
||||
font-size:14px;
|
||||
border-radius:4px;
|
||||
color:#000;
|
||||
text-align: center;
|
||||
}
|
||||
.videoRotate>p{
|
||||
line-height:40px;
|
||||
height:40px;
|
||||
margin:10px 0;
|
||||
}
|
||||
.videoRotate>p>button{
|
||||
padding:5px 10px;
|
||||
margin:0 5px;
|
||||
border:0;
|
||||
}
|
||||
.videoRotate>p>button:hover{
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.videoRotate>p:nth-child(2)>button:nth-child(2){
|
||||
width:40px;
|
||||
height:40px;
|
||||
border-radius:50%;
|
||||
|
||||
}
|
||||
.videoRotate>p>.bgColor{
|
||||
color:#fff;
|
||||
background:#003c71;
|
||||
}
|
||||
.videoTitle{
|
||||
position:absolute;
|
||||
z-index:9999999999999999999;
|
||||
background:#ccc;
|
||||
width:300px;
|
||||
height:140px;
|
||||
left:50%;
|
||||
top:50%;
|
||||
margin-top:-70px;
|
||||
margin-left:-150px;
|
||||
font-size:14px;
|
||||
border-radius:4px;
|
||||
border:1px solid #fff;
|
||||
display:none;
|
||||
}
|
||||
.videoTitle>p{
|
||||
text-align:center;
|
||||
}
|
||||
.videoTitle>p:nth-child(1){
|
||||
border-radius:4px 4px 0 0;
|
||||
height:30px;
|
||||
line-height:30px;
|
||||
text-align: center;
|
||||
background:#ccc;
|
||||
font-size:16px;
|
||||
font-weight: bold;
|
||||
border-bottom:1px solid #fff;
|
||||
}
|
||||
|
||||
.videoTitle>p:nth-child(2){
|
||||
height:50px;
|
||||
line-height:50px;
|
||||
}
|
||||
|
||||
.videoTitle>p:nth-child(3)>button{
|
||||
height:32px;
|
||||
line-height:28px;
|
||||
padding:0 12px;
|
||||
color:#000;
|
||||
border:0;
|
||||
font-size:14px;
|
||||
margin-right:5px;
|
||||
}
|
||||
|
||||
|
||||
.videoInfo,
|
||||
#qrcode{
|
||||
display:none;
|
||||
width:100%;
|
||||
z-index:99999999;
|
||||
|
||||
bottom:0px;
|
||||
position:absolute;
|
||||
color:#fff;
|
||||
font-size:14px;
|
||||
background:#000;
|
||||
opacity:0.6;
|
||||
}
|
||||
.videoInfo{
|
||||
left:0px;
|
||||
}
|
||||
#qrcode{
|
||||
width:150px;
|
||||
height:150px;
|
||||
border:1px solid #ccc;
|
||||
right:0px !important;
|
||||
opacity:1;
|
||||
}
|
||||
|
||||
.videoInfo>p{
|
||||
float:left;
|
||||
height:36px;
|
||||
line-height:36px;
|
||||
margin-left:10px;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>视频查看</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"/>
|
||||
<meta http-equiv="Cache" content="no-cache">
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<link rel="stylesheet" href="./layui.css">
|
||||
<script src="AgoraRTC_N-4.11.0.js"></script>
|
||||
<script src="./jquery-3.4.1.min.js"></script>
|
||||
<script src="./layui.js"></script>
|
||||
<!--给录像文件添加时间进度条-->
|
||||
<script src="fix-webm-duration.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="video">
|
||||
<div id="qrcode"></div>
|
||||
<div id="agora_local"></div>
|
||||
</div>
|
||||
|
||||
<!--视频操作-->
|
||||
<div class="videoNav">
|
||||
<p class="nav">
|
||||
<img src="images/videoExit.png" alt="" class="videoExit" title="退出"/>
|
||||
<img src="images/closeMute.png" alt="" title="静音" mute="close" class="closeMute"/>
|
||||
<img src="images/videoFullscreen.png" alt="" title="全屏" model="exitfullScreen" class="videoFullscreen"/>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!--当js文件发生变化的时候,自动清除浏览器缓存,只要标签后面的v每次不一样浏览器就更新了阿-->
|
||||
<script>
|
||||
//创建一个script标签
|
||||
function loadScriptString() {
|
||||
var timeStamp=new Date().getTime();
|
||||
var script = document.createElement("script"); //创建一个script标签
|
||||
script.type = "module";
|
||||
script.src=`js/deviceAlarmVideo.js?v=${timeStamp}`;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
}
|
||||
|
||||
//创建一个link标签
|
||||
function loadLinkString(){
|
||||
var timeStamp=new Date().getTime();
|
||||
var css = document.createElement("link"); //创建一个script标签
|
||||
css.rel = "stylesheet";
|
||||
css.href=`css/deviceAlarmVideo.css?v=${timeStamp}`
|
||||
document.getElementsByTagName('head')[0].appendChild(css);
|
||||
}
|
||||
|
||||
loadScriptString();
|
||||
loadLinkString();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,487 @@
|
|||
(function (name, definition) {
|
||||
if (typeof define === 'function' && define.amd) { // RequireJS / AMD
|
||||
define(definition);
|
||||
} else if (typeof module !== 'undefined' && module.exports) { // CommonJS / Node.js
|
||||
module.exports = definition();
|
||||
} else { // Direct include
|
||||
window.ysFixWebmDuration = definition();
|
||||
}
|
||||
})('fix-webm-duration', function () {
|
||||
/*
|
||||
* This is the list of possible WEBM file sections by their IDs.
|
||||
* Possible types: Container, Binary, Uint, Int, String, Float, Date
|
||||
*/
|
||||
var sections = {
|
||||
0xa45dfa3: { name: 'EBML', type: 'Container' },
|
||||
0x286: { name: 'EBMLVersion', type: 'Uint' },
|
||||
0x2f7: { name: 'EBMLReadVersion', type: 'Uint' },
|
||||
0x2f2: { name: 'EBMLMaxIDLength', type: 'Uint' },
|
||||
0x2f3: { name: 'EBMLMaxSizeLength', type: 'Uint' },
|
||||
0x282: { name: 'DocType', type: 'String' },
|
||||
0x287: { name: 'DocTypeVersion', type: 'Uint' },
|
||||
0x285: { name: 'DocTypeReadVersion', type: 'Uint' },
|
||||
0x6c: { name: 'Void', type: 'Binary' },
|
||||
0x3f: { name: 'CRC-32', type: 'Binary' },
|
||||
0xb538667: { name: 'SignatureSlot', type: 'Container' },
|
||||
0x3e8a: { name: 'SignatureAlgo', type: 'Uint' },
|
||||
0x3e9a: { name: 'SignatureHash', type: 'Uint' },
|
||||
0x3ea5: { name: 'SignaturePublicKey', type: 'Binary' },
|
||||
0x3eb5: { name: 'Signature', type: 'Binary' },
|
||||
0x3e5b: { name: 'SignatureElements', type: 'Container' },
|
||||
0x3e7b: { name: 'SignatureElementList', type: 'Container' },
|
||||
0x2532: { name: 'SignedElement', type: 'Binary' },
|
||||
0x8538067: { name: 'Segment', type: 'Container' },
|
||||
0x14d9b74: { name: 'SeekHead', type: 'Container' },
|
||||
0xdbb: { name: 'Seek', type: 'Container' },
|
||||
0x13ab: { name: 'SeekID', type: 'Binary' },
|
||||
0x13ac: { name: 'SeekPosition', type: 'Uint' },
|
||||
0x549a966: { name: 'Info', type: 'Container' },
|
||||
0x33a4: { name: 'SegmentUID', type: 'Binary' },
|
||||
0x3384: { name: 'SegmentFilename', type: 'String' },
|
||||
0x1cb923: { name: 'PrevUID', type: 'Binary' },
|
||||
0x1c83ab: { name: 'PrevFilename', type: 'String' },
|
||||
0x1eb923: { name: 'NextUID', type: 'Binary' },
|
||||
0x1e83bb: { name: 'NextFilename', type: 'String' },
|
||||
0x444: { name: 'SegmentFamily', type: 'Binary' },
|
||||
0x2924: { name: 'ChapterTranslate', type: 'Container' },
|
||||
0x29fc: { name: 'ChapterTranslateEditionUID', type: 'Uint' },
|
||||
0x29bf: { name: 'ChapterTranslateCodec', type: 'Uint' },
|
||||
0x29a5: { name: 'ChapterTranslateID', type: 'Binary' },
|
||||
0xad7b1: { name: 'TimecodeScale', type: 'Uint' },
|
||||
0x489: { name: 'Duration', type: 'Float' },
|
||||
0x461: { name: 'DateUTC', type: 'Date' },
|
||||
0x3ba9: { name: 'Title', type: 'String' },
|
||||
0xd80: { name: 'MuxingApp', type: 'String' },
|
||||
0x1741: { name: 'WritingApp', type: 'String' },
|
||||
// 0xf43b675: { name: 'Cluster', type: 'Container' },
|
||||
0x67: { name: 'Timecode', type: 'Uint' },
|
||||
0x1854: { name: 'SilentTracks', type: 'Container' },
|
||||
0x18d7: { name: 'SilentTrackNumber', type: 'Uint' },
|
||||
0x27: { name: 'Position', type: 'Uint' },
|
||||
0x2b: { name: 'PrevSize', type: 'Uint' },
|
||||
0x23: { name: 'SimpleBlock', type: 'Binary' },
|
||||
0x20: { name: 'BlockGroup', type: 'Container' },
|
||||
0x21: { name: 'Block', type: 'Binary' },
|
||||
0x22: { name: 'BlockVirtual', type: 'Binary' },
|
||||
0x35a1: { name: 'BlockAdditions', type: 'Container' },
|
||||
0x26: { name: 'BlockMore', type: 'Container' },
|
||||
0x6e: { name: 'BlockAddID', type: 'Uint' },
|
||||
0x25: { name: 'BlockAdditional', type: 'Binary' },
|
||||
0x1b: { name: 'BlockDuration', type: 'Uint' },
|
||||
0x7a: { name: 'ReferencePriority', type: 'Uint' },
|
||||
0x7b: { name: 'ReferenceBlock', type: 'Int' },
|
||||
0x7d: { name: 'ReferenceVirtual', type: 'Int' },
|
||||
0x24: { name: 'CodecState', type: 'Binary' },
|
||||
0x35a2: { name: 'DiscardPadding', type: 'Int' },
|
||||
0xe: { name: 'Slices', type: 'Container' },
|
||||
0x68: { name: 'TimeSlice', type: 'Container' },
|
||||
0x4c: { name: 'LaceNumber', type: 'Uint' },
|
||||
0x4d: { name: 'FrameNumber', type: 'Uint' },
|
||||
0x4b: { name: 'BlockAdditionID', type: 'Uint' },
|
||||
0x4e: { name: 'Delay', type: 'Uint' },
|
||||
0x4f: { name: 'SliceDuration', type: 'Uint' },
|
||||
0x48: { name: 'ReferenceFrame', type: 'Container' },
|
||||
0x49: { name: 'ReferenceOffset', type: 'Uint' },
|
||||
0x4a: { name: 'ReferenceTimeCode', type: 'Uint' },
|
||||
0x2f: { name: 'EncryptedBlock', type: 'Binary' },
|
||||
0x654ae6b: { name: 'Tracks', type: 'Container' },
|
||||
0x2e: { name: 'TrackEntry', type: 'Container' },
|
||||
0x57: { name: 'TrackNumber', type: 'Uint' },
|
||||
0x33c5: { name: 'TrackUID', type: 'Uint' },
|
||||
0x3: { name: 'TrackType', type: 'Uint' },
|
||||
0x39: { name: 'FlagEnabled', type: 'Uint' },
|
||||
0x8: { name: 'FlagDefault', type: 'Uint' },
|
||||
0x15aa: { name: 'FlagForced', type: 'Uint' },
|
||||
0x1c: { name: 'FlagLacing', type: 'Uint' },
|
||||
0x2de7: { name: 'MinCache', type: 'Uint' },
|
||||
0x2df8: { name: 'MaxCache', type: 'Uint' },
|
||||
0x3e383: { name: 'DefaultDuration', type: 'Uint' },
|
||||
0x34e7a: { name: 'DefaultDecodedFieldDuration', type: 'Uint' },
|
||||
0x3314f: { name: 'TrackTimecodeScale', type: 'Float' },
|
||||
0x137f: { name: 'TrackOffset', type: 'Int' },
|
||||
0x15ee: { name: 'MaxBlockAdditionID', type: 'Uint' },
|
||||
0x136e: { name: 'Name', type: 'String' },
|
||||
0x2b59c: { name: 'Language', type: 'String' },
|
||||
0x6: { name: 'CodecID', type: 'String' },
|
||||
0x23a2: { name: 'CodecPrivate', type: 'Binary' },
|
||||
0x58688: { name: 'CodecName', type: 'String' },
|
||||
0x3446: { name: 'AttachmentLink', type: 'Uint' },
|
||||
0x1a9697: { name: 'CodecSettings', type: 'String' },
|
||||
0x1b4040: { name: 'CodecInfoURL', type: 'String' },
|
||||
0x6b240: { name: 'CodecDownloadURL', type: 'String' },
|
||||
0x2a: { name: 'CodecDecodeAll', type: 'Uint' },
|
||||
0x2fab: { name: 'TrackOverlay', type: 'Uint' },
|
||||
0x16aa: { name: 'CodecDelay', type: 'Uint' },
|
||||
0x16bb: { name: 'SeekPreRoll', type: 'Uint' },
|
||||
0x2624: { name: 'TrackTranslate', type: 'Container' },
|
||||
0x26fc: { name: 'TrackTranslateEditionUID', type: 'Uint' },
|
||||
0x26bf: { name: 'TrackTranslateCodec', type: 'Uint' },
|
||||
0x26a5: { name: 'TrackTranslateTrackID', type: 'Binary' },
|
||||
0x60: { name: 'Video', type: 'Container' },
|
||||
0x1a: { name: 'FlagInterlaced', type: 'Uint' },
|
||||
0x13b8: { name: 'StereoMode', type: 'Uint' },
|
||||
0x13c0: { name: 'AlphaMode', type: 'Uint' },
|
||||
0x13b9: { name: 'OldStereoMode', type: 'Uint' },
|
||||
0x30: { name: 'PixelWidth', type: 'Uint' },
|
||||
0x3a: { name: 'PixelHeight', type: 'Uint' },
|
||||
0x14aa: { name: 'PixelCropBottom', type: 'Uint' },
|
||||
0x14bb: { name: 'PixelCropTop', type: 'Uint' },
|
||||
0x14cc: { name: 'PixelCropLeft', type: 'Uint' },
|
||||
0x14dd: { name: 'PixelCropRight', type: 'Uint' },
|
||||
0x14b0: { name: 'DisplayWidth', type: 'Uint' },
|
||||
0x14ba: { name: 'DisplayHeight', type: 'Uint' },
|
||||
0x14b2: { name: 'DisplayUnit', type: 'Uint' },
|
||||
0x14b3: { name: 'AspectRatioType', type: 'Uint' },
|
||||
0xeb524: { name: 'ColourSpace', type: 'Binary' },
|
||||
0xfb523: { name: 'GammaValue', type: 'Float' },
|
||||
0x383e3: { name: 'FrameRate', type: 'Float' },
|
||||
0x61: { name: 'Audio', type: 'Container' },
|
||||
0x35: { name: 'SamplingFrequency', type: 'Float' },
|
||||
0x38b5: { name: 'OutputSamplingFrequency', type: 'Float' },
|
||||
0x1f: { name: 'Channels', type: 'Uint' },
|
||||
0x3d7b: { name: 'ChannelPositions', type: 'Binary' },
|
||||
0x2264: { name: 'BitDepth', type: 'Uint' },
|
||||
0x62: { name: 'TrackOperation', type: 'Container' },
|
||||
0x63: { name: 'TrackCombinePlanes', type: 'Container' },
|
||||
0x64: { name: 'TrackPlane', type: 'Container' },
|
||||
0x65: { name: 'TrackPlaneUID', type: 'Uint' },
|
||||
0x66: { name: 'TrackPlaneType', type: 'Uint' },
|
||||
0x69: { name: 'TrackJoinBlocks', type: 'Container' },
|
||||
0x6d: { name: 'TrackJoinUID', type: 'Uint' },
|
||||
0x40: { name: 'TrickTrackUID', type: 'Uint' },
|
||||
0x41: { name: 'TrickTrackSegmentUID', type: 'Binary' },
|
||||
0x46: { name: 'TrickTrackFlag', type: 'Uint' },
|
||||
0x47: { name: 'TrickMasterTrackUID', type: 'Uint' },
|
||||
0x44: { name: 'TrickMasterTrackSegmentUID', type: 'Binary' },
|
||||
0x2d80: { name: 'ContentEncodings', type: 'Container' },
|
||||
0x2240: { name: 'ContentEncoding', type: 'Container' },
|
||||
0x1031: { name: 'ContentEncodingOrder', type: 'Uint' },
|
||||
0x1032: { name: 'ContentEncodingScope', type: 'Uint' },
|
||||
0x1033: { name: 'ContentEncodingType', type: 'Uint' },
|
||||
0x1034: { name: 'ContentCompression', type: 'Container' },
|
||||
0x254: { name: 'ContentCompAlgo', type: 'Uint' },
|
||||
0x255: { name: 'ContentCompSettings', type: 'Binary' },
|
||||
0x1035: { name: 'ContentEncryption', type: 'Container' },
|
||||
0x7e1: { name: 'ContentEncAlgo', type: 'Uint' },
|
||||
0x7e2: { name: 'ContentEncKeyID', type: 'Binary' },
|
||||
0x7e3: { name: 'ContentSignature', type: 'Binary' },
|
||||
0x7e4: { name: 'ContentSigKeyID', type: 'Binary' },
|
||||
0x7e5: { name: 'ContentSigAlgo', type: 'Uint' },
|
||||
0x7e6: { name: 'ContentSigHashAlgo', type: 'Uint' },
|
||||
0xc53bb6b: { name: 'Cues', type: 'Container' },
|
||||
0x3b: { name: 'CuePoint', type: 'Container' },
|
||||
0x33: { name: 'CueTime', type: 'Uint' },
|
||||
0x37: { name: 'CueTrackPositions', type: 'Container' },
|
||||
0x77: { name: 'CueTrack', type: 'Uint' },
|
||||
0x71: { name: 'CueClusterPosition', type: 'Uint' },
|
||||
0x70: { name: 'CueRelativePosition', type: 'Uint' },
|
||||
0x32: { name: 'CueDuration', type: 'Uint' },
|
||||
0x1378: { name: 'CueBlockNumber', type: 'Uint' },
|
||||
0x6a: { name: 'CueCodecState', type: 'Uint' },
|
||||
0x5b: { name: 'CueReference', type: 'Container' },
|
||||
0x16: { name: 'CueRefTime', type: 'Uint' },
|
||||
0x17: { name: 'CueRefCluster', type: 'Uint' },
|
||||
0x135f: { name: 'CueRefNumber', type: 'Uint' },
|
||||
0x6b: { name: 'CueRefCodecState', type: 'Uint' },
|
||||
0x941a469: { name: 'Attachments', type: 'Container' },
|
||||
0x21a7: { name: 'AttachedFile', type: 'Container' },
|
||||
0x67e: { name: 'FileDescription', type: 'String' },
|
||||
0x66e: { name: 'FileName', type: 'String' },
|
||||
0x660: { name: 'FileMimeType', type: 'String' },
|
||||
0x65c: { name: 'FileData', type: 'Binary' },
|
||||
0x6ae: { name: 'FileUID', type: 'Uint' },
|
||||
0x675: { name: 'FileReferral', type: 'Binary' },
|
||||
0x661: { name: 'FileUsedStartTime', type: 'Uint' },
|
||||
0x662: { name: 'FileUsedEndTime', type: 'Uint' },
|
||||
0x43a770: { name: 'Chapters', type: 'Container' },
|
||||
0x5b9: { name: 'EditionEntry', type: 'Container' },
|
||||
0x5bc: { name: 'EditionUID', type: 'Uint' },
|
||||
0x5bd: { name: 'EditionFlagHidden', type: 'Uint' },
|
||||
0x5db: { name: 'EditionFlagDefault', type: 'Uint' },
|
||||
0x5dd: { name: 'EditionFlagOrdered', type: 'Uint' },
|
||||
0x36: { name: 'ChapterAtom', type: 'Container' },
|
||||
0x33c4: { name: 'ChapterUID', type: 'Uint' },
|
||||
0x1654: { name: 'ChapterStringUID', type: 'String' },
|
||||
0x11: { name: 'ChapterTimeStart', type: 'Uint' },
|
||||
0x12: { name: 'ChapterTimeEnd', type: 'Uint' },
|
||||
0x18: { name: 'ChapterFlagHidden', type: 'Uint' },
|
||||
0x598: { name: 'ChapterFlagEnabled', type: 'Uint' },
|
||||
0x2e67: { name: 'ChapterSegmentUID', type: 'Binary' },
|
||||
0x2ebc: { name: 'ChapterSegmentEditionUID', type: 'Uint' },
|
||||
0x23c3: { name: 'ChapterPhysicalEquiv', type: 'Uint' },
|
||||
0xf: { name: 'ChapterTrack', type: 'Container' },
|
||||
0x9: { name: 'ChapterTrackNumber', type: 'Uint' },
|
||||
0x0: { name: 'ChapterDisplay', type: 'Container' },
|
||||
0x5: { name: 'ChapString', type: 'String' },
|
||||
0x37c: { name: 'ChapLanguage', type: 'String' },
|
||||
0x37e: { name: 'ChapCountry', type: 'String' },
|
||||
0x2944: { name: 'ChapProcess', type: 'Container' },
|
||||
0x2955: { name: 'ChapProcessCodecID', type: 'Uint' },
|
||||
0x50d: { name: 'ChapProcessPrivate', type: 'Binary' },
|
||||
0x2911: { name: 'ChapProcessCommand', type: 'Container' },
|
||||
0x2922: { name: 'ChapProcessTime', type: 'Uint' },
|
||||
0x2933: { name: 'ChapProcessData', type: 'Binary' },
|
||||
0x254c367: { name: 'Tags', type: 'Container' },
|
||||
0x3373: { name: 'Tag', type: 'Container' },
|
||||
0x23c0: { name: 'Targets', type: 'Container' },
|
||||
0x28ca: { name: 'TargetTypeValue', type: 'Uint' },
|
||||
0x23ca: { name: 'TargetType', type: 'String' },
|
||||
0x23c5: { name: 'TagTrackUID', type: 'Uint' },
|
||||
0x23c9: { name: 'TagEditionUID', type: 'Uint' },
|
||||
0x23c4: { name: 'TagChapterUID', type: 'Uint' },
|
||||
0x23c6: { name: 'TagAttachmentUID', type: 'Uint' },
|
||||
0x27c8: { name: 'SimpleTag', type: 'Container' },
|
||||
0x5a3: { name: 'TagName', type: 'String' },
|
||||
0x47a: { name: 'TagLanguage', type: 'String' },
|
||||
0x484: { name: 'TagDefault', type: 'Uint' },
|
||||
0x487: { name: 'TagString', type: 'String' },
|
||||
0x485: { name: 'TagBinary', type: 'Binary' }
|
||||
};
|
||||
|
||||
function doInherit(newClass, baseClass) {
|
||||
newClass.prototype = Object.create(baseClass.prototype);
|
||||
newClass.prototype.constructor = newClass;
|
||||
}
|
||||
|
||||
function WebmBase(name, type) {
|
||||
this.name = name || 'Unknown';
|
||||
this.type = type || 'Unknown';
|
||||
}
|
||||
WebmBase.prototype.updateBySource = function() { };
|
||||
WebmBase.prototype.setSource = function(source) {
|
||||
this.source = source;
|
||||
this.updateBySource();
|
||||
};
|
||||
WebmBase.prototype.updateByData = function() { };
|
||||
WebmBase.prototype.setData = function(data) {
|
||||
this.data = data;
|
||||
this.updateByData();
|
||||
};
|
||||
|
||||
function WebmUint(name, type) {
|
||||
WebmBase.call(this, name, type || 'Uint');
|
||||
}
|
||||
doInherit(WebmUint, WebmBase);
|
||||
function padHex(hex) {
|
||||
return hex.length % 2 === 1 ? '0' + hex : hex;
|
||||
}
|
||||
WebmUint.prototype.updateBySource = function() {
|
||||
// use hex representation of a number instead of number value
|
||||
this.data = '';
|
||||
for (var i = 0; i < this.source.length; i++) {
|
||||
var hex = this.source[i].toString(16);
|
||||
this.data += padHex(hex);
|
||||
}
|
||||
};
|
||||
WebmUint.prototype.updateByData = function() {
|
||||
var length = this.data.length / 2;
|
||||
this.source = new Uint8Array(length);
|
||||
for (var i = 0; i < length; i++) {
|
||||
var hex = this.data.substr(i * 2, 2);
|
||||
this.source[i] = parseInt(hex, 16);
|
||||
}
|
||||
};
|
||||
WebmUint.prototype.getValue = function() {
|
||||
return parseInt(this.data, 16);
|
||||
};
|
||||
WebmUint.prototype.setValue = function(value) {
|
||||
this.setData(padHex(value.toString(16)));
|
||||
};
|
||||
|
||||
function WebmFloat(name, type) {
|
||||
WebmBase.call(this, name, type || 'Float');
|
||||
}
|
||||
doInherit(WebmFloat, WebmBase);
|
||||
WebmFloat.prototype.getFloatArrayType = function() {
|
||||
return this.source && this.source.length === 4 ? Float32Array : Float64Array;
|
||||
};
|
||||
WebmFloat.prototype.updateBySource = function() {
|
||||
var byteArray = this.source.reverse();
|
||||
var floatArrayType = this.getFloatArrayType();
|
||||
var floatArray = new floatArrayType(byteArray.buffer);
|
||||
this.data = floatArray[0];
|
||||
};
|
||||
WebmFloat.prototype.updateByData = function() {
|
||||
var floatArrayType = this.getFloatArrayType();
|
||||
var floatArray = new floatArrayType([ this.data ]);
|
||||
var byteArray = new Uint8Array(floatArray.buffer);
|
||||
this.source = byteArray.reverse();
|
||||
};
|
||||
WebmFloat.prototype.getValue = function() {
|
||||
return this.data;
|
||||
};
|
||||
WebmFloat.prototype.setValue = function(value) {
|
||||
this.setData(value);
|
||||
};
|
||||
|
||||
function WebmContainer(name, type) {
|
||||
WebmBase.call(this, name, type || 'Container');
|
||||
}
|
||||
doInherit(WebmContainer, WebmBase);
|
||||
WebmContainer.prototype.readByte = function() {
|
||||
return this.source[this.offset++];
|
||||
};
|
||||
WebmContainer.prototype.readUint = function() {
|
||||
var firstByte = this.readByte();
|
||||
var bytes = 8 - firstByte.toString(2).length;
|
||||
var value = firstByte - (1 << (7 - bytes));
|
||||
for (var i = 0; i < bytes; i++) {
|
||||
// don't use bit operators to support x86
|
||||
value *= 256;
|
||||
value += this.readByte();
|
||||
}
|
||||
return value;
|
||||
};
|
||||
WebmContainer.prototype.updateBySource = function() {
|
||||
this.data = [];
|
||||
for (this.offset = 0; this.offset < this.source.length; this.offset = end) {
|
||||
var id = this.readUint();
|
||||
var len = this.readUint();
|
||||
var end = Math.min(this.offset + len, this.source.length);
|
||||
var data = this.source.slice(this.offset, end);
|
||||
|
||||
var info = sections[id] || { name: 'Unknown', type: 'Unknown' };
|
||||
var ctr = WebmBase;
|
||||
switch (info.type) {
|
||||
case 'Container':
|
||||
ctr = WebmContainer;
|
||||
break;
|
||||
case 'Uint':
|
||||
ctr = WebmUint;
|
||||
break;
|
||||
case 'Float':
|
||||
ctr = WebmFloat;
|
||||
break;
|
||||
}
|
||||
var section = new ctr(info.name, info.type);
|
||||
section.setSource(data);
|
||||
this.data.push({
|
||||
id: id,
|
||||
idHex: id.toString(16),
|
||||
data: section
|
||||
});
|
||||
}
|
||||
};
|
||||
WebmContainer.prototype.writeUint = function(x, draft) {
|
||||
for (var bytes = 1, flag = 0x80; x >= flag && bytes < 8; bytes++, flag *= 0x80) { }
|
||||
|
||||
if (!draft) {
|
||||
var value = flag + x;
|
||||
for (var i = bytes - 1; i >= 0; i--) {
|
||||
// don't use bit operators to support x86
|
||||
var c = value % 256;
|
||||
this.source[this.offset + i] = c;
|
||||
value = (value - c) / 256;
|
||||
}
|
||||
}
|
||||
|
||||
this.offset += bytes;
|
||||
};
|
||||
WebmContainer.prototype.writeSections = function(draft) {
|
||||
this.offset = 0;
|
||||
for (var i = 0; i < this.data.length; i++) {
|
||||
var section = this.data[i],
|
||||
content = section.data.source,
|
||||
contentLength = content.length;
|
||||
this.writeUint(section.id, draft);
|
||||
this.writeUint(contentLength, draft);
|
||||
if (!draft) {
|
||||
this.source.set(content, this.offset);
|
||||
}
|
||||
this.offset += contentLength;
|
||||
}
|
||||
return this.offset;
|
||||
};
|
||||
WebmContainer.prototype.updateByData = function() {
|
||||
// run without accessing this.source to determine total length - need to know it to create Uint8Array
|
||||
var length = this.writeSections('draft');
|
||||
this.source = new Uint8Array(length);
|
||||
// now really write data
|
||||
this.writeSections();
|
||||
};
|
||||
WebmContainer.prototype.getSectionById = function(id) {
|
||||
for (var i = 0; i < this.data.length; i++) {
|
||||
var section = this.data[i];
|
||||
if (section.id === id) {
|
||||
return section.data;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
function WebmFile(source) {
|
||||
WebmContainer.call(this, 'File', 'File');
|
||||
this.setSource(source);
|
||||
}
|
||||
doInherit(WebmFile, WebmContainer);
|
||||
WebmFile.prototype.fixDuration = function(duration) {
|
||||
var segmentSection = this.getSectionById(0x8538067);
|
||||
if (!segmentSection) {
|
||||
console.log('[fix-webm-duration] Segment section is missing');
|
||||
return false;
|
||||
}
|
||||
|
||||
var infoSection = segmentSection.getSectionById(0x549a966);
|
||||
if (!infoSection) {
|
||||
console.log('[fix-webm-duration] Info section is missing');
|
||||
return false;
|
||||
}
|
||||
|
||||
var timeScaleSection = infoSection.getSectionById(0xad7b1);
|
||||
if (!timeScaleSection) {
|
||||
console.log('[fix-webm-duration] TimecodeScale section is missing');
|
||||
return false;
|
||||
}
|
||||
|
||||
var durationSection = infoSection.getSectionById(0x489);
|
||||
if (durationSection) {
|
||||
if (durationSection.getValue() <= 0) {
|
||||
console.log('[fix-webm-duration] Duration section is present, but the value is empty');
|
||||
durationSection.setValue(duration);
|
||||
} else {
|
||||
console.log('[fix-webm-duration] Duration section is present');
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
console.log('[fix-webm-duration] Duration section is missing');
|
||||
// append Duration section
|
||||
durationSection = new WebmFloat('Duration', 'Float');
|
||||
durationSection.setValue(duration);
|
||||
infoSection.data.push({
|
||||
id: 0x489,
|
||||
data: durationSection
|
||||
});
|
||||
}
|
||||
|
||||
// set default time scale to 1 millisecond (1000000 nanoseconds)
|
||||
timeScaleSection.setValue(1000000);
|
||||
infoSection.updateByData();
|
||||
segmentSection.updateByData();
|
||||
this.updateByData();
|
||||
|
||||
return true;
|
||||
};
|
||||
WebmFile.prototype.toBlob = function() {
|
||||
return new Blob([this.source.buffer], { type: 'video/webm;codecs=vp8,opus' });
|
||||
};
|
||||
|
||||
return function(blob, duration, callback) {
|
||||
try {
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function() {
|
||||
try {
|
||||
var file = new WebmFile(new Uint8Array(reader.result));
|
||||
if (file.fixDuration(duration)) {
|
||||
blob = file.toBlob();
|
||||
}
|
||||
} catch (ex) {
|
||||
// ignore
|
||||
}
|
||||
callback(blob);
|
||||
};
|
||||
reader.readAsArrayBuffer(blob);
|
||||
} catch (ex) {
|
||||
callback(blob);
|
||||
}
|
||||
};
|
||||
});
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>视频查看</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"/>
|
||||
<meta http-equiv="Cache" content="no-cache">
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<link rel="stylesheet" href="./layui.css">
|
||||
<script src="AgoraRTC_N-4.11.0.js"></script>
|
||||
<script src="./jquery-3.4.1.min.js"></script>
|
||||
<script src="./layui.js"></script>
|
||||
<!--给录像文件添加时间进度条-->
|
||||
<script src="fix-webm-duration.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!--视频显示-->
|
||||
<div id="video">
|
||||
<div id="agora_local"></div>
|
||||
</div>
|
||||
<!--当js文件发生变化的时候,自动清除浏览器缓存,只要标签后面的v每次不一样浏览器就更新了阿-->
|
||||
<script>
|
||||
//创建一个script标签
|
||||
function loadScriptString() {
|
||||
var timeStamp=new Date().getTime();
|
||||
var script = document.createElement("script"); //创建一个script标签
|
||||
script.type = "module";
|
||||
script.src=`js/fullScreenVideo.js?v=${timeStamp}`;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
}
|
||||
|
||||
//创建一个link标签
|
||||
function loadLinkString(){
|
||||
var timeStamp=new Date().getTime();
|
||||
var css = document.createElement("link"); //创建一个script标签
|
||||
css.rel = "stylesheet";
|
||||
css.href=`css/fullScreenVideo.css?v=${timeStamp}`
|
||||
document.getElementsByTagName('head')[0].appendChild(css);
|
||||
$("#video").css("height","720px");
|
||||
|
||||
}
|
||||
loadScriptString();
|
||||
loadLinkString();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 1.9 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 22 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 961 B |
After Width: | Height: | Size: 21 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 17 KiB |
|
@ -0,0 +1,806 @@
|
|||
import {timestampFormat,getParams} from "./timestampFormat.js";
|
||||
import { mqttUrl } from "../config/url.js";
|
||||
window.onload=function(){
|
||||
var slider,sliderInit,layer;
|
||||
layui.use(['slider','layer'], function(){
|
||||
slider= layui.slider;
|
||||
layer = layui.layer;
|
||||
});
|
||||
var sizeLevel=0;//放大等级
|
||||
var videotapeStartTime="";//录像开始时间
|
||||
var videotapeEndTime="";//录像结束时间
|
||||
var startTimeStamp="";
|
||||
var endTimeStamp="";
|
||||
var bApplySign = false;
|
||||
var applyPage=false;
|
||||
var keyCode = 32;
|
||||
var videoTime=60000*10;
|
||||
var cdTimeCountFlag="video";//video跟videotape
|
||||
var cdTimeCount=videoTime;
|
||||
var countDownTimer=null;
|
||||
var channelValue=decodeURI(getParams("id"));
|
||||
var mdDeviceName=decodeURI(getParams("mdDeviceName"));
|
||||
var station=decodeURI(getParams("station"));
|
||||
var title=decodeURI(getParams("mdDeviceName"));
|
||||
var loginUserName=decodeURI(getParams("username"));
|
||||
var power=decodeURI(getParams("power"));
|
||||
var rtmName=channelValue;
|
||||
var client=null;
|
||||
var buffer=[];
|
||||
var mediaRecorder =null;
|
||||
var videoTimer=null;
|
||||
var options = {
|
||||
appid: "78846e9910a846688ab959e0f87034e5",
|
||||
channel: channelValue,
|
||||
uid: '',
|
||||
token: null
|
||||
};
|
||||
var client=AgoraRTC.createClient({mode: 'live',codec: "vp8"});
|
||||
var remoteUsers = {};
|
||||
let localTracks = {
|
||||
audioTrack: true
|
||||
};
|
||||
var videowatchingTimer=null;
|
||||
$("html>head>title").html(title);
|
||||
videoJoin();
|
||||
setPower(power);
|
||||
|
||||
|
||||
function setPower(power){
|
||||
if(power=="null"){
|
||||
power=0;
|
||||
}
|
||||
if(power>=90){
|
||||
var img="images/power100.png";
|
||||
}else if(power>=70){
|
||||
var img="images/power80.png";
|
||||
}else if(power>=50){
|
||||
var img="images/power60.png";
|
||||
}else if(power>=30){
|
||||
var img="images/power40.png";
|
||||
}else if(power>=10){
|
||||
var img="images/power20.png";
|
||||
}else{
|
||||
var img="images/power0.png";
|
||||
}
|
||||
$(".power>span").html(power+"%");
|
||||
$(".power>img").attr("src",img);
|
||||
}
|
||||
|
||||
function closePage(){
|
||||
leaveChannel();//我先离开频道
|
||||
var obj=getRtmData("videoclose","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
window.close();
|
||||
}
|
||||
|
||||
async function leaveChannel() {
|
||||
// leave the channel
|
||||
await client.leave();
|
||||
if(videowatchingTimer!=null){
|
||||
clearInterval(videowatchingTimer);
|
||||
videowatchingTimer=null;
|
||||
}
|
||||
}
|
||||
|
||||
//关闭并退出
|
||||
$(".videoNav>.nav>img:nth-child(1)").on('click',function(){
|
||||
resetParentPlayPage();
|
||||
})
|
||||
|
||||
//重置父页面的播放页面
|
||||
function resetParentPlayPage(){
|
||||
var param = {
|
||||
"sender":"children",
|
||||
"receiver":"parent",
|
||||
"deviceid":channelValue,
|
||||
"cmd":"closePage"
|
||||
};
|
||||
window.parent.postMessage(param,'*');
|
||||
closePage();
|
||||
}
|
||||
|
||||
|
||||
window.addEventListener('message', function(e) {
|
||||
var data=e.data
|
||||
var cmd=data["cmd"];
|
||||
var deviceid=data["deviceid"]
|
||||
if(cmd=="videoclose"){
|
||||
if(channelValue==deviceid){
|
||||
closePage();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//如果在全屏
|
||||
function confClosePage(){
|
||||
var url=window.location.href;
|
||||
if(url.indexOf("fullScreenVideo")==-1){
|
||||
closePage();
|
||||
}
|
||||
}
|
||||
|
||||
window.onresize = function () {
|
||||
var w=parseFloat(window.innerWidth);
|
||||
var h=parseFloat(window.innerHeight - 40);
|
||||
switch(sizeLevel){
|
||||
case 1:
|
||||
setVideoSize1280(w,h);
|
||||
break;
|
||||
case 2:
|
||||
setVideoSize720(w,h);
|
||||
break;
|
||||
case 3:
|
||||
setVideoSize480(w,h);
|
||||
break;
|
||||
case 4:
|
||||
setVideoSize640(w,h);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//1280*720
|
||||
function setVideoSize1280(w,h){
|
||||
var f=parseFloat(h/w);
|
||||
if(f >= 0.5625){
|
||||
var width=w;
|
||||
var height=width*0.5625;
|
||||
var x= 0;
|
||||
var y=parseFloat(h-height)/2;
|
||||
}else{
|
||||
var height=h;
|
||||
var width=(height*16)/9;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y= 0;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
//720*1280
|
||||
function setVideoSize720(w,h){
|
||||
var f=parseFloat(w/h);
|
||||
if(f>=0.5625){
|
||||
var height=h;
|
||||
var width=h*0.5625;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y=0;
|
||||
}else{
|
||||
var width=w;
|
||||
var height=(w*16)/9;
|
||||
var x=0;
|
||||
var y=parseFloat(h-height)/2;;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
//480*640
|
||||
function setVideoSize480(w,h){//宽度是480px;height:640px;
|
||||
var f=parseFloat(w/h);
|
||||
if(f>=0.75){
|
||||
var height=h;
|
||||
var width=h*0.75;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y=0;
|
||||
}else{
|
||||
var width=w;
|
||||
var height=(w*4)/3;
|
||||
var x=0;
|
||||
var y=parseFloat(h-height)/2;;
|
||||
}
|
||||
setPageSize(0,0,120,160)
|
||||
}
|
||||
|
||||
//640*480
|
||||
function setVideoSize640(w,h){
|
||||
var f=parseFloat(h/w);
|
||||
if(f >= 0.75){
|
||||
var width=w;
|
||||
var height=width*0.75;
|
||||
var x= 0;
|
||||
var y=parseFloat(h-height)/2;
|
||||
}else{
|
||||
var height=h;
|
||||
var width=(height*4)/3;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y= 0;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
function setPageSize(x,y,width,height){
|
||||
$("#video").css("width",width+"px");
|
||||
$("#video").css("height",height+"px");
|
||||
$("#video").css("left",x);
|
||||
$("#video").css("top",y);
|
||||
}
|
||||
|
||||
$(".videoFullscreen").unbind('click');
|
||||
$(".videoFullscreen").click(function(){
|
||||
//投一个新的屏幕出去
|
||||
var width=1280;
|
||||
var height=720;
|
||||
window.open("fullScreenVideo.html?id="+encodeURI(channelValue)+"&power="+encodeURI(power)+"&mdDeviceName="+encodeURI(encodeURI(mdDeviceName))+"&station="+encodeURI(encodeURI(station))+"&title="+encodeURI(encodeURI(title))+"&username="+loginUserName,"","width="+width+",height="+height+",top=0,left=0");
|
||||
})
|
||||
|
||||
//打开声音
|
||||
function openMute(select){
|
||||
$(select).attr("src","images/openMute.png");
|
||||
$(select).attr("title","音量");
|
||||
$(select).attr("mute","open");
|
||||
}
|
||||
|
||||
//关闭声音
|
||||
function closeMute(select){
|
||||
$(select).attr("src","images/closeMute.png");
|
||||
$(select).attr("title","静音");
|
||||
$(select).attr("mute","close");
|
||||
}
|
||||
|
||||
//初始化声音
|
||||
function videoSlideInit(){
|
||||
sliderInit=slider.render({
|
||||
elem: '#slideTest1',
|
||||
change: function(value){
|
||||
var select=$(".closeMute");
|
||||
if(value==0){
|
||||
closeMute(select);
|
||||
}else{
|
||||
openMute(select);
|
||||
}
|
||||
setRemoteUserMute(value*10);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setRemoteUserMute(value){
|
||||
for(var user in remoteUsers){
|
||||
remoteUsers[user].audioTrack.setVolume(value);
|
||||
}
|
||||
}
|
||||
|
||||
let cameraid=0;
|
||||
let rotateid=0;
|
||||
//摄像图的操作
|
||||
$(".carmeOper").on('click',function(){
|
||||
rotateid=parseInt($(this).attr("rotate"));
|
||||
$(".carmeOper").removeClass("bgColor");
|
||||
$(this).addClass("bgColor")
|
||||
sendCarmeOper();
|
||||
})
|
||||
|
||||
//摄像头的方向调整
|
||||
$(".carmeDir").on('click',function(){
|
||||
let dir=$(this).attr("dir");
|
||||
cameraid=dir;
|
||||
if(dir=="0"){
|
||||
$(this).attr("dir","1");
|
||||
$(this).html("后");
|
||||
}else{
|
||||
$(this).attr("dir","0");
|
||||
$(this).html("前");
|
||||
}
|
||||
sendCarmeOper();
|
||||
})
|
||||
|
||||
function sendCarmeOper(){
|
||||
var obj=getRtmData("videoclose","");
|
||||
sendMqttData(obj);
|
||||
setTimeout(()=>{
|
||||
let data={
|
||||
"rtmpflag":0,
|
||||
"camera":cameraid,
|
||||
"rotation":rotateid
|
||||
}
|
||||
var obj=getRtmData("videocall",JSON.stringify(data));
|
||||
sendMqttData(obj);
|
||||
videoInfoWind();
|
||||
},4000)
|
||||
}
|
||||
|
||||
//调节音量大小
|
||||
$(".closeMute").click(function(){
|
||||
var mute=$(this).attr("mute");
|
||||
if(mute=="open"){
|
||||
setRemoteUserMute(0)
|
||||
sliderInit.setValue(0) //设置开始值
|
||||
closeMute(this);
|
||||
}else{
|
||||
setRemoteUserMute(1000)
|
||||
sliderInit.setValue(100) //设置开始值
|
||||
openMute(this);
|
||||
}
|
||||
})
|
||||
|
||||
async function videoJoin() {
|
||||
//订阅用户推送流
|
||||
client.on("user-published", handleUserPublished);
|
||||
//订阅用户取消推流
|
||||
client.on("user-unpublished", handleUserUnpublished);
|
||||
try {
|
||||
// join a channel and create local tracks, we can use Promise.all to run them concurrently
|
||||
[ options.uid] = await Promise.all([
|
||||
// join the channel
|
||||
client.join(options.appid, options.channel, options.token || null),
|
||||
]);
|
||||
} catch (e) {
|
||||
console.log("加入频道失败", e);
|
||||
}
|
||||
// 使用 Web SDK 4.x,服务器频道禁用以后,客服端需要退出页面跟频道
|
||||
client.on("connection-state-change", (curState, prevState) => {
|
||||
closePage();
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
async function subscribe(user, mediaType) {
|
||||
const uid = user.uid;
|
||||
// subscribe to a remote user
|
||||
await client.subscribe(user, mediaType);
|
||||
if (mediaType === 'video') {
|
||||
const player = $(`
|
||||
<div id="player-${uid}" class="player"></div>
|
||||
`);
|
||||
$("#agora_local").append(player);
|
||||
user.videoTrack.play(`player-${uid}`);
|
||||
//设置视频数据
|
||||
setVideoData();
|
||||
//初始化视频的尺寸
|
||||
videoInfoWind();
|
||||
|
||||
if(videowatchingTimer==null){
|
||||
setInterval(function(){
|
||||
var obj=getRtmData("videowatching","");
|
||||
sendMqttData(obj)
|
||||
//每隔1分钟发送发送1个不关闭视频的指令
|
||||
},60000)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
if(mediaType === 'audio'){
|
||||
setRemoteUserMute(0);
|
||||
//初始化音量
|
||||
videoSlideInit();
|
||||
user.audioTrack.play();
|
||||
}
|
||||
}
|
||||
|
||||
function handleUserPublished(user, mediaType) {
|
||||
const id = user.uid;
|
||||
remoteUsers[id] = user;
|
||||
subscribe(user, mediaType);
|
||||
}
|
||||
|
||||
function handleUserUnpublished(user) {
|
||||
const id = user.uid;
|
||||
delete remoteUsers[id];
|
||||
$(`#player-wrapper-${id}`).remove();
|
||||
resetParentPlayPage();
|
||||
}
|
||||
|
||||
|
||||
function setVideoData(){
|
||||
setInterval(()=>{
|
||||
var evt=client.getRemoteVideoStats();
|
||||
if(JSON.stringify(evt)!="{}"){
|
||||
for(var j in evt){
|
||||
var packetLossRate=evt[j]["packetLossRate"]
|
||||
var receiveBitrate=parseFloat(evt[j]["receiveBitrate"]/1024).toFixed(2);
|
||||
var receiveFrameRate=evt[j]["receiveFrameRate"]
|
||||
var totalDuration=evt[j]["totalDuration"]
|
||||
var totalFreezeTime=evt[j]["totalFreezeTime"]
|
||||
var transportDelay=evt[j]["transportDelay"]
|
||||
$(".PacketLossRate").html(packetLossRate);
|
||||
$(".RecvBitrate").html(receiveBitrate);
|
||||
$(".RenderFrameRate").html(receiveFrameRate);
|
||||
$(".TotalPlayDuration").html(totalDuration);
|
||||
$(".TotalFreezeTime").html(totalFreezeTime);
|
||||
$(".TransportDelay").html(transportDelay);
|
||||
}
|
||||
}
|
||||
},1000)
|
||||
}
|
||||
|
||||
function videoInfoWind(){
|
||||
videoTimer=setInterval(() => {
|
||||
var evt=client.getRemoteVideoStats();
|
||||
if(JSON.stringify(evt)!="{}"){
|
||||
for(var i in evt){
|
||||
if("receiveResolutionHeight" in evt[i]){
|
||||
var RecvResolutionHeight=evt[i]["receiveResolutionHeight"];
|
||||
}
|
||||
if("receiveResolutionWidth" in evt[i]){
|
||||
var RecvResolutionWidth=evt[i]["receiveResolutionWidth"];
|
||||
}
|
||||
if((RecvResolutionWidth!="0"&&RecvResolutionHeight!="0")&&(RecvResolutionWidth!=undefined&&RecvResolutionHeight!=undefined)){
|
||||
clearInterval(videoTimer);
|
||||
var width=RecvResolutionWidth;
|
||||
var height=parseFloat(RecvResolutionHeight);
|
||||
if(RecvResolutionWidth=="1280"&&RecvResolutionHeight=="720"){
|
||||
sizeLevel=1;
|
||||
}else if(RecvResolutionWidth=="720"&&RecvResolutionHeight=="1280"){
|
||||
if(window.screen.height+200<=height){
|
||||
width=width*0.8;
|
||||
height=height*0.8;
|
||||
}
|
||||
sizeLevel=2;
|
||||
window.resizeTo(width,height);
|
||||
}else if(RecvResolutionWidth=="480"&&RecvResolutionHeight=="640"){
|
||||
sizeLevel=3;
|
||||
window.resizeTo("480","640");
|
||||
}else if(RecvResolutionWidth=="640"&&RecvResolutionHeight=="480"){
|
||||
sizeLevel=4;
|
||||
window.resizeTo(RecvResolutionWidth,RecvResolutionHeight);
|
||||
}
|
||||
var param={
|
||||
"deviceid":channelValue,
|
||||
"cmd":"videoloadedSuccess",
|
||||
"data":{
|
||||
w:width,
|
||||
h:height
|
||||
}
|
||||
}
|
||||
console.log(param);
|
||||
parent.postMessage(param,'*');
|
||||
//启动倒计时
|
||||
downTime30();
|
||||
}
|
||||
}
|
||||
}
|
||||
},1000)
|
||||
}
|
||||
|
||||
//设置stream
|
||||
function setRecStream(){
|
||||
let mediaStream = new MediaStream();
|
||||
console.log(mediaStream);
|
||||
for(var user in remoteUsers){
|
||||
mediaStream.addTrack(remoteUsers[user].videoTrack.getMediaStreamTrack())
|
||||
mediaStream.addTrack(remoteUsers[user].audioTrack.getMediaStreamTrack())
|
||||
}
|
||||
window.stream=mediaStream;
|
||||
}
|
||||
|
||||
//开启远程录像
|
||||
$(".startRecording").unbind();
|
||||
$(".startRecording").click(function(){
|
||||
var recordState=$(this).attr("state");
|
||||
if(recordState=="open"){
|
||||
setRecStream();
|
||||
startRecord();
|
||||
startTimeStamp=new Date().getTime();
|
||||
videotapeStartTime=timestampFormat();
|
||||
$(this).attr("state","close");
|
||||
$(this).attr("src","images/endRecording.png");
|
||||
$(this).attr("title","结束录像");
|
||||
layer.msg("录像开启成功");
|
||||
$(".inTheVideo").css("display","block");
|
||||
cdTimeCountFlag="videotape";
|
||||
downTime30();
|
||||
}else{
|
||||
endTimeStamp=new Date().getTime();
|
||||
videotapeEndTime=timestampFormat();
|
||||
stopRecord();
|
||||
cdTimeCount=videoTime;
|
||||
clearInterval(countDownTimer);
|
||||
countDownTimer=null;
|
||||
cdTimeCountFlag="video";
|
||||
}
|
||||
})
|
||||
|
||||
//视频信息
|
||||
$(".videoReInfo").on('click',function(){
|
||||
var state=$(this).attr("state");
|
||||
if(state=="close"){
|
||||
$(this).attr("state","open");
|
||||
$(".videoInfo").css("display","block");
|
||||
|
||||
|
||||
}else{
|
||||
$(this).attr("state","close");
|
||||
$(".videoInfo").css("display","none");
|
||||
}
|
||||
})
|
||||
|
||||
//分享
|
||||
$(".videoShare").on('click',function(){
|
||||
var state=$(this).attr("state");
|
||||
if(state=="close"){
|
||||
$(this).attr("state","open");
|
||||
$("#qrcode").css("display","block");
|
||||
|
||||
|
||||
}else{
|
||||
$(this).attr("state","close");
|
||||
$("#qrcode").css("display","none");
|
||||
}
|
||||
})
|
||||
|
||||
async function setClientHost(){
|
||||
//设置成主播
|
||||
await client.setClientRole("host");
|
||||
try {
|
||||
// join a channel and create local tracks, we can use Promise.all to run them concurrently
|
||||
[localTracks.audioTrack] = await Promise.all([
|
||||
// create local tracks, using microphone and camera
|
||||
AgoraRTC.createMicrophoneAudioTrack()
|
||||
]);
|
||||
await client.publish(Object.values(localTracks));
|
||||
} catch (e) {
|
||||
console.log("加入频道失败", e);
|
||||
}
|
||||
}
|
||||
async function setClientAudience(){
|
||||
//先调用取消发布,在设置成观众
|
||||
await client.unpublish(Object.values(localTracks));
|
||||
await client.setClientRole("audience");
|
||||
}
|
||||
|
||||
//开启对讲
|
||||
$(".videoWalk").unbind();
|
||||
$(".videoWalk").click(function(){
|
||||
var state=$(this).attr("state");
|
||||
if(state=="close"){
|
||||
//开启
|
||||
$(this).attr("state","open");
|
||||
$(this).attr("src","images/videoWalkOnline.png");
|
||||
applyPage=true;
|
||||
bApplySign=true;
|
||||
setClientHost();
|
||||
}else{
|
||||
applyPage=false;
|
||||
bApplySign=false;
|
||||
//关闭
|
||||
$(this).attr("state","close");
|
||||
$(this).attr("src","images/videoWalk.png");
|
||||
setClientAudience();
|
||||
}
|
||||
})
|
||||
|
||||
//键盘松开
|
||||
document.onkeyup = function (event) {
|
||||
var e = event || window.event || arguments.callee.caller.arguments[0];
|
||||
if(applyPage){
|
||||
if(e && e.keyCode == keyCode&&!bApplySign) {
|
||||
bApplySign = true;
|
||||
//关闭麦克风
|
||||
localTracks.audioTrack.setEnabled(false);
|
||||
//开启远程的声音
|
||||
setRemoteUserMute(100);
|
||||
var select=$(".closeMute");
|
||||
openMute(select);
|
||||
sliderInit.setValue(100) //设置开始值
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//键盘按下
|
||||
document.onkeydown = function (event) {
|
||||
var e = event || window.event || arguments.callee.caller.arguments[0];
|
||||
if(applyPage){
|
||||
if(e && e.keyCode == keyCode&&bApplySign) {
|
||||
bApplySign = false;
|
||||
//启用麦克风
|
||||
localTracks.audioTrack.setEnabled(true);
|
||||
//关闭远程的声音
|
||||
setRemoteUserMute(0);
|
||||
//页面状态改变
|
||||
sliderInit.setValue(0) //设置开始值
|
||||
var select=$(".closeMute");
|
||||
closeMute(select);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//截图,并且把图片保存在云端
|
||||
$(".videoImg").click(function(){
|
||||
var video=document.querySelector(".agora_video_player");
|
||||
var canvas=document.getElementById('canvas');
|
||||
if(video!=null){
|
||||
$(".canvasImg").css("display","block");
|
||||
canvas.width=video.videoWidth;
|
||||
canvas.height=video.videoHeight;
|
||||
canvas.getContext('2d').drawImage(video,0,0,canvas.width,canvas.height);
|
||||
var image = canvas . toDataURL ("image/png") ;
|
||||
$(".canvasImgBox").css("width",canvas.width*0.3+"px");
|
||||
$(".canvasImgBox").css("height",canvas.height*0.3+"px");
|
||||
document.getElementById("save").href=image;
|
||||
document.getElementById("save").download=mdDeviceName+".jpg";
|
||||
document.getElementById('save').onclick=function(){
|
||||
|
||||
$(".canvasImg").css("display","none");
|
||||
}
|
||||
document.getElementById('cancel').onclick=function(){
|
||||
$(".canvasImg").css("display","none");
|
||||
}
|
||||
}else{
|
||||
layer.msg("用户已离开,无法截图");
|
||||
}
|
||||
})
|
||||
|
||||
function closeVideoStream(){
|
||||
var obj=getRtmData("videoclose","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//倒计时30分钟以后关闭录像,告诉用户,录像已经完成
|
||||
/*************************观看视频为5分钟1次,如果不点击确定,就会关闭***********************************/
|
||||
function downTime30(){
|
||||
if(countDownTimer!=null){
|
||||
clearInterval(countDownTimer);
|
||||
}else{
|
||||
countDownTimer=setInterval(function(){
|
||||
cdTimeCount-=1000;
|
||||
if(cdTimeCount<=0){
|
||||
clearInterval(countDownTimer);
|
||||
countDownTimer=null;
|
||||
if(cdTimeCountFlag=="videotape"){
|
||||
endTimeStamp=new Date().getTime();
|
||||
videotapeEndTime=timestampFormat();
|
||||
stopRecord();
|
||||
}else{
|
||||
//倒计时
|
||||
showCountDownTimer();
|
||||
}
|
||||
}
|
||||
},1000);
|
||||
}
|
||||
}
|
||||
|
||||
//倒计时*******************************************
|
||||
var closeTime=10;//倒计时
|
||||
var closePageTimer=null;
|
||||
function showCountDownTimer(){
|
||||
$(".videoTitle").css("display","block");
|
||||
$(".close_ing_time").html(closeTime);
|
||||
videoTitleEvent();
|
||||
closePageTimer=setInterval(function(){
|
||||
closeTime--;
|
||||
$(".close_ing_time").html(closeTime);
|
||||
if(closeTime<=0){
|
||||
closeVideoStream();//发送关闭指令
|
||||
leaveChannel();//离开频道
|
||||
clearInterval(closePageTimer);//退出定时器
|
||||
}
|
||||
},1000);
|
||||
}
|
||||
|
||||
function videoTitleEvent(){
|
||||
$(".videoTitle>p:last-child>button:nth-child(1)").on('click',function(){
|
||||
var obj=getRtmData("videocall","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
$(".videoTitle").css("display","none");
|
||||
clearInterval(closePageTimer);
|
||||
closePageTimer=null;
|
||||
closeTime=10;
|
||||
cdTimeCount=videoTime;
|
||||
//再次加入频道
|
||||
videoJoin()
|
||||
downTime30()
|
||||
})
|
||||
$(".videoTitle>p:last-child>button:nth-child(2)").on('click',function(){
|
||||
closePage();
|
||||
})
|
||||
}
|
||||
|
||||
function handleDataAvailable(e){ // 5、获取数据的事件函数 当我们点击录制之后,数据就会源源不断的从这个事件函数中获取到
|
||||
if(e && e.data && e.data.size > 0){
|
||||
console.log(e.data);
|
||||
buffer.push(e.data); // 将e.data放入二进制数组里面
|
||||
// 这个buffer应该是我们在开始录制的时候创建这个buffer
|
||||
}
|
||||
}
|
||||
|
||||
//开始录像
|
||||
function startRecord(){
|
||||
buffer = []; // 定义数组
|
||||
if (typeof MediaRecorder.isTypeSupported == 'function') {
|
||||
if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
|
||||
var options = {
|
||||
mimeType: 'video/webm;codecs=vp9,opus'
|
||||
}
|
||||
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
|
||||
var options = {
|
||||
mimeType:'video/webm;codecs=vp9,opus'
|
||||
};
|
||||
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) {
|
||||
var options = {
|
||||
mimeType:'video/webm;codecs=h264,opus'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if(!MediaRecorder.isTypeSupported(options.mimeType)){ // 判断录制的视频 mimeType 格式浏览器是否支持
|
||||
return;
|
||||
}
|
||||
|
||||
try{ // 防止录制异常
|
||||
// 5、先在上面定义全局对象mediaRecorder,以便于后面停止录制的时候可以用到
|
||||
mediaRecorder = new MediaRecorder(window.stream, options); // 调用录制API // window.stream在gotMediaStream中获取
|
||||
//4、调用事件 这个事件处理函数里面就会收到我们录制的那块数据 当我们收集到这个数据之后我们应该把它存储起来
|
||||
mediaRecorder.ondataavailable = handleDataAvailable;
|
||||
mediaRecorder.start(10); // start方法里面传入一个时间片,每隔一个 时间片存储 一块数据
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//停止录制
|
||||
function stopRecord(){
|
||||
//6、调用停止录制
|
||||
try{
|
||||
mediaRecorder.stop();
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
$(".startRecording").attr("state","open");
|
||||
$(".startRecording").attr("src","images/startRecording.png");
|
||||
$(this).attr("title","开始录像");
|
||||
layer.msg('录像已保存', {
|
||||
time: false, //20s后自动关闭
|
||||
btn: ['知道了']
|
||||
});
|
||||
|
||||
$(".inTheVideo").css("display","none");
|
||||
var tmpBlob = new Blob(buffer, {type: 'video/webm'});
|
||||
var duration=endTimeStamp-startTimeStamp;
|
||||
//调用设置时长代码。该函数基于fix-webm-duration.js
|
||||
ysFixWebmDuration(tmpBlob, duration, function (fixedBlob) {
|
||||
var recorderFile = fixedBlob;
|
||||
let name =`${mdDeviceName}(${videotapeStartTime}---${videotapeEndTime}).mp4`;
|
||||
var url = window.URL.createObjectURL(recorderFile);
|
||||
var a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.style.display = 'none';
|
||||
a.download = name;
|
||||
a.click();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
//构建rtm发送对象
|
||||
function getRtmData(title,data){
|
||||
return {
|
||||
"title":title,
|
||||
"sender":loginUserName,
|
||||
"department":"",
|
||||
"scope":"",
|
||||
"receiver":[rtmName],
|
||||
"video":"",
|
||||
"rtm":(new Date().getTime()).toString(),
|
||||
"data":data,
|
||||
"userScope":"",
|
||||
"userBragide":"",
|
||||
"userDetachchment":"",
|
||||
"userBorough":"",
|
||||
"name":"",
|
||||
}
|
||||
}
|
||||
|
||||
//发送mqqt接口数据
|
||||
function sendMqttData(obj){
|
||||
var mqttObj={
|
||||
"topic":`${station}/ter_cmd`,
|
||||
"message":JSON.stringify(obj)
|
||||
}
|
||||
$.ajax({
|
||||
url: mqttUrl,
|
||||
type: "post",
|
||||
dataType: "json",
|
||||
headers: {
|
||||
"Content-Type": "application/json;charset=utf-8"
|
||||
},
|
||||
data: JSON.stringify(mqttObj),
|
||||
success: function(d) {
|
||||
//console.error(d);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,798 @@
|
|||
import {timestampFormat,getParams,fullScreen,exitFullscreen} from "./timestampFormat.js";
|
||||
import { mqttUrl } from "../config/url.js";
|
||||
window.onload=function(){
|
||||
var locationUrl=window.location.href;
|
||||
var slider,sliderInit,layer;
|
||||
layui.use(['slider','layer'], function(){
|
||||
slider= layui.slider;
|
||||
layer = layui.layer;
|
||||
});
|
||||
var sizeLevel=0;//放大等级
|
||||
var videotapeStartTime="";//录像开始时间
|
||||
var videotapeEndTime="";//录像结束时间
|
||||
var startTimeStamp="";
|
||||
var endTimeStamp="";
|
||||
var bApplySign = false;
|
||||
var applyPage=false;
|
||||
var keyCode = 32;
|
||||
var videoTime=60000*12000;
|
||||
var cdTimeCountFlag="video";//video跟videotape
|
||||
var cdTimeCount=videoTime;
|
||||
var countDownTimer=null;
|
||||
var channelValue=decodeURI(getParams("id"));
|
||||
var mdDeviceName=decodeURI(getParams("mdDeviceName"));
|
||||
var station=decodeURI(getParams("station"));
|
||||
var title=decodeURI(getParams("mdDeviceName"));
|
||||
var loginUserName=decodeURI(getParams("username"));
|
||||
var power=decodeURI(getParams("power"));
|
||||
var rtmName=channelValue;
|
||||
var client=null;
|
||||
var buffer=[];
|
||||
var mediaRecorder =null;
|
||||
var videoTimer=null;
|
||||
var options = {
|
||||
appid: "78846e9910a846688ab959e0f87034e5",
|
||||
channel: channelValue,
|
||||
uid: '',
|
||||
token: null
|
||||
};
|
||||
var client=AgoraRTC.createClient({mode: 'live',codec: "vp8"});
|
||||
var remoteUsers = {};
|
||||
let localTracks = {
|
||||
audioTrack: true
|
||||
};
|
||||
$("html>head>title").html(title);
|
||||
videoJoin();
|
||||
setPower(power);
|
||||
function setPower(power){
|
||||
if(power=="null"){
|
||||
power=0;
|
||||
}
|
||||
if(power>=90){
|
||||
var img="images/power100.png";
|
||||
}else if(power>=70){
|
||||
var img="images/power80.png";
|
||||
}else if(power>=50){
|
||||
var img="images/power60.png";
|
||||
}else if(power>=30){
|
||||
var img="images/power40.png";
|
||||
}else if(power>=10){
|
||||
var img="images/power20.png";
|
||||
}else{
|
||||
var img="images/power0.png";
|
||||
}
|
||||
$(".power>span").html(power+"%");
|
||||
$(".power>img").attr("src",img);
|
||||
}
|
||||
|
||||
function closePage(){
|
||||
leaveChannel();//我先离开频道
|
||||
var obj=getRtmData("videoclose","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
window.close();
|
||||
}
|
||||
|
||||
async function leaveChannel() {
|
||||
// leave the channel
|
||||
await client.leave();
|
||||
}
|
||||
|
||||
//关闭并退出
|
||||
$(".videoNav>.nav>img:nth-child(1)").click(function(){
|
||||
var param = {
|
||||
"sender":"children",
|
||||
"receiver":"parent",
|
||||
"deviceid":channelValue,
|
||||
"cmd":"closePage"
|
||||
};
|
||||
window.parent.postMessage(param,'*');
|
||||
closePage();
|
||||
})
|
||||
|
||||
window.addEventListener('message', function(e) {
|
||||
var data=e.data
|
||||
var cmd=data["cmd"];
|
||||
var deviceid=data["deviceid"]
|
||||
if(cmd=="videoclose"){
|
||||
if(channelValue==deviceid){
|
||||
closePage();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//如果在全屏
|
||||
function confClosePage(){
|
||||
var url=window.location.href;
|
||||
if(url.indexOf("fullScreenVideo")==-1){
|
||||
closePage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.onbeforeunload=function(e){
|
||||
if(locationUrl.indexOf("videoMoitorShow")==-1){
|
||||
confClosePage();
|
||||
}
|
||||
}
|
||||
|
||||
window.onresize = function () {
|
||||
var w=parseFloat(window.innerWidth);
|
||||
var h=parseFloat(window.innerHeight - 40);
|
||||
switch(sizeLevel){
|
||||
case 1:
|
||||
setVideoSize1280(w,h);
|
||||
break;
|
||||
case 2:
|
||||
setVideoSize720(w,h);
|
||||
break;
|
||||
case 3:
|
||||
setVideoSize480(w,h);
|
||||
break;
|
||||
case 4:
|
||||
setVideoSize640(w,h);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//1280*720
|
||||
function setVideoSize1280(w,h){
|
||||
var f=parseFloat(h/w);
|
||||
if(f >= 0.5625){
|
||||
var width=w;
|
||||
var height=width*0.5625;
|
||||
var x= 0;
|
||||
var y=parseFloat(h-height)/2;
|
||||
}else{
|
||||
var height=h;
|
||||
var width=(height*16)/9;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y= 0;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
//720*1280
|
||||
function setVideoSize720(w,h){
|
||||
var f=parseFloat(w/h);
|
||||
if(f>0.5625){
|
||||
var height=h;
|
||||
var width=h*0.5625;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y=0;
|
||||
}else{
|
||||
var width=w;
|
||||
var height=(w*16)/9;
|
||||
var x=0;
|
||||
var y=parseFloat(h-height)/2;;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
|
||||
//480*640
|
||||
function setVideoSize480(w,h){//宽度是480px;height:640px;
|
||||
var f=parseFloat(w/h);
|
||||
if(f>0.75){
|
||||
var height=h;
|
||||
var width=h*0.75;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y=0;
|
||||
}else{
|
||||
var width=w;
|
||||
var height=(w*4)/3;
|
||||
var x=0;
|
||||
var y=parseFloat(h-height)/2;;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
//640*480
|
||||
function setVideoSize640(w,h){
|
||||
var f=parseFloat(h/w);
|
||||
if(f >= 0.75){
|
||||
var width=w;
|
||||
var height=width*0.75;
|
||||
var x= 0;
|
||||
var y=parseFloat(h-height)/2;
|
||||
}else{
|
||||
var height=h;
|
||||
var width=(height*4)/3;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y= 0;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
|
||||
|
||||
function setPageSize(x,y,width,height){
|
||||
$("#video").css("width",width+"px");
|
||||
$("#video").css("height",height+"px");
|
||||
$("#video").css("left",x);
|
||||
$("#video").css("top",y);
|
||||
}
|
||||
|
||||
$(".videoFullscreen").unbind('click');
|
||||
$(".videoFullscreen").click(function(){
|
||||
|
||||
console.log(123456);
|
||||
|
||||
var url=window.location.href;
|
||||
if(url.indexOf("alarmDeviceVideo")!=-1){
|
||||
//投一个新的屏幕出去
|
||||
var width=1280;
|
||||
var height=760;
|
||||
window.open("fullScreenVideo.html?id="+encodeURI(channelValue)+"&power="+encodeURI(power)+"&mdDeviceName="+encodeURI(encodeURI(mdDeviceName))+"&station="+encodeURI(encodeURI(station))+"&title="+encodeURI(encodeURI(title))+"&username="+loginUserName,"","width="+width+",height="+height+",top=0,left=0");
|
||||
}else{
|
||||
var model=$(this).attr("model");
|
||||
if(model=="exitfullScreen"){
|
||||
fullScreen()
|
||||
$(this).attr("src","images/videoExitFullscreen.png").attr("model","fullScreen").attr("title","退出全屏")
|
||||
}else{
|
||||
exitFullscreen()
|
||||
$(this).attr("src","images/videoFullscreen.png").attr("model","exitfullScreen").attr("title","全屏");
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//打开声音
|
||||
function openMute(select){
|
||||
$(select).attr("src","images/openMute.png");
|
||||
$(select).attr("title","音量");
|
||||
$(select).attr("mute","open");
|
||||
}
|
||||
|
||||
//关闭声音
|
||||
function closeMute(select){
|
||||
$(select).attr("src","images/closeMute.png");
|
||||
$(select).attr("title","静音");
|
||||
$(select).attr("mute","close");
|
||||
}
|
||||
|
||||
//初始化声音
|
||||
function videoSlideInit(){
|
||||
sliderInit=slider.render({
|
||||
elem: '#slideTest1',
|
||||
change: function(value){
|
||||
var select=$(".closeMute");
|
||||
if(value==0){
|
||||
closeMute(select);
|
||||
}else{
|
||||
openMute(select);
|
||||
}
|
||||
setRemoteUserMute(value*10);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setRemoteUserMute(value){
|
||||
for(var user in remoteUsers){
|
||||
remoteUsers[user].audioTrack.setVolume(value);
|
||||
}
|
||||
}
|
||||
|
||||
let cameraid=0;
|
||||
let rotateid=0;
|
||||
//摄像图的操作
|
||||
$(".carmeOper").on('click',function(){
|
||||
rotateid=parseInt($(this).attr("rotate"));
|
||||
$(".carmeOper").removeClass("bgColor");
|
||||
$(this).addClass("bgColor")
|
||||
sendCarmeOper();
|
||||
})
|
||||
|
||||
//摄像头的方向调整
|
||||
$(".carmeDir").on('click',function(){
|
||||
let dir=$(this).attr("dir");
|
||||
cameraid=dir;
|
||||
if(dir=="0"){
|
||||
$(this).attr("dir","1");
|
||||
$(this).html("后");
|
||||
}else{
|
||||
$(this).attr("dir","0");
|
||||
$(this).html("前");
|
||||
}
|
||||
sendCarmeOper();
|
||||
})
|
||||
|
||||
function sendCarmeOper(){
|
||||
var obj=getRtmData("videoclose","");
|
||||
sendMqttData(obj);
|
||||
setTimeout(()=>{
|
||||
let data={
|
||||
"rtmpflag":0,
|
||||
"camera":cameraid,
|
||||
"rotation":rotateid
|
||||
}
|
||||
var obj=getRtmData("videocall",JSON.stringify(data));
|
||||
sendMqttData(obj);
|
||||
videoInfoWind();
|
||||
},4000)
|
||||
}
|
||||
|
||||
//调节音量大小
|
||||
$(".closeMute").click(function(){
|
||||
var mute=$(this).attr("mute");
|
||||
if(mute=="open"){
|
||||
setRemoteUserMute(0)
|
||||
sliderInit.setValue(0) //设置开始值
|
||||
closeMute(this);
|
||||
}else{
|
||||
setRemoteUserMute(1000)
|
||||
sliderInit.setValue(100) //设置开始值
|
||||
openMute(this);
|
||||
}
|
||||
})
|
||||
|
||||
async function videoJoin() {
|
||||
//订阅用户推送流
|
||||
client.on("user-published", handleUserPublished);
|
||||
//订阅用户取消推流
|
||||
client.on("user-unpublished", handleUserUnpublished);
|
||||
try {
|
||||
// join a channel and create local tracks, we can use Promise.all to run them concurrently
|
||||
[ options.uid] = await Promise.all([
|
||||
// join the channel
|
||||
client.join(options.appid, options.channel, options.token || null),
|
||||
]);
|
||||
} catch (e) {
|
||||
console.log("加入频道失败", e);
|
||||
}
|
||||
// 使用 Web SDK 4.x,服务器频道禁用以后,客服端需要退出页面跟频道
|
||||
client.on("connection-state-change", (curState, prevState) => {
|
||||
closePage();
|
||||
});
|
||||
}
|
||||
|
||||
async function subscribe(user, mediaType) {
|
||||
const uid = user.uid;
|
||||
// subscribe to a remote user
|
||||
await client.subscribe(user, mediaType);
|
||||
if (mediaType === 'video') {
|
||||
const player = $(`
|
||||
<div id="player-${uid}" class="player"></div>
|
||||
`);
|
||||
$("#agora_local").append(player);
|
||||
user.videoTrack.play(`player-${uid}`);
|
||||
//设置视频数据
|
||||
setVideoData();
|
||||
//初始化视频的尺寸
|
||||
videoInfoWind();
|
||||
|
||||
|
||||
setInterval(function(){
|
||||
var obj=getRtmData("videowatching","");
|
||||
sendMqttData(obj)
|
||||
//每隔1分钟发送发送1个不关闭视频的指令
|
||||
},60000)
|
||||
|
||||
}
|
||||
if(mediaType === 'audio'){
|
||||
setRemoteUserMute(0);
|
||||
//初始化音量
|
||||
videoSlideInit();
|
||||
user.audioTrack.play();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleUserPublished(user, mediaType) {
|
||||
const id = user.uid;
|
||||
remoteUsers[id] = user;
|
||||
subscribe(user, mediaType);
|
||||
}
|
||||
|
||||
function handleUserUnpublished(user) {
|
||||
const id = user.uid;
|
||||
delete remoteUsers[id];
|
||||
$(`#player-wrapper-${id}`).remove();
|
||||
}
|
||||
|
||||
|
||||
function setVideoData(){
|
||||
setInterval(()=>{
|
||||
var evt=client.getRemoteVideoStats();
|
||||
if(JSON.stringify(evt)!="{}"){
|
||||
for(var j in evt){
|
||||
var packetLossRate=evt[j]["packetLossRate"]
|
||||
var receiveBitrate=parseFloat(evt[j]["receiveBitrate"]/1024).toFixed(2);
|
||||
var receiveFrameRate=evt[j]["receiveFrameRate"]
|
||||
var totalDuration=evt[j]["totalDuration"]
|
||||
var totalFreezeTime=evt[j]["totalFreezeTime"]
|
||||
var transportDelay=evt[j]["transportDelay"]
|
||||
$(".PacketLossRate").html(packetLossRate);
|
||||
$(".RecvBitrate").html(receiveBitrate);
|
||||
$(".RenderFrameRate").html(receiveFrameRate);
|
||||
$(".TotalPlayDuration").html(totalDuration);
|
||||
$(".TotalFreezeTime").html(totalFreezeTime);
|
||||
$(".TransportDelay").html(transportDelay);
|
||||
}
|
||||
}
|
||||
},1000)
|
||||
}
|
||||
|
||||
function videoInfoWind(){
|
||||
videoTimer=setInterval(() => {
|
||||
var evt=client.getRemoteVideoStats();
|
||||
if(JSON.stringify(evt)!="{}"){
|
||||
for(var i in evt){
|
||||
if("receiveResolutionHeight" in evt[i]){
|
||||
var RecvResolutionHeight=evt[i]["receiveResolutionHeight"];
|
||||
}
|
||||
if("receiveResolutionWidth" in evt[i]){
|
||||
var RecvResolutionWidth=evt[i]["receiveResolutionWidth"];
|
||||
}
|
||||
if((RecvResolutionWidth!="0"&&RecvResolutionHeight!="0")&&(RecvResolutionWidth!=undefined&&RecvResolutionHeight!=undefined)){
|
||||
clearInterval(videoTimer);
|
||||
var width=RecvResolutionWidth;
|
||||
var height=parseFloat(RecvResolutionHeight);
|
||||
if(RecvResolutionWidth=="1280"&&RecvResolutionHeight=="720"){
|
||||
sizeLevel=1;
|
||||
setVideoSize1280(width*0.5,height*0.5);
|
||||
window.resizeTo(width,height);
|
||||
}else if(RecvResolutionWidth=="720"&&RecvResolutionHeight=="1280"){
|
||||
if(window.screen.height+200<=height){
|
||||
width=width*0.8;
|
||||
height=height*0.8;
|
||||
}
|
||||
sizeLevel=2;
|
||||
setVideoSize720(width*0.5,height*0.5);
|
||||
window.resizeTo(width,height);
|
||||
}else if(RecvResolutionWidth=="480"&&RecvResolutionHeight=="640"){
|
||||
sizeLevel=3;
|
||||
setVideoSize480(width*0.5,height*0.5);
|
||||
window.resizeTo("496","750");
|
||||
}else if(RecvResolutionWidth=="640"&&RecvResolutionHeight=="480"){
|
||||
sizeLevel=4;
|
||||
setVideoSize640(width*0.5,height*0.5);
|
||||
window.resizeTo(RecvResolutionWidth,RecvResolutionHeight);
|
||||
}
|
||||
var param={
|
||||
"deviceid":channelValue,
|
||||
"cmd":"videoloadedSuccess"
|
||||
}
|
||||
parent.postMessage(param,'*');
|
||||
//启动倒计时
|
||||
downTime30();
|
||||
}
|
||||
}
|
||||
}
|
||||
},1000)
|
||||
}
|
||||
|
||||
//设置stream
|
||||
function setRecStream(){
|
||||
let mediaStream = new MediaStream();
|
||||
for(var user in remoteUsers){
|
||||
mediaStream.addTrack(remoteUsers[user].videoTrack.getMediaStreamTrack())
|
||||
mediaStream.addTrack(remoteUsers[user].audioTrack.getMediaStreamTrack())
|
||||
}
|
||||
window.stream=mediaStream;
|
||||
}
|
||||
|
||||
//开启远程录像
|
||||
$(".startRecording").unbind();
|
||||
$(".startRecording").click(function(){
|
||||
var recordState=$(this).attr("state");
|
||||
if(recordState=="open"){
|
||||
setRecStream();
|
||||
startRecord();
|
||||
startTimeStamp=new Date().getTime();
|
||||
videotapeStartTime=timestampFormat();
|
||||
$(this).attr("state","close");
|
||||
$(this).attr("src","images/endRecording.png");
|
||||
$(this).attr("title","结束录像");
|
||||
layer.msg("录像开启成功");
|
||||
$(".inTheVideo").css("display","block");
|
||||
cdTimeCountFlag="videotape";
|
||||
downTime30();
|
||||
}else{
|
||||
endTimeStamp=new Date().getTime();
|
||||
videotapeEndTime=timestampFormat();
|
||||
stopRecord();
|
||||
cdTimeCount=videoTime;
|
||||
clearInterval(countDownTimer);
|
||||
countDownTimer=null;
|
||||
cdTimeCountFlag="video";
|
||||
}
|
||||
})
|
||||
|
||||
//视频信息
|
||||
$(".videoReInfo").on('click',function(){
|
||||
var state=$(this).attr("state");
|
||||
if(state=="close"){
|
||||
$(this).attr("state","open");
|
||||
$(".videoInfo").css("display","block");
|
||||
|
||||
|
||||
}else{
|
||||
$(this).attr("state","close");
|
||||
$(".videoInfo").css("display","none");
|
||||
}
|
||||
})
|
||||
|
||||
async function setClientHost(){
|
||||
//设置成主播
|
||||
await client.setClientRole("host");
|
||||
try {
|
||||
// join a channel and create local tracks, we can use Promise.all to run them concurrently
|
||||
[localTracks.audioTrack] = await Promise.all([
|
||||
// create local tracks, using microphone and camera
|
||||
AgoraRTC.createMicrophoneAudioTrack()
|
||||
]);
|
||||
await client.publish(Object.values(localTracks));
|
||||
} catch (e) {
|
||||
console.log("加入频道失败", e);
|
||||
}
|
||||
}
|
||||
async function setClientAudience(){
|
||||
//先调用取消发布,在设置成观众
|
||||
await client.unpublish(Object.values(localTracks));
|
||||
await client.setClientRole("audience");
|
||||
}
|
||||
|
||||
//开启对讲
|
||||
$(".videoWalk").unbind();
|
||||
$(".videoWalk").click(function(){
|
||||
var state=$(this).attr("state");
|
||||
if(state=="close"){
|
||||
//开启
|
||||
$(this).attr("state","open");
|
||||
$(this).attr("src","images/videoWalkOnline.png");
|
||||
applyPage=true;
|
||||
bApplySign=true;
|
||||
setClientHost();
|
||||
}else{
|
||||
applyPage=false;
|
||||
bApplySign=false;
|
||||
//关闭
|
||||
$(this).attr("state","close");
|
||||
$(this).attr("src","images/videoWalk.png");
|
||||
setClientAudience();
|
||||
}
|
||||
})
|
||||
|
||||
//键盘松开
|
||||
document.onkeyup = function (event) {
|
||||
var e = event || window.event || arguments.callee.caller.arguments[0];
|
||||
if(applyPage){
|
||||
if(e && e.keyCode == keyCode&&!bApplySign) {
|
||||
bApplySign = true;
|
||||
//关闭麦克风
|
||||
localTracks.audioTrack.setEnabled(false);
|
||||
//开启远程的声音
|
||||
setRemoteUserMute(100);
|
||||
var select=$(".closeMute");
|
||||
openMute(select);
|
||||
sliderInit.setValue(100) //设置开始值
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//键盘按下
|
||||
document.onkeydown = function (event) {
|
||||
var e = event || window.event || arguments.callee.caller.arguments[0];
|
||||
if(applyPage){
|
||||
if(e && e.keyCode == keyCode&&bApplySign) {
|
||||
bApplySign = false;
|
||||
//启用麦克风
|
||||
localTracks.audioTrack.setEnabled(true);
|
||||
//关闭远程的声音
|
||||
setRemoteUserMute(0);
|
||||
//页面状态改变
|
||||
sliderInit.setValue(0) //设置开始值
|
||||
var select=$(".closeMute");
|
||||
closeMute(select);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//截图,并且把图片保存在云端
|
||||
$(".videoImg").click(function(){
|
||||
var video=document.querySelector(".agora_video_player");
|
||||
var canvas=document.getElementById('canvas');
|
||||
if(video!=null){
|
||||
$(".canvasImg").css("display","block");
|
||||
canvas.width=video.videoWidth;
|
||||
canvas.height=video.videoHeight;
|
||||
canvas.getContext('2d').drawImage(video,0,0,canvas.width,canvas.height);
|
||||
var image = canvas . toDataURL ("image/png") ;
|
||||
$(".canvasImgBox").css("width",canvas.width*0.3+"px");
|
||||
$(".canvasImgBox").css("height",canvas.height*0.3+"px");
|
||||
document.getElementById("save").href=image;
|
||||
document.getElementById("save").download=mdDeviceName+".jpg";
|
||||
document.getElementById('save').onclick=function(){
|
||||
|
||||
$(".canvasImg").css("display","none");
|
||||
}
|
||||
document.getElementById('cancel').onclick=function(){
|
||||
$(".canvasImg").css("display","none");
|
||||
}
|
||||
}else{
|
||||
layer.msg("用户已离开,无法截图");
|
||||
}
|
||||
})
|
||||
|
||||
function closeVideoStream(){
|
||||
var obj=getRtmData("videoclose","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//倒计时30分钟以后关闭录像,告诉用户,录像已经完成
|
||||
/*************************观看视频为5分钟1次,如果不点击确定,就会关闭***********************************/
|
||||
function downTime30(){
|
||||
if(countDownTimer!=null){
|
||||
clearInterval(countDownTimer);
|
||||
}else{
|
||||
countDownTimer=setInterval(function(){
|
||||
cdTimeCount-=1000;
|
||||
if(cdTimeCount<=0){
|
||||
clearInterval(countDownTimer);
|
||||
countDownTimer=null;
|
||||
if(cdTimeCountFlag=="videotape"){
|
||||
endTimeStamp=new Date().getTime();
|
||||
videotapeEndTime=timestampFormat();
|
||||
stopRecord();
|
||||
}else{
|
||||
//倒计时
|
||||
showCountDownTimer();
|
||||
}
|
||||
}
|
||||
},1000);
|
||||
}
|
||||
}
|
||||
|
||||
//倒计时*******************************************
|
||||
var closeTime=10;//倒计时
|
||||
var closePageTimer=null;
|
||||
function showCountDownTimer(){
|
||||
$(".videoTitle").css("display","block");
|
||||
$(".close_ing_time").html(closeTime);
|
||||
videoTitleEvent();
|
||||
closePageTimer=setInterval(function(){
|
||||
closeTime--;
|
||||
$(".close_ing_time").html(closeTime);
|
||||
if(closeTime<=0){
|
||||
closeVideoStream();//发送关闭指令
|
||||
leaveChannel();//离开频道
|
||||
clearInterval(closePageTimer);//退出定时器
|
||||
}
|
||||
},1000);
|
||||
}
|
||||
|
||||
function videoTitleEvent(){
|
||||
$(".videoTitle>p:last-child>button:nth-child(1)").on('click',function(){
|
||||
var obj=getRtmData("videocall","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
$(".videoTitle").css("display","none");
|
||||
clearInterval(closePageTimer);
|
||||
closePageTimer=null;
|
||||
closeTime=10;
|
||||
cdTimeCount=videoTime;
|
||||
//再次加入频道
|
||||
videoJoin()
|
||||
downTime30()
|
||||
})
|
||||
$(".videoTitle>p:last-child>button:nth-child(2)").on('click',function(){
|
||||
closePage();
|
||||
})
|
||||
}
|
||||
|
||||
function handleDataAvailable(e){ // 5、获取数据的事件函数 当我们点击录制之后,数据就会源源不断的从这个事件函数中获取到
|
||||
if(e && e.data && e.data.size > 0){
|
||||
console.log(e.data);
|
||||
buffer.push(e.data); // 将e.data放入二进制数组里面
|
||||
// 这个buffer应该是我们在开始录制的时候创建这个buffer
|
||||
}
|
||||
}
|
||||
|
||||
//开始录像
|
||||
function startRecord(){
|
||||
buffer = []; // 定义数组
|
||||
if (typeof MediaRecorder.isTypeSupported == 'function') {
|
||||
if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
|
||||
var options = {
|
||||
mimeType: 'video/webm;codecs=vp9,opus'
|
||||
}
|
||||
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
|
||||
var options = {
|
||||
mimeType:'video/webm;codecs=vp9,opus'
|
||||
};
|
||||
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) {
|
||||
var options = {
|
||||
mimeType:'video/webm;codecs=h264,opus'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if(!MediaRecorder.isTypeSupported(options.mimeType)){ // 判断录制的视频 mimeType 格式浏览器是否支持
|
||||
return;
|
||||
}
|
||||
|
||||
try{ // 防止录制异常
|
||||
// 5、先在上面定义全局对象mediaRecorder,以便于后面停止录制的时候可以用到
|
||||
mediaRecorder = new MediaRecorder(window.stream, options); // 调用录制API // window.stream在gotMediaStream中获取
|
||||
//4、调用事件 这个事件处理函数里面就会收到我们录制的那块数据 当我们收集到这个数据之后我们应该把它存储起来
|
||||
mediaRecorder.ondataavailable = handleDataAvailable;
|
||||
mediaRecorder.start(0); // start方法里面传入一个时间片,每隔一个 时间片存储 一块数据
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//停止录制
|
||||
function stopRecord(){
|
||||
//6、调用停止录制
|
||||
try{
|
||||
mediaRecorder.stop();
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
$(".startRecording").attr("state","open");
|
||||
$(".startRecording").attr("src","images/startRecording.png");
|
||||
$(this).attr("title","开始录像");
|
||||
layer.msg('录像已保存', {
|
||||
time: false, //20s后自动关闭
|
||||
btn: ['知道了']
|
||||
});
|
||||
|
||||
$(".inTheVideo").css("display","none");
|
||||
var tmpBlob = new Blob(buffer, {type: 'video/webm'});
|
||||
var duration=endTimeStamp-startTimeStamp;
|
||||
//调用设置时长代码。该函数基于fix-webm-duration.js
|
||||
ysFixWebmDuration(tmpBlob, duration, function (fixedBlob) {
|
||||
var recorderFile = fixedBlob;
|
||||
let name =`${mdDeviceName}(${videotapeStartTime}---${videotapeEndTime}).mp4`;
|
||||
var url = window.URL.createObjectURL(recorderFile);
|
||||
var a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.style.display = 'none';
|
||||
a.download = name;
|
||||
a.click();
|
||||
});
|
||||
}
|
||||
//构建rtm发送对象
|
||||
function getRtmData(title,data){
|
||||
return {
|
||||
"title":title,
|
||||
"sender":loginUserName,
|
||||
"department":"",
|
||||
"scope":"",
|
||||
"receiver":[rtmName],
|
||||
"video":"",
|
||||
"rtm":(new Date().getTime()).toString(),
|
||||
"data":data,
|
||||
"userScope":"",
|
||||
"userBragide":"",
|
||||
"userDetachchment":"",
|
||||
"userBorough":"",
|
||||
"name":"",
|
||||
}
|
||||
}
|
||||
|
||||
//发送mqqt接口数据
|
||||
function sendMqttData(obj){
|
||||
var mqttObj={
|
||||
"topic":`${station}/ter_cmd`,
|
||||
"message":JSON.stringify(obj)
|
||||
}
|
||||
$.ajax({
|
||||
url: mqttUrl,
|
||||
type: "post",
|
||||
dataType: "json",
|
||||
headers: {
|
||||
"Content-Type": "application/json;charset=utf-8"
|
||||
},
|
||||
data: JSON.stringify(mqttObj),
|
||||
success: function(d) {
|
||||
//console.error(d);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,798 @@
|
|||
import {timestampFormat,getParams,fullScreen,exitFullscreen} from "./timestampFormat.js";
|
||||
import { mqttUrl } from "../config/url.js";
|
||||
window.onload=function(){
|
||||
var locationUrl=window.location.href;
|
||||
var slider,sliderInit,layer;
|
||||
layui.use(['slider','layer'], function(){
|
||||
slider= layui.slider;
|
||||
layer = layui.layer;
|
||||
});
|
||||
var sizeLevel=0;//放大等级
|
||||
var videotapeStartTime="";//录像开始时间
|
||||
var videotapeEndTime="";//录像结束时间
|
||||
var startTimeStamp="";
|
||||
var endTimeStamp="";
|
||||
var bApplySign = false;
|
||||
var applyPage=false;
|
||||
var keyCode = 32;
|
||||
var videoTime=60000*12000;
|
||||
var cdTimeCountFlag="video";//video跟videotape
|
||||
var cdTimeCount=videoTime;
|
||||
var countDownTimer=null;
|
||||
var channelValue=decodeURI(getParams("id"));
|
||||
var mdDeviceName=decodeURI(getParams("mdDeviceName"));
|
||||
var station=decodeURI(getParams("station"));
|
||||
var title=decodeURI(getParams("mdDeviceName"));
|
||||
var loginUserName=decodeURI(getParams("username"));
|
||||
var power=decodeURI(getParams("power"));
|
||||
var rtmName=channelValue;
|
||||
var client=null;
|
||||
var buffer=[];
|
||||
var mediaRecorder =null;
|
||||
var videoTimer=null;
|
||||
var options = {
|
||||
appid: "78846e9910a846688ab959e0f87034e5",
|
||||
channel: channelValue,
|
||||
uid: '',
|
||||
token: null
|
||||
};
|
||||
var client=AgoraRTC.createClient({mode: 'live',codec: "vp8"});
|
||||
var remoteUsers = {};
|
||||
let localTracks = {
|
||||
audioTrack: true
|
||||
};
|
||||
$("html>head>title").html(title);
|
||||
videoJoin();
|
||||
setPower(power);
|
||||
function setPower(power){
|
||||
if(power=="null"){
|
||||
power=0;
|
||||
}
|
||||
if(power>=90){
|
||||
var img="images/power100.png";
|
||||
}else if(power>=70){
|
||||
var img="images/power80.png";
|
||||
}else if(power>=50){
|
||||
var img="images/power60.png";
|
||||
}else if(power>=30){
|
||||
var img="images/power40.png";
|
||||
}else if(power>=10){
|
||||
var img="images/power20.png";
|
||||
}else{
|
||||
var img="images/power0.png";
|
||||
}
|
||||
$(".power>span").html(power+"%");
|
||||
$(".power>img").attr("src",img);
|
||||
}
|
||||
|
||||
function closePage(){
|
||||
leaveChannel();//我先离开频道
|
||||
var obj=getRtmData("videoclose","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
window.close();
|
||||
}
|
||||
|
||||
async function leaveChannel() {
|
||||
// leave the channel
|
||||
await client.leave();
|
||||
}
|
||||
|
||||
//关闭并退出
|
||||
$(".videoNav>.nav>img:nth-child(1)").click(function(){
|
||||
var param = {
|
||||
"sender":"children",
|
||||
"receiver":"parent",
|
||||
"deviceid":channelValue,
|
||||
"cmd":"closePage"
|
||||
};
|
||||
window.parent.postMessage(param,'*');
|
||||
closePage();
|
||||
})
|
||||
|
||||
window.addEventListener('message', function(e) {
|
||||
var data=e.data
|
||||
var cmd=data["cmd"];
|
||||
var deviceid=data["deviceid"]
|
||||
if(cmd=="videoclose"){
|
||||
if(channelValue==deviceid){
|
||||
closePage();
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//如果在全屏
|
||||
function confClosePage(){
|
||||
var url=window.location.href;
|
||||
if(url.indexOf("fullScreenVideo")==-1){
|
||||
closePage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
window.onbeforeunload=function(e){
|
||||
if(locationUrl.indexOf("videoMoitorShow")==-1){
|
||||
confClosePage();
|
||||
}
|
||||
}
|
||||
|
||||
window.onresize = function () {
|
||||
var w=parseFloat(window.innerWidth);
|
||||
var h=parseFloat(window.innerHeight - 40);
|
||||
switch(sizeLevel){
|
||||
case 1:
|
||||
setVideoSize1280(w,h);
|
||||
break;
|
||||
case 2:
|
||||
setVideoSize720(w,h);
|
||||
break;
|
||||
case 3:
|
||||
setVideoSize480(w,h);
|
||||
break;
|
||||
case 4:
|
||||
setVideoSize640(w,h);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//1280*720
|
||||
function setVideoSize1280(w,h){
|
||||
var f=parseFloat(h/w);
|
||||
if(f >= 0.5625){
|
||||
var width=w;
|
||||
var height=width*0.5625;
|
||||
var x= 0;
|
||||
var y=parseFloat(h-height)/2;
|
||||
}else{
|
||||
var height=h;
|
||||
var width=(height*16)/9;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y= 0;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
//720*1280
|
||||
function setVideoSize720(w,h){
|
||||
var f=parseFloat(w/h);
|
||||
if(f>0.5625){
|
||||
var height=h;
|
||||
var width=h*0.5625;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y=0;
|
||||
}else{
|
||||
var width=w;
|
||||
var height=(w*16)/9;
|
||||
var x=0;
|
||||
var y=parseFloat(h-height)/2;;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
|
||||
//480*640
|
||||
function setVideoSize480(w,h){//宽度是480px;height:640px;
|
||||
var f=parseFloat(w/h);
|
||||
if(f>0.75){
|
||||
var height=h;
|
||||
var width=h*0.75;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y=0;
|
||||
}else{
|
||||
var width=w;
|
||||
var height=(w*4)/3;
|
||||
var x=0;
|
||||
var y=parseFloat(h-height)/2;;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
//640*480
|
||||
function setVideoSize640(w,h){
|
||||
var f=parseFloat(h/w);
|
||||
if(f >= 0.75){
|
||||
var width=w;
|
||||
var height=width*0.75;
|
||||
var x= 0;
|
||||
var y=parseFloat(h-height)/2;
|
||||
}else{
|
||||
var height=h;
|
||||
var width=(height*4)/3;
|
||||
var x=parseFloat(w-width)/2;
|
||||
var y= 0;
|
||||
}
|
||||
setPageSize(x,y,width,height)
|
||||
}
|
||||
|
||||
|
||||
|
||||
function setPageSize(x,y,width,height){
|
||||
$("#video").css("width",width+"px");
|
||||
$("#video").css("height",height+"px");
|
||||
$("#video").css("left",x);
|
||||
$("#video").css("top",y);
|
||||
}
|
||||
|
||||
$(".videoFullscreen").unbind('click');
|
||||
$(".videoFullscreen").click(function(){
|
||||
|
||||
console.log(123456);
|
||||
|
||||
var url=window.location.href;
|
||||
if(url.indexOf("alarmDeviceVideo")!=-1){
|
||||
//投一个新的屏幕出去
|
||||
var width=1280;
|
||||
var height=760;
|
||||
window.open("fullScreenVideo.html?id="+encodeURI(channelValue)+"&power="+encodeURI(power)+"&mdDeviceName="+encodeURI(encodeURI(mdDeviceName))+"&station="+encodeURI(encodeURI(station))+"&title="+encodeURI(encodeURI(title))+"&username="+loginUserName,"","width="+width+",height="+height+",top=0,left=0");
|
||||
}else{
|
||||
var model=$(this).attr("model");
|
||||
if(model=="exitfullScreen"){
|
||||
fullScreen()
|
||||
$(this).attr("src","images/videoExitFullscreen.png").attr("model","fullScreen").attr("title","退出全屏")
|
||||
}else{
|
||||
exitFullscreen()
|
||||
$(this).attr("src","images/videoFullscreen.png").attr("model","exitfullScreen").attr("title","全屏");
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
//打开声音
|
||||
function openMute(select){
|
||||
$(select).attr("src","images/openMute.png");
|
||||
$(select).attr("title","音量");
|
||||
$(select).attr("mute","open");
|
||||
}
|
||||
|
||||
//关闭声音
|
||||
function closeMute(select){
|
||||
$(select).attr("src","images/closeMute.png");
|
||||
$(select).attr("title","静音");
|
||||
$(select).attr("mute","close");
|
||||
}
|
||||
|
||||
//初始化声音
|
||||
function videoSlideInit(){
|
||||
sliderInit=slider.render({
|
||||
elem: '#slideTest1',
|
||||
change: function(value){
|
||||
var select=$(".closeMute");
|
||||
if(value==0){
|
||||
closeMute(select);
|
||||
}else{
|
||||
openMute(select);
|
||||
}
|
||||
setRemoteUserMute(value*10);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function setRemoteUserMute(value){
|
||||
for(var user in remoteUsers){
|
||||
remoteUsers[user].audioTrack.setVolume(value);
|
||||
}
|
||||
}
|
||||
|
||||
let cameraid=0;
|
||||
let rotateid=0;
|
||||
//摄像图的操作
|
||||
$(".carmeOper").on('click',function(){
|
||||
rotateid=parseInt($(this).attr("rotate"));
|
||||
$(".carmeOper").removeClass("bgColor");
|
||||
$(this).addClass("bgColor")
|
||||
sendCarmeOper();
|
||||
})
|
||||
|
||||
//摄像头的方向调整
|
||||
$(".carmeDir").on('click',function(){
|
||||
let dir=$(this).attr("dir");
|
||||
cameraid=dir;
|
||||
if(dir=="0"){
|
||||
$(this).attr("dir","1");
|
||||
$(this).html("后");
|
||||
}else{
|
||||
$(this).attr("dir","0");
|
||||
$(this).html("前");
|
||||
}
|
||||
sendCarmeOper();
|
||||
})
|
||||
|
||||
function sendCarmeOper(){
|
||||
var obj=getRtmData("videoclose","");
|
||||
sendMqttData(obj);
|
||||
setTimeout(()=>{
|
||||
let data={
|
||||
"rtmpflag":0,
|
||||
"camera":cameraid,
|
||||
"rotation":rotateid
|
||||
}
|
||||
var obj=getRtmData("videocall",JSON.stringify(data));
|
||||
sendMqttData(obj);
|
||||
videoInfoWind();
|
||||
},4000)
|
||||
}
|
||||
|
||||
//调节音量大小
|
||||
$(".closeMute").click(function(){
|
||||
var mute=$(this).attr("mute");
|
||||
if(mute=="open"){
|
||||
setRemoteUserMute(0)
|
||||
sliderInit.setValue(0) //设置开始值
|
||||
closeMute(this);
|
||||
}else{
|
||||
setRemoteUserMute(1000)
|
||||
sliderInit.setValue(100) //设置开始值
|
||||
openMute(this);
|
||||
}
|
||||
})
|
||||
|
||||
async function videoJoin() {
|
||||
//订阅用户推送流
|
||||
client.on("user-published", handleUserPublished);
|
||||
//订阅用户取消推流
|
||||
client.on("user-unpublished", handleUserUnpublished);
|
||||
try {
|
||||
// join a channel and create local tracks, we can use Promise.all to run them concurrently
|
||||
[ options.uid] = await Promise.all([
|
||||
// join the channel
|
||||
client.join(options.appid, options.channel, options.token || null),
|
||||
]);
|
||||
} catch (e) {
|
||||
console.log("加入频道失败", e);
|
||||
}
|
||||
// 使用 Web SDK 4.x,服务器频道禁用以后,客服端需要退出页面跟频道
|
||||
client.on("connection-state-change", (curState, prevState) => {
|
||||
closePage();
|
||||
});
|
||||
}
|
||||
|
||||
async function subscribe(user, mediaType) {
|
||||
const uid = user.uid;
|
||||
// subscribe to a remote user
|
||||
await client.subscribe(user, mediaType);
|
||||
if (mediaType === 'video') {
|
||||
const player = $(`
|
||||
<div id="player-${uid}" class="player"></div>
|
||||
`);
|
||||
$("#agora_local").append(player);
|
||||
user.videoTrack.play(`player-${uid}`);
|
||||
//设置视频数据
|
||||
setVideoData();
|
||||
//初始化视频的尺寸
|
||||
videoInfoWind();
|
||||
|
||||
|
||||
setInterval(function(){
|
||||
var obj=getRtmData("videowatching","");
|
||||
sendMqttData(obj)
|
||||
//每隔1分钟发送发送1个不关闭视频的指令
|
||||
},60000)
|
||||
|
||||
}
|
||||
if(mediaType === 'audio'){
|
||||
setRemoteUserMute(0);
|
||||
//初始化音量
|
||||
videoSlideInit();
|
||||
user.audioTrack.play();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function handleUserPublished(user, mediaType) {
|
||||
const id = user.uid;
|
||||
remoteUsers[id] = user;
|
||||
subscribe(user, mediaType);
|
||||
}
|
||||
|
||||
function handleUserUnpublished(user) {
|
||||
const id = user.uid;
|
||||
delete remoteUsers[id];
|
||||
$(`#player-wrapper-${id}`).remove();
|
||||
}
|
||||
|
||||
|
||||
function setVideoData(){
|
||||
setInterval(()=>{
|
||||
var evt=client.getRemoteVideoStats();
|
||||
if(JSON.stringify(evt)!="{}"){
|
||||
for(var j in evt){
|
||||
var packetLossRate=evt[j]["packetLossRate"]
|
||||
var receiveBitrate=parseFloat(evt[j]["receiveBitrate"]/1024).toFixed(2);
|
||||
var receiveFrameRate=evt[j]["receiveFrameRate"]
|
||||
var totalDuration=evt[j]["totalDuration"]
|
||||
var totalFreezeTime=evt[j]["totalFreezeTime"]
|
||||
var transportDelay=evt[j]["transportDelay"]
|
||||
$(".PacketLossRate").html(packetLossRate);
|
||||
$(".RecvBitrate").html(receiveBitrate);
|
||||
$(".RenderFrameRate").html(receiveFrameRate);
|
||||
$(".TotalPlayDuration").html(totalDuration);
|
||||
$(".TotalFreezeTime").html(totalFreezeTime);
|
||||
$(".TransportDelay").html(transportDelay);
|
||||
}
|
||||
}
|
||||
},1000)
|
||||
}
|
||||
|
||||
function videoInfoWind(){
|
||||
videoTimer=setInterval(() => {
|
||||
var evt=client.getRemoteVideoStats();
|
||||
if(JSON.stringify(evt)!="{}"){
|
||||
for(var i in evt){
|
||||
if("receiveResolutionHeight" in evt[i]){
|
||||
var RecvResolutionHeight=evt[i]["receiveResolutionHeight"];
|
||||
}
|
||||
if("receiveResolutionWidth" in evt[i]){
|
||||
var RecvResolutionWidth=evt[i]["receiveResolutionWidth"];
|
||||
}
|
||||
if((RecvResolutionWidth!="0"&&RecvResolutionHeight!="0")&&(RecvResolutionWidth!=undefined&&RecvResolutionHeight!=undefined)){
|
||||
clearInterval(videoTimer);
|
||||
var width=RecvResolutionWidth;
|
||||
var height=parseFloat(RecvResolutionHeight);
|
||||
if(RecvResolutionWidth=="1280"&&RecvResolutionHeight=="720"){
|
||||
sizeLevel=1;
|
||||
setVideoSize1280(width*0.5,height*0.5);
|
||||
window.resizeTo(width,height);
|
||||
}else if(RecvResolutionWidth=="720"&&RecvResolutionHeight=="1280"){
|
||||
if(window.screen.height+200<=height){
|
||||
width=width*0.8;
|
||||
height=height*0.8;
|
||||
}
|
||||
sizeLevel=2;
|
||||
setVideoSize720(width*0.5,height*0.5);
|
||||
window.resizeTo(width,height);
|
||||
}else if(RecvResolutionWidth=="480"&&RecvResolutionHeight=="640"){
|
||||
sizeLevel=3;
|
||||
setVideoSize480(width*0.5,height*0.5);
|
||||
window.resizeTo("496","750");
|
||||
}else if(RecvResolutionWidth=="640"&&RecvResolutionHeight=="480"){
|
||||
sizeLevel=4;
|
||||
setVideoSize640(width*0.5,height*0.5);
|
||||
window.resizeTo(RecvResolutionWidth,RecvResolutionHeight);
|
||||
}
|
||||
var param={
|
||||
"deviceid":channelValue,
|
||||
"cmd":"videoloadedSuccess"
|
||||
}
|
||||
parent.postMessage(param,'*');
|
||||
//启动倒计时
|
||||
downTime30();
|
||||
}
|
||||
}
|
||||
}
|
||||
},1000)
|
||||
}
|
||||
|
||||
//设置stream
|
||||
function setRecStream(){
|
||||
let mediaStream = new MediaStream();
|
||||
for(var user in remoteUsers){
|
||||
mediaStream.addTrack(remoteUsers[user].videoTrack.getMediaStreamTrack())
|
||||
mediaStream.addTrack(remoteUsers[user].audioTrack.getMediaStreamTrack())
|
||||
}
|
||||
window.stream=mediaStream;
|
||||
}
|
||||
|
||||
//开启远程录像
|
||||
$(".startRecording").unbind();
|
||||
$(".startRecording").click(function(){
|
||||
var recordState=$(this).attr("state");
|
||||
if(recordState=="open"){
|
||||
setRecStream();
|
||||
startRecord();
|
||||
startTimeStamp=new Date().getTime();
|
||||
videotapeStartTime=timestampFormat();
|
||||
$(this).attr("state","close");
|
||||
$(this).attr("src","images/endRecording.png");
|
||||
$(this).attr("title","结束录像");
|
||||
layer.msg("录像开启成功");
|
||||
$(".inTheVideo").css("display","block");
|
||||
cdTimeCountFlag="videotape";
|
||||
downTime30();
|
||||
}else{
|
||||
endTimeStamp=new Date().getTime();
|
||||
videotapeEndTime=timestampFormat();
|
||||
stopRecord();
|
||||
cdTimeCount=videoTime;
|
||||
clearInterval(countDownTimer);
|
||||
countDownTimer=null;
|
||||
cdTimeCountFlag="video";
|
||||
}
|
||||
})
|
||||
|
||||
//视频信息
|
||||
$(".videoReInfo").on('click',function(){
|
||||
var state=$(this).attr("state");
|
||||
if(state=="close"){
|
||||
$(this).attr("state","open");
|
||||
$(".videoInfo").css("display","block");
|
||||
|
||||
|
||||
}else{
|
||||
$(this).attr("state","close");
|
||||
$(".videoInfo").css("display","none");
|
||||
}
|
||||
})
|
||||
|
||||
async function setClientHost(){
|
||||
//设置成主播
|
||||
await client.setClientRole("host");
|
||||
try {
|
||||
// join a channel and create local tracks, we can use Promise.all to run them concurrently
|
||||
[localTracks.audioTrack] = await Promise.all([
|
||||
// create local tracks, using microphone and camera
|
||||
AgoraRTC.createMicrophoneAudioTrack()
|
||||
]);
|
||||
await client.publish(Object.values(localTracks));
|
||||
} catch (e) {
|
||||
console.log("加入频道失败", e);
|
||||
}
|
||||
}
|
||||
async function setClientAudience(){
|
||||
//先调用取消发布,在设置成观众
|
||||
await client.unpublish(Object.values(localTracks));
|
||||
await client.setClientRole("audience");
|
||||
}
|
||||
|
||||
//开启对讲
|
||||
$(".videoWalk").unbind();
|
||||
$(".videoWalk").click(function(){
|
||||
var state=$(this).attr("state");
|
||||
if(state=="close"){
|
||||
//开启
|
||||
$(this).attr("state","open");
|
||||
$(this).attr("src","images/videoWalkOnline.png");
|
||||
applyPage=true;
|
||||
bApplySign=true;
|
||||
setClientHost();
|
||||
}else{
|
||||
applyPage=false;
|
||||
bApplySign=false;
|
||||
//关闭
|
||||
$(this).attr("state","close");
|
||||
$(this).attr("src","images/videoWalk.png");
|
||||
setClientAudience();
|
||||
}
|
||||
})
|
||||
|
||||
//键盘松开
|
||||
document.onkeyup = function (event) {
|
||||
var e = event || window.event || arguments.callee.caller.arguments[0];
|
||||
if(applyPage){
|
||||
if(e && e.keyCode == keyCode&&!bApplySign) {
|
||||
bApplySign = true;
|
||||
//关闭麦克风
|
||||
localTracks.audioTrack.setEnabled(false);
|
||||
//开启远程的声音
|
||||
setRemoteUserMute(100);
|
||||
var select=$(".closeMute");
|
||||
openMute(select);
|
||||
sliderInit.setValue(100) //设置开始值
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//键盘按下
|
||||
document.onkeydown = function (event) {
|
||||
var e = event || window.event || arguments.callee.caller.arguments[0];
|
||||
if(applyPage){
|
||||
if(e && e.keyCode == keyCode&&bApplySign) {
|
||||
bApplySign = false;
|
||||
//启用麦克风
|
||||
localTracks.audioTrack.setEnabled(true);
|
||||
//关闭远程的声音
|
||||
setRemoteUserMute(0);
|
||||
//页面状态改变
|
||||
sliderInit.setValue(0) //设置开始值
|
||||
var select=$(".closeMute");
|
||||
closeMute(select);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//截图,并且把图片保存在云端
|
||||
$(".videoImg").click(function(){
|
||||
var video=document.querySelector(".agora_video_player");
|
||||
var canvas=document.getElementById('canvas');
|
||||
if(video!=null){
|
||||
$(".canvasImg").css("display","block");
|
||||
canvas.width=video.videoWidth;
|
||||
canvas.height=video.videoHeight;
|
||||
canvas.getContext('2d').drawImage(video,0,0,canvas.width,canvas.height);
|
||||
var image = canvas . toDataURL ("image/png") ;
|
||||
$(".canvasImgBox").css("width",canvas.width*0.3+"px");
|
||||
$(".canvasImgBox").css("height",canvas.height*0.3+"px");
|
||||
document.getElementById("save").href=image;
|
||||
document.getElementById("save").download=mdDeviceName+".jpg";
|
||||
document.getElementById('save').onclick=function(){
|
||||
|
||||
$(".canvasImg").css("display","none");
|
||||
}
|
||||
document.getElementById('cancel').onclick=function(){
|
||||
$(".canvasImg").css("display","none");
|
||||
}
|
||||
}else{
|
||||
layer.msg("用户已离开,无法截图");
|
||||
}
|
||||
})
|
||||
|
||||
function closeVideoStream(){
|
||||
var obj=getRtmData("videoclose","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//倒计时30分钟以后关闭录像,告诉用户,录像已经完成
|
||||
/*************************观看视频为5分钟1次,如果不点击确定,就会关闭***********************************/
|
||||
function downTime30(){
|
||||
if(countDownTimer!=null){
|
||||
clearInterval(countDownTimer);
|
||||
}else{
|
||||
countDownTimer=setInterval(function(){
|
||||
cdTimeCount-=1000;
|
||||
if(cdTimeCount<=0){
|
||||
clearInterval(countDownTimer);
|
||||
countDownTimer=null;
|
||||
if(cdTimeCountFlag=="videotape"){
|
||||
endTimeStamp=new Date().getTime();
|
||||
videotapeEndTime=timestampFormat();
|
||||
stopRecord();
|
||||
}else{
|
||||
//倒计时
|
||||
showCountDownTimer();
|
||||
}
|
||||
}
|
||||
},1000);
|
||||
}
|
||||
}
|
||||
|
||||
//倒计时*******************************************
|
||||
var closeTime=10;//倒计时
|
||||
var closePageTimer=null;
|
||||
function showCountDownTimer(){
|
||||
$(".videoTitle").css("display","block");
|
||||
$(".close_ing_time").html(closeTime);
|
||||
videoTitleEvent();
|
||||
closePageTimer=setInterval(function(){
|
||||
closeTime--;
|
||||
$(".close_ing_time").html(closeTime);
|
||||
if(closeTime<=0){
|
||||
closeVideoStream();//发送关闭指令
|
||||
leaveChannel();//离开频道
|
||||
clearInterval(closePageTimer);//退出定时器
|
||||
}
|
||||
},1000);
|
||||
}
|
||||
|
||||
function videoTitleEvent(){
|
||||
$(".videoTitle>p:last-child>button:nth-child(1)").on('click',function(){
|
||||
var obj=getRtmData("videocall","");//在去关闭
|
||||
sendMqttData(obj);
|
||||
$(".videoTitle").css("display","none");
|
||||
clearInterval(closePageTimer);
|
||||
closePageTimer=null;
|
||||
closeTime=10;
|
||||
cdTimeCount=videoTime;
|
||||
//再次加入频道
|
||||
videoJoin()
|
||||
downTime30()
|
||||
})
|
||||
$(".videoTitle>p:last-child>button:nth-child(2)").on('click',function(){
|
||||
closePage();
|
||||
})
|
||||
}
|
||||
|
||||
function handleDataAvailable(e){ // 5、获取数据的事件函数 当我们点击录制之后,数据就会源源不断的从这个事件函数中获取到
|
||||
if(e && e.data && e.data.size > 0){
|
||||
console.log(e.data);
|
||||
buffer.push(e.data); // 将e.data放入二进制数组里面
|
||||
// 这个buffer应该是我们在开始录制的时候创建这个buffer
|
||||
}
|
||||
}
|
||||
|
||||
//开始录像
|
||||
function startRecord(){
|
||||
buffer = []; // 定义数组
|
||||
if (typeof MediaRecorder.isTypeSupported == 'function') {
|
||||
if (MediaRecorder.isTypeSupported('video/webm;codecs=vp8')) {
|
||||
var options = {
|
||||
mimeType: 'video/webm;codecs=vp9,opus'
|
||||
}
|
||||
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=vp9')) {
|
||||
var options = {
|
||||
mimeType:'video/webm;codecs=vp9,opus'
|
||||
};
|
||||
} else if (MediaRecorder.isTypeSupported('video/webm;codecs=h264')) {
|
||||
var options = {
|
||||
mimeType:'video/webm;codecs=h264,opus'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
if(!MediaRecorder.isTypeSupported(options.mimeType)){ // 判断录制的视频 mimeType 格式浏览器是否支持
|
||||
return;
|
||||
}
|
||||
|
||||
try{ // 防止录制异常
|
||||
// 5、先在上面定义全局对象mediaRecorder,以便于后面停止录制的时候可以用到
|
||||
mediaRecorder = new MediaRecorder(window.stream, options); // 调用录制API // window.stream在gotMediaStream中获取
|
||||
//4、调用事件 这个事件处理函数里面就会收到我们录制的那块数据 当我们收集到这个数据之后我们应该把它存储起来
|
||||
mediaRecorder.ondataavailable = handleDataAvailable;
|
||||
mediaRecorder.start(0); // start方法里面传入一个时间片,每隔一个 时间片存储 一块数据
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//停止录制
|
||||
function stopRecord(){
|
||||
//6、调用停止录制
|
||||
try{
|
||||
mediaRecorder.stop();
|
||||
}catch(e){
|
||||
console.error(e);
|
||||
}
|
||||
$(".startRecording").attr("state","open");
|
||||
$(".startRecording").attr("src","images/startRecording.png");
|
||||
$(this).attr("title","开始录像");
|
||||
layer.msg('录像已保存', {
|
||||
time: false, //20s后自动关闭
|
||||
btn: ['知道了']
|
||||
});
|
||||
|
||||
$(".inTheVideo").css("display","none");
|
||||
var tmpBlob = new Blob(buffer, {type: 'video/webm'});
|
||||
var duration=endTimeStamp-startTimeStamp;
|
||||
//调用设置时长代码。该函数基于fix-webm-duration.js
|
||||
ysFixWebmDuration(tmpBlob, duration, function (fixedBlob) {
|
||||
var recorderFile = fixedBlob;
|
||||
let name =`${mdDeviceName}(${videotapeStartTime}---${videotapeEndTime}).mp4`;
|
||||
var url = window.URL.createObjectURL(recorderFile);
|
||||
var a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.style.display = 'none';
|
||||
a.download = name;
|
||||
a.click();
|
||||
});
|
||||
}
|
||||
//构建rtm发送对象
|
||||
function getRtmData(title,data){
|
||||
return {
|
||||
"title":title,
|
||||
"sender":loginUserName,
|
||||
"department":"",
|
||||
"scope":"",
|
||||
"receiver":[rtmName],
|
||||
"video":"",
|
||||
"rtm":(new Date().getTime()).toString(),
|
||||
"data":data,
|
||||
"userScope":"",
|
||||
"userBragide":"",
|
||||
"userDetachchment":"",
|
||||
"userBorough":"",
|
||||
"name":"",
|
||||
}
|
||||
}
|
||||
|
||||
//发送mqqt接口数据
|
||||
function sendMqttData(obj){
|
||||
var mqttObj={
|
||||
"topic":`${station}/ter_cmd`,
|
||||
"message":JSON.stringify(obj)
|
||||
}
|
||||
$.ajax({
|
||||
url: mqttUrl,
|
||||
type: "post",
|
||||
dataType: "json",
|
||||
headers: {
|
||||
"Content-Type": "application/json;charset=utf-8"
|
||||
},
|
||||
data: JSON.stringify(mqttObj),
|
||||
success: function(d) {
|
||||
//console.error(d);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
export function timestampFormat(){
|
||||
var currentTime = new Date();
|
||||
var year = currentTime.getFullYear();
|
||||
var getMonth = (currentTime.getMonth()) + 1;
|
||||
var getDate = currentTime.getDate();
|
||||
var getHours = currentTime.getHours();
|
||||
var getMinutes = currentTime.getMinutes();
|
||||
var getSeconds = currentTime.getSeconds();
|
||||
if(getMonth < 10) {
|
||||
getMonth = "0" + getMonth;
|
||||
}
|
||||
if(getDate < 10) {
|
||||
getDate = "0" + getDate;
|
||||
}
|
||||
if(getHours < 10) {
|
||||
getHours = "0" + getHours;
|
||||
}
|
||||
if(getMinutes < 10) {
|
||||
getMinutes = "0" + getMinutes;
|
||||
}
|
||||
if(getSeconds < 10) {
|
||||
getSeconds = "0" + getSeconds;
|
||||
}
|
||||
return year + "年" + getMonth + "月" + getDate + "日" + getHours + "时" + getMinutes + "分" + getSeconds+"秒";
|
||||
}
|
||||
|
||||
//接受url的值,进行解析
|
||||
export function getParams(key) {
|
||||
var reg = new RegExp("(^|&)" + key + "=([^&]*)(&|$)");
|
||||
var r = window.location.search.substr(1).match(reg);
|
||||
if (r != null) {
|
||||
return unescape(r[2]);
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
//全屏
|
||||
export function fullScreen() {
|
||||
var element = document.documentElement;
|
||||
if (element.requestFullscreen) {
|
||||
element.requestFullscreen();
|
||||
} else if (element.msRequestFullscreen) {
|
||||
element.msRequestFullscreen();
|
||||
} else if (element.mozRequestFullScreen) {
|
||||
element.mozRequestFullScreen();
|
||||
} else if (element.webkitRequestFullscreen) {
|
||||
element.webkitRequestFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
//退出全屏
|
||||
export function exitFullscreen() {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.msExitFullscreen) {
|
||||
document.msExitFullscreen();
|
||||
} else if (document.mozCancelFullScreen) {
|
||||
document.mozCancelFullScreen();
|
||||
} else if (document.webkitExitFullscreen) {
|
||||
document.webkitExitFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,184 @@
|
|||
function md5(string) {
|
||||
function md5_RotateLeft(lValue, iShiftBits) {
|
||||
return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
|
||||
}
|
||||
function md5_AddUnsigned(lX, lY) {
|
||||
var lX4, lY4, lX8, lY8, lResult;
|
||||
lX8 = (lX & 0x80000000);
|
||||
lY8 = (lY & 0x80000000);
|
||||
lX4 = (lX & 0x40000000);
|
||||
lY4 = (lY & 0x40000000);
|
||||
lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
|
||||
if (lX4 & lY4) {
|
||||
return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
|
||||
}
|
||||
if (lX4 | lY4) {
|
||||
if (lResult & 0x40000000) {
|
||||
return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
|
||||
} else {
|
||||
return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
|
||||
}
|
||||
} else {
|
||||
return (lResult ^ lX8 ^ lY8);
|
||||
}
|
||||
}
|
||||
function md5_F(x, y, z) {
|
||||
return (x & y) | ((~x) & z);
|
||||
}
|
||||
function md5_G(x, y, z) {
|
||||
return (x & z) | (y & (~z));
|
||||
}
|
||||
function md5_H(x, y, z) {
|
||||
return (x ^ y ^ z);
|
||||
}
|
||||
function md5_I(x, y, z) {
|
||||
return (y ^ (x | (~z)));
|
||||
}
|
||||
function md5_FF(a, b, c, d, x, s, ac) {
|
||||
a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_F(b, c, d), x), ac));
|
||||
return md5_AddUnsigned(md5_RotateLeft(a, s), b);
|
||||
};
|
||||
function md5_GG(a, b, c, d, x, s, ac) {
|
||||
a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_G(b, c, d), x), ac));
|
||||
return md5_AddUnsigned(md5_RotateLeft(a, s), b);
|
||||
};
|
||||
function md5_HH(a, b, c, d, x, s, ac) {
|
||||
a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_H(b, c, d), x), ac));
|
||||
return md5_AddUnsigned(md5_RotateLeft(a, s), b);
|
||||
};
|
||||
function md5_II(a, b, c, d, x, s, ac) {
|
||||
a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_I(b, c, d), x), ac));
|
||||
return md5_AddUnsigned(md5_RotateLeft(a, s), b);
|
||||
};
|
||||
function md5_ConvertToWordArray(string) {
|
||||
var lWordCount;
|
||||
var lMessageLength = string.length;
|
||||
var lNumberOfWords_temp1 = lMessageLength + 8;
|
||||
var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
|
||||
var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
|
||||
var lWordArray = Array(lNumberOfWords - 1);
|
||||
var lBytePosition = 0;
|
||||
var lByteCount = 0;
|
||||
while (lByteCount < lMessageLength) {
|
||||
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
|
||||
lBytePosition = (lByteCount % 4) * 8;
|
||||
lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
|
||||
lByteCount++;
|
||||
}
|
||||
lWordCount = (lByteCount - (lByteCount % 4)) / 4;
|
||||
lBytePosition = (lByteCount % 4) * 8;
|
||||
lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
|
||||
lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
|
||||
lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
|
||||
return lWordArray;
|
||||
};
|
||||
function md5_WordToHex(lValue) {
|
||||
var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
|
||||
for (lCount = 0; lCount <= 3; lCount++) {
|
||||
lByte = (lValue >>> (lCount * 8)) & 255;
|
||||
WordToHexValue_temp = "0" + lByte.toString(16);
|
||||
WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
|
||||
}
|
||||
return WordToHexValue;
|
||||
};
|
||||
function md5_Utf8Encode(string) {
|
||||
string = string.replace(/\r\n/g, "\n");
|
||||
var utftext = "";
|
||||
for (var n = 0; n < string.length; n++) {
|
||||
var c = string.charCodeAt(n);
|
||||
if (c < 128) {
|
||||
utftext += String.fromCharCode(c);
|
||||
} else if ((c > 127) && (c < 2048)) {
|
||||
utftext += String.fromCharCode((c >> 6) | 192);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
} else {
|
||||
utftext += String.fromCharCode((c >> 12) | 224);
|
||||
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
||||
utftext += String.fromCharCode((c & 63) | 128);
|
||||
}
|
||||
}
|
||||
return utftext;
|
||||
};
|
||||
var x = Array();
|
||||
var k, AA, BB, CC, DD, a, b, c, d;
|
||||
var S11 = 7, S12 = 12, S13 = 17, S14 = 22;
|
||||
var S21 = 5, S22 = 9, S23 = 14, S24 = 20;
|
||||
var S31 = 4, S32 = 11, S33 = 16, S34 = 23;
|
||||
var S41 = 6, S42 = 10, S43 = 15, S44 = 21;
|
||||
string = md5_Utf8Encode(string);
|
||||
x = md5_ConvertToWordArray(string);
|
||||
a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
|
||||
for (k = 0; k < x.length; k += 16) {
|
||||
AA = a; BB = b; CC = c; DD = d;
|
||||
a = md5_FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
|
||||
d = md5_FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
|
||||
c = md5_FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
|
||||
b = md5_FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
|
||||
a = md5_FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
|
||||
d = md5_FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
|
||||
c = md5_FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
|
||||
b = md5_FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
|
||||
a = md5_FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
|
||||
d = md5_FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
|
||||
c = md5_FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
|
||||
b = md5_FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
|
||||
a = md5_FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
|
||||
d = md5_FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
|
||||
c = md5_FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
|
||||
b = md5_FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
|
||||
a = md5_GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
|
||||
d = md5_GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
|
||||
c = md5_GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
|
||||
b = md5_GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
|
||||
a = md5_GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
|
||||
d = md5_GG(d, a, b, c, x[k + 10], S22, 0x2441453);
|
||||
c = md5_GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
|
||||
b = md5_GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
|
||||
a = md5_GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
|
||||
d = md5_GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
|
||||
c = md5_GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
|
||||
b = md5_GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
|
||||
a = md5_GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
|
||||
d = md5_GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
|
||||
c = md5_GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
|
||||
b = md5_GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
|
||||
a = md5_HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
|
||||
d = md5_HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
|
||||
c = md5_HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
|
||||
b = md5_HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
|
||||
a = md5_HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
|
||||
d = md5_HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
|
||||
c = md5_HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
|
||||
b = md5_HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
|
||||
a = md5_HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
|
||||
d = md5_HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
|
||||
c = md5_HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
|
||||
b = md5_HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
|
||||
a = md5_HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
|
||||
d = md5_HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
|
||||
c = md5_HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
|
||||
b = md5_HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
|
||||
a = md5_II(a, b, c, d, x[k + 0], S41, 0xF4292244);
|
||||
d = md5_II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
|
||||
c = md5_II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
|
||||
b = md5_II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
|
||||
a = md5_II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
|
||||
d = md5_II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
|
||||
c = md5_II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
|
||||
b = md5_II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
|
||||
a = md5_II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
|
||||
d = md5_II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
|
||||
c = md5_II(c, d, a, b, x[k + 6], S43, 0xA3014314);
|
||||
b = md5_II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
|
||||
a = md5_II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
|
||||
d = md5_II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
|
||||
c = md5_II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
|
||||
b = md5_II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
|
||||
a = md5_AddUnsigned(a, AA);
|
||||
b = md5_AddUnsigned(b, BB);
|
||||
c = md5_AddUnsigned(c, CC);
|
||||
d = md5_AddUnsigned(d, DD);
|
||||
}
|
||||
return (md5_WordToHex(a) + md5_WordToHex(b) + md5_WordToHex(c) + md5_WordToHex(d)).toLowerCase();
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>视频查看</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
|
||||
<meta http-equiv="Cache" content="no-cache">
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<link rel="stylesheet" href="./layui.css">
|
||||
<script src="./layui.js"></script>
|
||||
<script src="./jquery-3.4.1.min.js"></script>
|
||||
<script src="AgoraRTC_N-4.11.0.js"></script>
|
||||
<!--给录像文件添加时间进度条-->
|
||||
<script src="fix-webm-duration.js"></script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="video">
|
||||
<div class="inTheVideo">
|
||||
<img src="./images/inTheVideo.png" alt="" />
|
||||
<span>REC</span>
|
||||
</div>
|
||||
<!--视频信息-->
|
||||
<div class="videoInfo">
|
||||
<p>丢包率:<span class="PacketLossRate">0</span>(%)</p>
|
||||
<p>接收码率:<span class="RecvBitrate">0</span>(Kbps)</p>
|
||||
<p>渲染帧率:<span class="RenderFrameRate">0</span>(fps)</p>
|
||||
<p>播放总时间:<span class="TotalPlayDuration">0</span>(s)</p>
|
||||
<p>卡顿总时间:<span class="TotalFreezeTime">0</span>(s)</p>
|
||||
<p>传输延时:<span class="TransportDelay">0</span>(ms)</p>
|
||||
</div>
|
||||
<div id="qrcode"></div>
|
||||
<div id="agora_local"></div>
|
||||
</div>
|
||||
<!--视频操作-->
|
||||
<div class="videoNav">
|
||||
<p class="nav">
|
||||
<img src="images/videoExit.png" alt="" class="videoExit" title="退出" />
|
||||
<img src="images/closeMute.png" alt="" title="静音" mute="close" class="closeMute" />
|
||||
<img src="images/videoImg.png" alt="" title="截图" class="videoImg" />
|
||||
<img src="images/startRecording.png" alt="" title="开始录像" class="startRecording" state="open" />
|
||||
<img src="images/videoWalk.png" alt="" title="对讲" state="close" class="videoWalk" />
|
||||
<img src="images/videoFullscreen.png" alt="" title="全屏" model="exitfullScreen" class="videoFullscreen" />
|
||||
<img src="images/videoReInfo.png" alt="" title="视频信息" state="close" class="videoReInfo" />
|
||||
</p>
|
||||
<div id="slideTest1" class="demo-slider"></div>
|
||||
<p class="power">
|
||||
<img src="images/power100.png" alt="" title="电量" />
|
||||
<span></span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!--倒计时-->
|
||||
<div class="videoTitle">
|
||||
<p>视频关闭中...</p>
|
||||
<p>正在努力关闭视频中,还需<span class="close_ing_time"></span>秒</p>
|
||||
<p>
|
||||
<button type="button" class="layui-btn layui-btn-primary">确认</button>
|
||||
<button type="button" class="layui-btn layui-btn-primary">取消</button>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!--截图-->
|
||||
<div class="canvasImg">
|
||||
<div class="canvasImgBox">
|
||||
<canvas id="canvas"></canvas>
|
||||
<p>
|
||||
<a href="#" id="save" download=".png">保存</a>
|
||||
<button id="cancel">取消</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--当js文件发生变化的时候,自动清除浏览器缓存,只要标签后面的v每次不一样浏览器就更新了阿-->
|
||||
<script>
|
||||
//创建一个script标签
|
||||
function loadScriptString() {
|
||||
var timeStamp = new Date().getTime();
|
||||
var script = document.createElement("script"); //创建一个script标签
|
||||
script.type = "module";
|
||||
script.src = `js/moveDeviceVideoOne.js?v=${timeStamp}`;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
}
|
||||
//创建一个link标签
|
||||
function loadLinkString() {
|
||||
var timeStamp = new Date().getTime();
|
||||
var css = document.createElement("link"); //创建一个script标签
|
||||
css.rel = "stylesheet";
|
||||
css.href = `css/moveDeviceVideoOne.css?v=${timeStamp}`
|
||||
document.getElementsByTagName('head')[0].appendChild(css);
|
||||
$("#video").css("height", "720px");
|
||||
}
|
||||
|
||||
loadScriptString();
|
||||
loadLinkString();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,100 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>视频查看</title>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate"/>
|
||||
<meta http-equiv="Cache" content="no-cache">
|
||||
<meta http-equiv="Pragma" content="no-cache" />
|
||||
<meta http-equiv="Expires" content="0" />
|
||||
<link rel="stylesheet" href="./layui.css">
|
||||
<script src="./jquery-3.4.1.min.js"></script>
|
||||
<script src="./layui.js"></script>
|
||||
<script src="AgoraRTC_N-4.11.0.js"></script>
|
||||
<!--给录像文件添加时间进度条-->
|
||||
<script src="fix-webm-duration.js"></script>
|
||||
</head>
|
||||
<body
|
||||
<!--视频显示-->
|
||||
<div id="video">
|
||||
<div class="inTheVideo">
|
||||
<!-- <img src="../images/inTheVideo.png" alt="" /> -->
|
||||
<span>REC</span>
|
||||
</div>
|
||||
<!--视频信息-->
|
||||
<div class="videoInfo">
|
||||
<p>丢包率:<span class="PacketLossRate">0</span>(%)</p>
|
||||
<p>接收码率:<span class="RecvBitrate">0</span>(Kbps)</p>
|
||||
<p>渲染帧率:<span class="RenderFrameRate">0</span>(fps)</p>
|
||||
<p>播放总时间:<span class="TotalPlayDuration">0</span>(s)</p>
|
||||
<p>卡顿总时间:<span class="TotalFreezeTime">0</span>(s)</p>
|
||||
<p>传输延时:<span class="TransportDelay">0</span>(ms)</p>
|
||||
</div>
|
||||
|
||||
<div id="agora_local"></div>
|
||||
</div>
|
||||
|
||||
<!--视频操作-->
|
||||
<div class="videoNav">
|
||||
<p class="nav">
|
||||
<img src="images/videoExit.png" alt="" class="videoExit" title="退出"/>
|
||||
<img src="images/closeMute.png" alt="" title="静音" mute="close" class="closeMute"/>
|
||||
<img src="images/videoImg.png" alt="" title="截图" class="videoImg"/>
|
||||
<img src="images/startRecording.png" alt="" title="开始录像" class="startRecording" state="open"/>
|
||||
<img src="images/videoWalk.png" alt="" title="对讲" state="close" class="videoWalk"/>
|
||||
<img src="images/videoFullscreen.png" alt="" title="全屏" model="exitfullScreen" class="videoFullscreen"/>
|
||||
<img src="images/videoReInfo.png" alt="" title="视频信息" state="close" class="videoReInfo"/>
|
||||
</p>
|
||||
<div id="slideTest1" class="demo-slider"></div>
|
||||
<!--<p class="power">
|
||||
<img src="images/power100.png" alt="" title="电量"/>
|
||||
<span></span>
|
||||
</p>-->
|
||||
</div>
|
||||
|
||||
<!--倒计时-->
|
||||
<div class="videoTitle">
|
||||
<p>视频关闭中...</p>
|
||||
<p>正在努力关闭视频中,还需<span class="close_ing_time"></span>秒</p>
|
||||
<p><button>确认</button><button>关闭</button></p>
|
||||
</div>
|
||||
|
||||
<!--截图-->
|
||||
<div class="canvasImg">
|
||||
<div class="canvasImgBox">
|
||||
<canvas id="canvas"></canvas>
|
||||
<p>
|
||||
<a href="#" id="save" download=".png">保存</a>
|
||||
<button id="cancel">取消</button>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--当js文件发生变化的时候,自动清除浏览器缓存,只要标签后面的v每次不一样浏览器就更新了阿-->
|
||||
<script>
|
||||
//创建一个script标签
|
||||
function loadScriptString() {
|
||||
var timeStamp=new Date().getTime();
|
||||
var script = document.createElement("script"); //创建一个script标签
|
||||
script.type = "module";
|
||||
script.src=`js/moveDeviceVideoOne.js?v=${timeStamp}`;
|
||||
document.getElementsByTagName('head')[0].appendChild(script);
|
||||
}
|
||||
|
||||
//创建一个link标签
|
||||
function loadLinkString(){
|
||||
var timeStamp=new Date().getTime();
|
||||
var css = document.createElement("link"); //创建一个script标签
|
||||
css.rel = "stylesheet";
|
||||
css.href=`css/moveDeviceVideoOne.css?v=${timeStamp}`
|
||||
document.getElementsByTagName('head')[0].appendChild(css);
|
||||
|
||||
$("#video").css("height","720px");
|
||||
}
|
||||
|
||||
loadScriptString();
|
||||
loadLinkString();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
After Width: | Height: | Size: 27 KiB |
|
@ -0,0 +1,25 @@
|
|||
// import { userLoginInfo } from "../../view/index/js/index.js";
|
||||
function createMqttData(deviceid: any, title: any, data: any, receiver: any) {
|
||||
var openObj = {
|
||||
"topic": deviceid + "_rtmtranfer",//设备号_rtmtranfer,微站名/ter_cmd
|
||||
"message": JSON.stringify({
|
||||
"title": title,
|
||||
// "sender": userLoginInfo["user_name"],
|
||||
"sender": 'test05',
|
||||
"department": "",
|
||||
"scope": "",
|
||||
"receiver": [receiver],
|
||||
"video": "",
|
||||
"rtm": (new Date().getTime()).toString(),
|
||||
"data": data,
|
||||
"userScope": "",
|
||||
"userBragide": "",
|
||||
"userDetachchment": "",
|
||||
"userBorough": "",
|
||||
"name": ""
|
||||
})
|
||||
}
|
||||
return openObj;
|
||||
}
|
||||
|
||||
export { createMqttData }
|
|
@ -0,0 +1,16 @@
|
|||
// import axios from "axios";
|
||||
// var url = 'https://www.hnjinglian.cn:2563/api_8083/firectrl/client/notice/sendmqtt'
|
||||
// function sendMqtt(data: any) {
|
||||
// return axios({
|
||||
// method: 'post',
|
||||
// url,
|
||||
// data: data
|
||||
// })
|
||||
// }
|
||||
// export { sendMqtt }
|
||||
|
||||
import api from '@/axios'
|
||||
function sendMqtt(data: any) {
|
||||
return api.post('/multialarm/video/keep', data)
|
||||
}
|
||||
export { sendMqtt }
|
|
@ -36,7 +36,7 @@ onMounted(() => {
|
|||
// iWidth: 600,
|
||||
// iHeight: 400,
|
||||
szId: 'player', //需要英文字母开头,唯一性,必填
|
||||
szBasePath: './', // 必填,与h5player.min.js的引用目录一致
|
||||
szBasePath: '/haikang', // 必填,与h5player.min.js的引用目录一致
|
||||
iMaxSplit: 1, // 分屏播放,默认最大分屏4*4
|
||||
iCurrentSplit: IS_MOVE_DEVICE ? 1 : 2,
|
||||
openDebug: true,
|
||||
|
@ -45,11 +45,6 @@ onMounted(() => {
|
|||
},
|
||||
bSupporDoubleClickFull: true, //是否支持双击全屏,默认true
|
||||
})
|
||||
myPlugin
|
||||
.JS_SetWindowControlCallback({
|
||||
pluginErrorHandler: function (index: any, iErrorCode: any, oError: any) {},
|
||||
})
|
||||
.then((res: any) => {})
|
||||
|
||||
var controlIndex = 2
|
||||
function playVideo() {
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
</el-form-item>
|
||||
<!-- <el-input v-model="0"></el-input> -->
|
||||
</div>
|
||||
|
||||
<!-- <button @click="stop">关闭</button> -->
|
||||
<div style="padding: 0px 20px; height: 75%; overflow: auto" v-show="show3">
|
||||
<a-tree
|
||||
v-loading="loading"
|
||||
|
@ -37,10 +39,10 @@
|
|||
:tree-data="treedataall"
|
||||
@select="selectA"
|
||||
>
|
||||
<template #title="{ title, level }">
|
||||
<template #title="{ title }">
|
||||
{{ title }}
|
||||
</template>
|
||||
<template #icon="{ level, deviceType, selected, title }">
|
||||
<template #icon="{ level, deviceType, title }">
|
||||
<img v-if="title == '湖南省'" style="" src="./indeximag/shu/一级.png" alt="" />
|
||||
<img v-if="level == '1'" style="" src="./indeximag/shu/一级.png" alt="" />
|
||||
<img v-if="level == '2'" style="" src="./indeximag/shu/二级.png" alt="" />
|
||||
|
@ -344,12 +346,14 @@
|
|||
</a-timeline>
|
||||
</div>
|
||||
|
||||
<el-dialog title="视频" v-model="dialogVisible" width="30%">
|
||||
<iframe style="width: 100%; height: 250px" :src="'https://www.jy-sh.com/h5sVideo/index.html?token=' + pointCode + '&autoplay=true'" frameborder="0"></iframe>
|
||||
</el-dialog>
|
||||
<div v-if="showIframe" class="iframe-container">
|
||||
<iframe :src="videoUrl" frameborder="0"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { createMqttData } from '@/utils/createMqttData'
|
||||
import { sendMqtt } from '@/utils/sendMqtt'
|
||||
import { DownOutlined, SmileOutlined, FrownOutlined, FrownFilled } from '@ant-design/icons-vue'
|
||||
import { useWebSocket } from '@vueuse/core'
|
||||
import { wsUrl } from '@/utils/webSocket'
|
||||
|
@ -369,7 +373,10 @@ import closeimag from './imag/infoClose.png'
|
|||
import { Ref, ref, watch, onMounted, onBeforeMount, reactive, getCurrentInstance, nextTick } from 'vue'
|
||||
// import AMapLoader from "@amap/amap-jsapi-loader";
|
||||
import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
|
||||
import { log } from 'util'
|
||||
|
||||
const showIframe = ref(false)
|
||||
const videoUrl = ref('')
|
||||
|
||||
const { proxy } = getCurrentInstance() as any
|
||||
const day = proxy.day
|
||||
const size = ref('')
|
||||
|
@ -377,7 +384,7 @@ const lodash = proxy.lodash
|
|||
const value1 = ref('a1')
|
||||
const zoom = ref('12')
|
||||
const center = ref([121.59996, 31.197646])
|
||||
const map = null
|
||||
let map: any
|
||||
const expandedKeys = ref([])
|
||||
const selectedKeys = ref([])
|
||||
const checkedKeys = ref([])
|
||||
|
@ -413,7 +420,7 @@ const gbht = () => {
|
|||
}
|
||||
|
||||
const isActive1 = ref('1')
|
||||
const qhzty2 = (data) => {
|
||||
const qhzty2 = (data: any) => {
|
||||
isActive1.value = data
|
||||
}
|
||||
|
||||
|
@ -434,7 +441,7 @@ const closee = () => {
|
|||
visible.value = false
|
||||
}
|
||||
//解锁
|
||||
const jiesuo = (data) => {
|
||||
const jiesuo = (data: any) => {
|
||||
api
|
||||
.post('/multialarm/client/alarm_event/unlock', {
|
||||
eventId: data.multiAlarmId,
|
||||
|
@ -465,7 +472,7 @@ const jiesuo = (data) => {
|
|||
})
|
||||
}
|
||||
//锁定
|
||||
const lock = (data) => {
|
||||
const lock = (data: any) => {
|
||||
api
|
||||
.post('/multialarm/client/alarm_event/lock', {
|
||||
eventId: data.multiAlarmId,
|
||||
|
@ -497,20 +504,20 @@ const lock = (data) => {
|
|||
})
|
||||
}
|
||||
//
|
||||
const printLeafs = (tree, jirearr) => {
|
||||
const printLeafs = (tree: any, jirearr: any) => {
|
||||
if (!tree.children) {
|
||||
tree.children = []
|
||||
jirearr.forEach((x) => {
|
||||
jirearr.forEach((x: any) => {
|
||||
if (tree.stationId == x.stationId) {
|
||||
tree.children.push(x)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
tree.children.forEach((child) => printLeafs(child, jirearr))
|
||||
tree.children.forEach((child: any) => printLeafs(child, jirearr))
|
||||
}
|
||||
}
|
||||
const isActive = ref('6')
|
||||
const qhzty = (data) => {
|
||||
const qhzty = (data: any) => {
|
||||
isActive.value = data
|
||||
switch (data) {
|
||||
case '1':
|
||||
|
@ -536,7 +543,7 @@ const qhzty = (data) => {
|
|||
const loading = ref(false)
|
||||
//四级组织树获取
|
||||
const treedataall = ref([])
|
||||
const gettree4 = (data) => {
|
||||
const gettree4 = (data: any) => {
|
||||
loading.value = true
|
||||
api
|
||||
.post('/common/client/user/org/tree4', {
|
||||
|
@ -565,7 +572,7 @@ const gettree4 = (data) => {
|
|||
})
|
||||
}
|
||||
//关闭
|
||||
const close = (info) => {
|
||||
const close = (info: any) => {
|
||||
api
|
||||
.post('/multialarm/client/alarm_event/close', {
|
||||
eventId: info.multiAlarmId,
|
||||
|
@ -609,7 +616,7 @@ const gridData = [
|
|||
address: 'New York City',
|
||||
},
|
||||
]
|
||||
const totypecn = (data) => {
|
||||
const totypecn = (data: any) => {
|
||||
if (data == '0') {
|
||||
return '未核验'
|
||||
} else if (data == '1') {
|
||||
|
@ -618,7 +625,7 @@ const totypecn = (data) => {
|
|||
return '核验为真'
|
||||
}
|
||||
}
|
||||
const toCn = (data) => {
|
||||
const toCn = (data: any) => {
|
||||
if (data == 'report') {
|
||||
return '信息上报'
|
||||
} else if (data == 'modify.userinfo') {
|
||||
|
@ -643,15 +650,15 @@ const num = ref(100)
|
|||
const handleChange = (value: number) => {
|
||||
// console.log(value)
|
||||
}
|
||||
const cz = (infoData, upstatuslist) => {
|
||||
const cz = (infoData: any, upstatuslist: any) => {
|
||||
let routeData = router.resolve({ path: '/index/communitymanage', query: { multiAlarmId: infoData.multiAlarmId, data: JSON.stringify(infoData), upstatuslist: JSON.stringify(upstatuslist) } })
|
||||
window.open(routeData.href, '_blank')
|
||||
}
|
||||
;(window as any).cz2 = (infoData, upstatuslist) => {
|
||||
;(window as any).cz2 = (infoData: any, upstatuslist: any) => {
|
||||
let routeData = router.resolve({ path: '/index/communitymanage', query: { multiAlarmId: infoData.multiAlarmId, data: JSON.stringify(infoData), upstatuslist: JSON.stringify(upstatuslist) } })
|
||||
window.open(routeData.href, '_blank')
|
||||
}
|
||||
const sendStationList = (rollCall_websocket, stationTempArr) => {
|
||||
const sendStationList = (rollCall_websocket: any, stationTempArr: any) => {
|
||||
var getIot = {
|
||||
msgcode: 102,
|
||||
msgname: 'station-sensor-list',
|
||||
|
@ -661,7 +668,7 @@ const sendStationList = (rollCall_websocket, stationTempArr) => {
|
|||
rollCall_websocket.send(msg)
|
||||
}
|
||||
const ingrssddata = ref()
|
||||
const clickKz = (dat2a) => {
|
||||
const clickKz = (dat2a: any) => {
|
||||
api
|
||||
.post('/multialarm/client/alarm_event/get_all_resource', {
|
||||
range: 1000,
|
||||
|
@ -701,8 +708,8 @@ const treedata = () => {
|
|||
.then((res) => {
|
||||
var gridSize = 60
|
||||
// console.log('总数', res)
|
||||
var points = []
|
||||
res.data.map((x) => {
|
||||
var points: any[]
|
||||
res.data.map((x: any) => {
|
||||
const marker = new AMap.Marker({
|
||||
position: new AMap.LngLat(x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude),
|
||||
offset: new AMap.Pixel(-15, -15),
|
||||
|
@ -726,7 +733,7 @@ const treedata = () => {
|
|||
})
|
||||
var count = points.length
|
||||
// 聚合点样式
|
||||
var _renderClusterMarker = function (context) {
|
||||
var _renderClusterMarker = function (context: any) {
|
||||
var factor = Math.pow(context.count / count, 1 / 18)
|
||||
var div = document.createElement('div')
|
||||
var Hue = 180 - factor * 180
|
||||
|
@ -777,7 +784,7 @@ const getdayline = () => {
|
|||
// console.log('当日报警列表', res)
|
||||
jinbao.value = res.data
|
||||
if (res.data.length > 0) {
|
||||
res.data.map((x) => {
|
||||
res.data.map((x: any) => {
|
||||
if (x.state == 'close') {
|
||||
const marker = new AMap.Marker({
|
||||
position: new AMap.LngLat(x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude),
|
||||
|
@ -881,7 +888,7 @@ const gettotal = () => {
|
|||
}
|
||||
//
|
||||
let deviceInfoWindow = ref(null)
|
||||
const selectA = (selectedKeys, e) => {
|
||||
const selectA = (selectedKeys: any, e: any) => {
|
||||
// console.log('selectedKeys',selectedKeys,e)
|
||||
if (selectedKeys[0].length >= 13) {
|
||||
let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude]
|
||||
|
@ -895,19 +902,19 @@ const selectA = (selectedKeys, e) => {
|
|||
state.map.setZoomAndCenter(205, targetLangLat)
|
||||
}
|
||||
}
|
||||
const selectB = (selectedKeys, e) => {
|
||||
const selectB = (selectedKeys: any, e: any) => {
|
||||
if (e.selectedNodes[0]) {
|
||||
let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude]
|
||||
state.map.panTo(targetLangLat)
|
||||
}
|
||||
}
|
||||
const selectC = (selectedKeys, e) => {
|
||||
const selectC = (selectedKeys: any, e: any) => {
|
||||
if (e.selectedNodes[0]) {
|
||||
let targetLangLat = [e.selectedNodes[0].longitude == null ? 0 : e.selectedNodes[0].longitude, e.selectedNodes[0].latitude == null ? 0 : e.selectedNodes[0].latitude]
|
||||
state.map.panTo(targetLangLat)
|
||||
}
|
||||
}
|
||||
const createSubstanceInfowindow = (obj, type) => {
|
||||
const createSubstanceInfowindow = (obj: any, type: any) => {
|
||||
//定义顶部标题
|
||||
var mdinfoTop = document.createElement('div')
|
||||
mdinfoTop.className = 'mapPopInfo'
|
||||
|
@ -938,7 +945,7 @@ const createSubstanceInfowindow = (obj, type) => {
|
|||
|
||||
return mdinfoTop
|
||||
}
|
||||
const createSubstanceInfowindow1 = (obj, type) => {
|
||||
const createSubstanceInfowindow1 = (obj: any, type: any) => {
|
||||
//定义顶部标题
|
||||
var mdinfoTop = document.createElement('div')
|
||||
mdinfoTop.className = 'mapPopInfo'
|
||||
|
@ -969,7 +976,7 @@ const createSubstanceInfowindow1 = (obj, type) => {
|
|||
|
||||
return mdinfoTop
|
||||
}
|
||||
const createSubstanceInfowindow2 = (obj, type) => {
|
||||
const createSubstanceInfowindow2 = (obj: any, type: any) => {
|
||||
//定义顶部标题
|
||||
var mdinfoTop = document.createElement('div')
|
||||
mdinfoTop.className = 'mapPopInfo'
|
||||
|
@ -1001,7 +1008,7 @@ const createSubstanceInfowindow2 = (obj, type) => {
|
|||
return mdinfoTop
|
||||
}
|
||||
|
||||
const getSubstanceInfoWindowContent2 = (obj, type) => {
|
||||
const getSubstanceInfoWindowContent2 = (obj: any, type: any) => {
|
||||
console.log('🚀 ~ getSubstanceInfoWindowContent2 ~ obj, type:', obj, type)
|
||||
var station = obj['station']
|
||||
var nickname = ''
|
||||
|
@ -1051,37 +1058,67 @@ const getSubstanceInfoWindowContent2 = (obj, type) => {
|
|||
const dialogVisible = ref(false)
|
||||
const pointCode = ref()
|
||||
|
||||
;(window as any).addrt = (a) => {
|
||||
;(window as any).addrt = (a: any) => {
|
||||
console.log('播放_______________', a)
|
||||
|
||||
// let routeData = router.resolve({ path: '/index/hkplay', query: { pointId: a.pointId } })
|
||||
// window.open(routeData.href, '_blank')
|
||||
if (a.deviceType == '00') {
|
||||
if (a.alarmType == 'isc') {
|
||||
try {
|
||||
// router.push({ path: '/index/hkplay', query: { pointId: a.pointId } })
|
||||
let routeData = router.resolve({ path: '/index/hkplay', query: { pointId: a.pointId } })
|
||||
// console.log('routeData.href_____________________', routeData.href)
|
||||
// routeData.href = 'index.html' + routeData.href
|
||||
console.log('routeData.href_____________________', routeData.href)
|
||||
|
||||
// console.log('🚀 ~ routeData:', JSON.stringify(routeData))
|
||||
// window.location.href = routeData.href
|
||||
|
||||
window.open(routeData.href, '_blank')
|
||||
// window.open('http://172.10.10.161:9527/#/index/hkplay?pointId=43000000581314000013', '_blank') //直接跳要么白屏,要么说未找到token
|
||||
// window.open('https://www.hndyjqrh.cn/#/index/hkplay?pointId=43000000581314000013', '_blank')
|
||||
} catch (error) {
|
||||
console.log('🚀 ~addrt error:', error)
|
||||
}
|
||||
} catch (error) {}
|
||||
}
|
||||
// window.open('https://www.jy-sh.com/h5sVideo/index.html?token=' + a.pointCode + '&autoplay=true')
|
||||
} else {
|
||||
window.open('https://www.jy-sh.com/webRtcVideo/moveDeviceVideoOne.html?id=' + a.deviceId)
|
||||
// 手持设备的播放
|
||||
var width = 1280
|
||||
var height = 760
|
||||
let deviceID = a.deviceId
|
||||
let timeID_: ReturnType<typeof setTimeout>
|
||||
function preview() {
|
||||
api.post('/multialarm/video/preview', { pointId: a.pointId }).then((res) => {
|
||||
console.log('🚀 ~ /multialarm/video/preview:', res)
|
||||
if (res.code === 0) {
|
||||
keep()
|
||||
timeID_ = setInterval(() => {
|
||||
console.log(111111)
|
||||
keep()
|
||||
}, 60000)
|
||||
}
|
||||
})
|
||||
}
|
||||
function keep() {
|
||||
api.post('/multialarm/video/keep', { pointId: a.pointId }).then((res) => {
|
||||
console.log('🚀 ~ /multialarm/video/keep:', res)
|
||||
})
|
||||
}
|
||||
function close() {
|
||||
api.post('/multialarm/video/close', { pointId: a.pointId }).then((res) => {
|
||||
console.log('🚀 ~ /multialarm/video/close:', res)
|
||||
})
|
||||
}
|
||||
var url = `/rtc/moveDeviceVideoOne.html?id=${deviceID}`
|
||||
const newWindow = window.open(url, '', 'width=' + width + ',height=' + height + ",top=0,left=0,status='no',location='no',resizable='no',toolbar='no'")
|
||||
preview()
|
||||
const onWindowClosed = () => {
|
||||
console.log('timerID, timeID', timerID, timeID_)
|
||||
close()
|
||||
clearInterval(timeID_)
|
||||
clearInterval(timerID)
|
||||
console.log('新窗口已关闭____成功')
|
||||
}
|
||||
let timerID: ReturnType<typeof setTimeout>
|
||||
if (newWindow) {
|
||||
timerID = setInterval(() => {
|
||||
if (newWindow.closed) {
|
||||
onWindowClosed()
|
||||
clearInterval(timerID)
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getSubstanceInfoWindowContent = (obj, type) => {
|
||||
const getSubstanceInfoWindowContent = (obj: any, type: any) => {
|
||||
// console.log('obj', obj, type)
|
||||
var station = obj['station']
|
||||
var nickname = ''
|
||||
|
@ -1170,7 +1207,7 @@ const getRealTimeAlarmSituation = () => {
|
|||
// console.log('实时警情', res)
|
||||
if (res.code == 0) {
|
||||
listData.value = res.data.reverse()
|
||||
res.data.map((x) => {
|
||||
res.data.map((x: any) => {
|
||||
const marker = new AMap.Marker({
|
||||
position: new AMap.LngLat(x.longitude == null ? 0 : x.longitude, x.latitude == null ? 0 : x.latitude),
|
||||
offset: new AMap.Pixel(-10, -10),
|
||||
|
@ -1201,7 +1238,7 @@ const getRealTimeAlarmSituation = () => {
|
|||
const infoData = ref({})
|
||||
const upstatuslist = ref([])
|
||||
const listindex = ref()
|
||||
const toinfo = (item, index) => {
|
||||
const toinfo = (item: any, index: number) => {
|
||||
listindex.value = index
|
||||
// dialogTableVisible.value = false;
|
||||
nextTick(() => {
|
||||
|
@ -1862,4 +1899,18 @@ const defaultProps = {
|
|||
border: 1px solid #2081c1;
|
||||
box-shadow: 0 0 3px 3px #244b68;
|
||||
}
|
||||
.iframe-container {
|
||||
width: 80%;
|
||||
height: 80%;
|
||||
position: fixed;
|
||||
top: 10%;
|
||||
left: 10%;
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
|
||||
background: #fff;
|
||||
}
|
||||
iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import {defineConfig, loadEnv, UserConfigExport} from 'vite'
|
||||
import { defineConfig, loadEnv, UserConfigExport } from 'vite'
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import * as path from "path";
|
||||
import { resolve } from 'path';
|
||||
import Components from 'unplugin-vue-components/vite';
|
||||
import {AntDesignVueResolver} from 'unplugin-vue-components/resolvers';
|
||||
import {visualizer} from 'rollup-plugin-visualizer'
|
||||
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers';
|
||||
import { visualizer } from 'rollup-plugin-visualizer'
|
||||
// @ts-ignore
|
||||
import {name, version, description, appName} from "./package.json";
|
||||
import { name, version, description, appName } from "./package.json";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
const __APP_INFO__ = {
|
||||
|
@ -20,7 +21,7 @@ const __APP_INFO__ = {
|
|||
const pathSrc = path.resolve(__dirname, 'src');
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default ({mode}): UserConfigExport => {
|
||||
export default ({ mode }): UserConfigExport => {
|
||||
const env: Record<string, string> = loadEnv(mode, process.cwd(), '')
|
||||
return defineConfig({
|
||||
define: {
|
||||
|
@ -32,7 +33,7 @@ export default ({mode}): UserConfigExport => {
|
|||
vue(),
|
||||
vueJsx(),
|
||||
Components({
|
||||
resolvers: [AntDesignVueResolver({importStyle: false})]
|
||||
resolvers: [AntDesignVueResolver({ importStyle: false })]
|
||||
}),
|
||||
visualizer({
|
||||
emitFile: false,
|
||||
|
@ -57,7 +58,8 @@ export default ({mode}): UserConfigExport => {
|
|||
changeOrigin: true,
|
||||
rewrite: path => path.replace(RegExp(`^${env['VITE_APP_WS_API']}`), ''),
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
},
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
|
@ -75,6 +77,7 @@ export default ({mode}): UserConfigExport => {
|
|||
comments: false
|
||||
}
|
||||
},
|
||||
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks(id) {
|
||||
|
|