644 lines
20 KiB
Vue
644 lines
20 KiB
Vue
<template>
|
||
<div class="content-box">
|
||
<!-- v-if="videoTypeShow" -->
|
||
<div class="videoTypeBox" v-if="videoTypeShow">
|
||
<el-form :inline="true" :model="videoTypeForm" class="demo-form-inline" >
|
||
<el-form-item label="视频源类型:" >
|
||
<el-radio-group v-model="videoTypeForm.videoType">
|
||
<el-radio label="实时视频"></el-radio>
|
||
<el-radio label="离线视频"></el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
<div>
|
||
<el-row>
|
||
<el-col :span="6" v-for="(item, index) in videoList" :key="item.id" :offset="index > 0 ? 0 : 0" >
|
||
<el-card :body-style="{ padding: '0px' }" class="card" >
|
||
<div class="type">
|
||
<img src="@/assets/img/AnalysisMain/leftTop.png" alt="" v-if="item.type=='实时视频'">
|
||
<img src="@/assets/img/AnalysisMain/leftTop2.png" alt="" v-if="item.type=='离线视频'">
|
||
</div>
|
||
<div class="name">
|
||
<img src="@/assets/img/AnalysisMain/ssVideo.png" alt="" v-if="item.type=='实时视频'">
|
||
<img src="@/assets/img/AnalysisMain/lxVideo.png" alt="" v-if="item.type=='离线视频'">
|
||
</div>
|
||
<div class="statusN">
|
||
<img src="@/assets/img/AnalysisMain/status.png" alt="" >
|
||
<span class="statusName">{{ item.status }}</span>
|
||
</div>
|
||
|
||
<!-- <div class="del" @click="open(item.id)"> <i class='el-icon-delete'></i></div> -->
|
||
<img :src="item.img" class="image" @click="goToPage(item.id,item.num,item.title,item.type,item.status)">
|
||
<div class="bot">
|
||
<span style=" vertical-align: middle;">
|
||
<img src="@/assets/img/AnalysisMain/video (1).png" alt="">
|
||
<!-- <img :src="item.img" alt=""> -->
|
||
</span>
|
||
<div class="bottom clearfix">
|
||
<time class="time">{{ item.title }}</time>
|
||
<!-- <el-button type="text" class="button">操作按钮</el-button> -->
|
||
<div class="streamAddress" :content="item.videoStreamAddress!=''? item.videoStreamAddress:item.videoPath">{{item.videoStreamAddress!=''? item.videoStreamAddress:item.videoPath}}</div>
|
||
</div>
|
||
|
||
<div class="st">
|
||
<!-- <span>{{ item.status }}</span> -->
|
||
<el-button type="primary" icon="el-icon-delete" @click="open(item.id)"></el-button>
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-card :body-style="{ padding: '0px' }">
|
||
<div class="middle">
|
||
<div style="width: 50%;height: 100%;margin: auto;padding-top: 15%;cursor: pointer;text-align: center;" @click="informationInfo('新增')">
|
||
<img src="@/assets/img/AnalysisMain/add.png" width="80%">
|
||
</div>
|
||
|
||
</div>
|
||
|
||
</el-card>
|
||
</el-col>
|
||
</el-row>
|
||
<div class="btn">
|
||
|
||
<el-button type="primary" @click="applicationBtn">保存</el-button>
|
||
<!-- <el-button type="primary" @click="stopAlgorithmBtn">关闭程序</el-button> -->
|
||
</div>
|
||
</div>
|
||
<!-- <div id="dialog" class="margin-top: 0px !important;"> -->
|
||
<el-dialog
|
||
title="视频源配置"
|
||
width="40%"
|
||
:visible.sync="dialogFormVisible"
|
||
>
|
||
<!-- <editModal ></editModal> -->
|
||
<el-form :model="form">
|
||
<el-form-item label="视频源名称" :label-width="formLabelWidth">
|
||
<el-input v-model="form.videoName" autocomplete="off" style="width:50%" placeholder="请输入视频源名称"></el-input>
|
||
</el-form-item>
|
||
<!-- <el-form-item label="视频源类型" :label-width="formLabelWidth">
|
||
<el-radio-group v-model="form.videoType">
|
||
<el-radio label="实时视频"></el-radio>
|
||
<el-radio label="离线视频"></el-radio>
|
||
</el-radio-group>
|
||
</el-form-item> -->
|
||
<el-form-item label="视频源地址" :label-width="formLabelWidth" v-if="videoTypeForm.videoType=='实时视频'">
|
||
<el-input v-model="form.videoStreamAddress" autocomplete="off" style="width:80%" placeholder="请输入视频源地址" >
|
||
<template slot="prepend">rtsp://</template>
|
||
</el-input>
|
||
<!-- <el-input v-model="form.videoStreamAddress" autocomplete="off" style="width:80%"></el-input> -->
|
||
</el-form-item>
|
||
<el-form-item label="离线视频上传" :label-width="formLabelWidth" v-if="videoTypeForm.videoType=='离线视频'">
|
||
<!-- <el-button slot="trigger" size="small" type="primary">选取文件</el-button> -->
|
||
<input type="file" id="fileExport" @change="handleFileChange" ref="inputer">
|
||
<el-button size="small" type="primary" @click="load">点击上传</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
<div slot="footer" class="dialog-footer">
|
||
<el-button @click="dialogFormVisible = false" :disabled="dis">取 消</el-button>
|
||
<el-button type="primary" @click="commit(form)" :disabled="dis">确 定</el-button>
|
||
</div>
|
||
</el-dialog>
|
||
<!-- </div> -->
|
||
|
||
|
||
</div>
|
||
|
||
</template>
|
||
|
||
<script>
|
||
import editModal from "@/views/bounced/maintenanceRemind";
|
||
import {getGetShipjk,getDeleteShipjk,getApplication,getStopAlgorithm} from "../api/index";
|
||
import serverUrl from "../config/apiurl.js"
|
||
import axios from 'axios'
|
||
import mqttConfig from "@/utils/mqttConfig.js";
|
||
var mqtt; //mqtt 处理对象(全局变量)
|
||
var client;
|
||
export default {
|
||
data(){
|
||
return{
|
||
receiveNews: "",
|
||
topicSends:[],
|
||
componentShow: "",
|
||
numArr:[],
|
||
currentDate: new Date(),
|
||
closeStatus: null,
|
||
dis:false,
|
||
dialogFormVisible: false,
|
||
videoTypeShow: false,
|
||
loading:true,
|
||
fileList: [],
|
||
form: {
|
||
radio:'',
|
||
videoName:'测试视频01',
|
||
city:'',
|
||
videoStreamAddress:'',
|
||
videoPath:''
|
||
},
|
||
formLabelWidth: '120px',
|
||
formLabelWidth: '200px',
|
||
videoTypeForm:{
|
||
videoType:'实时视频'
|
||
},
|
||
videoList:[],
|
||
fullscreenLoading: false
|
||
}
|
||
},
|
||
mounted() {
|
||
console.log("dialogFormVisible",this.dialogFormVisible)
|
||
this.getVideoList()
|
||
this.createMqtt()
|
||
},
|
||
//离开当前页面后执行
|
||
destroyed: function () {
|
||
// console.log("离开当前页")
|
||
// client.end();
|
||
},
|
||
methods: {
|
||
/** 创建mqtt */
|
||
createMqtt() {
|
||
//创建链接,接收数据
|
||
console.log(window.PubScribe,'********************');
|
||
window.PubScribe(null,-1,this.realInfo);
|
||
/*mqtt = new mqttConfig(this.topicSends);
|
||
client = mqtt.createConnect();
|
||
// client.subscribe(,, { qos: 0 })
|
||
// client.subscribe('img'+this.videoList[i].num, { qos: 0 }, (err)=> {
|
||
// if (!err) {
|
||
// console.log("订阅成功");
|
||
// client.publish('msg_stream',JSON.stringify({"msg_flag":parseInt(-1)}))
|
||
|
||
// } else {
|
||
// console.log('消息订阅失败!')
|
||
// }
|
||
// });
|
||
// setTimeout(function() {
|
||
client.subscribe(['hert','img0','img1','img2','img3','img4','img5','img6','img7'], { qos: 0 }, (err)=> {
|
||
if (!err) {
|
||
console.log("订阅图片成功");
|
||
// client.publish('msg_stream',JSON.stringify({"msg_flag":parseInt(-1)}))
|
||
|
||
} else {
|
||
console.log('消息订阅失败!')
|
||
}
|
||
});
|
||
// }, 5000);
|
||
client.on("message", (topic, message) => {
|
||
//数据分类
|
||
try {
|
||
// this.receiveNews = this.receiveNews.concat(message);
|
||
// this.realInfo(topic, this.receiveNews);
|
||
this.realInfo(topic, message);
|
||
} catch (error) {
|
||
|
||
}
|
||
});*/
|
||
},
|
||
//停止订阅mqtt
|
||
disConnect() {
|
||
// if (client != null) {
|
||
// client.unsubscribe(this.topicSends);
|
||
// client = null;
|
||
// }
|
||
},
|
||
/** 实时数据分类 */
|
||
realInfo(topic, message) {
|
||
// console.log("topic",topic)
|
||
switch (topic) {
|
||
// 接收托片
|
||
case "img0":
|
||
case "img1":
|
||
case "img2":
|
||
case "img3":
|
||
case "img4":
|
||
case "img5":
|
||
case "img6":
|
||
case "img7":
|
||
case "img8":
|
||
try {
|
||
const utf8decoder = new TextDecoder()
|
||
const u8arr = new Uint8Array(message)
|
||
const temp = utf8decoder.decode(u8arr) // 将二进制数据转为字符串
|
||
const msg = JSON.parse(temp) //这一步报错则返回的是二进制流图片,不报错则返回的是JSON的错误提示数据
|
||
// var newArr = []
|
||
//msg为转换后的JSON数据
|
||
if(msg.rate=='low'){
|
||
// console.log("msg", msg)
|
||
if(this.videoList.length!=0){
|
||
for (let i = 0; i < this.videoList.length; i++) {
|
||
if(msg.id==this.videoList[i].id){
|
||
this.videoList[i].img ='data:image/png;base64,' + msg.pic
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
// this.imgUrl3 = 'data:image/png;base64,' + msg.pic;
|
||
// console.log("imageUrl", imageUrl)
|
||
|
||
} catch (error) {
|
||
|
||
}
|
||
break;
|
||
case "hert":
|
||
try {
|
||
const utf8decoder = new TextDecoder()
|
||
const u8arr = new Uint8Array(message)
|
||
const temp = utf8decoder.decode(u8arr) // 将二进制数据转为字符串
|
||
const msg = JSON.parse(temp) //这一步报错则返回的是二进制流图片,不报错则返回的是JSON的错误提示数据
|
||
// console.log("hert", msg) //msg为转换后的JSON数据
|
||
if(msg==''){
|
||
|
||
}
|
||
|
||
} catch (error) {
|
||
|
||
}
|
||
break;
|
||
}
|
||
this.receiveNews = "";
|
||
},
|
||
informationInfo(data,item) {
|
||
console.log("data",data)
|
||
if(data=='新增'){
|
||
this.form={
|
||
radio: '',
|
||
videoName:'测试视频01',
|
||
city:'',
|
||
videoStreamAddress:'',
|
||
videoPath:''
|
||
},
|
||
|
||
this.dialogFormVisible = true;
|
||
}
|
||
|
||
},
|
||
open(item) {
|
||
console.log("item",item)
|
||
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
type: 'warning'
|
||
}).then(() => {
|
||
getDeleteShipjk({VideoId:item}).then(res=>{
|
||
console.log("res",res)
|
||
this.$message({
|
||
type: 'success',
|
||
message: '删除成功!'
|
||
});
|
||
this.getVideoList()
|
||
})
|
||
|
||
}).catch(() => {
|
||
this.$message({
|
||
type: 'info',
|
||
message: '已取消删除'
|
||
});
|
||
});
|
||
},
|
||
commit(form){
|
||
console.log("form",form)
|
||
let formData = new FormData();
|
||
formData.append("VideoName",form.videoName);
|
||
formData.append("VideoType",this.videoTypeForm.videoType);
|
||
if(this.videoTypeForm.videoType=='离线视频'){
|
||
formData.append("VideoPath",form.videoStreamAddress);
|
||
|
||
}else{
|
||
formData.append("VideoStreamAddress",form.videoStreamAddress);
|
||
}
|
||
axios({
|
||
method: "post",
|
||
url: serverUrl.dataUrl,
|
||
data:formData
|
||
}).then((res) => {
|
||
console.log("提交按钮",res)
|
||
if(res.data.msg=='添加成功'){
|
||
this.$message({
|
||
message: res.data.msg,
|
||
type: 'success'
|
||
});
|
||
this.getVideoList()
|
||
}else{
|
||
this.$message({
|
||
message: res.data.msg,
|
||
type: 'warning'
|
||
});
|
||
}
|
||
|
||
this.dialogFormVisible = false;
|
||
|
||
});
|
||
|
||
},
|
||
handleFileChange(e) {
|
||
let inputDOM = this.$refs.inputer;
|
||
this.file = inputDOM.files[0];// 通过DOM取文件数据
|
||
|
||
},
|
||
//应用
|
||
applicationBtn(){
|
||
getApplication().then(res=>{
|
||
console.log("res",res)
|
||
if(res.data.code==200){
|
||
const loading = this.$loading({
|
||
lock: true,
|
||
text: 'Loading',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
setTimeout(() => {
|
||
loading.close();
|
||
this.getVideoList()
|
||
this.$message({
|
||
message: res.data.msg,
|
||
type: 'success'
|
||
});
|
||
}, 5000);
|
||
}
|
||
})
|
||
},
|
||
//停止
|
||
stopAlgorithmBtn(){
|
||
getStopAlgorithm().then(res=>{
|
||
console.log("res",res)
|
||
if(res.data.code==200){
|
||
this.getVideoList()
|
||
this.$message({
|
||
message: res.data.msg,
|
||
type: 'success'
|
||
});
|
||
}
|
||
})
|
||
},
|
||
S4() {
|
||
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
|
||
},
|
||
guid() {
|
||
return (this.S4() + this.S4() + "-" + this.S4() + "-" + this.S4() + "-" + this.S4() + "-" + this.S4() + this.S4() + this.S4());
|
||
},
|
||
load() {
|
||
let size = this.file.size;//文件大小
|
||
|
||
let maxZrea = 8; //设置每个分区大小 MB
|
||
let bufferSize = maxZrea * (1024 * 1024);
|
||
let fileStart = 0;
|
||
let fileEnd = bufferSize;
|
||
let arrFile = [];
|
||
var loadingN = this.$loading({
|
||
lock: true,
|
||
text: '正在上传中',
|
||
target: '.el-dialog',
|
||
spinner: 'el-icon-loading',
|
||
background: 'rgba(0, 0, 0, 0.7)'
|
||
});
|
||
while (fileStart < size) {
|
||
var fileInfo = {
|
||
File: this.file.slice(fileStart, fileEnd),
|
||
Start: fileStart,
|
||
End: fileEnd
|
||
}
|
||
arrFile.push(fileInfo);
|
||
fileStart = fileEnd;
|
||
fileEnd = fileStart + bufferSize;
|
||
}
|
||
let count = arrFile.length;
|
||
let filename = this.file.name + "~" + this.guid();
|
||
for (var i = 0; i < count; i++) {
|
||
let formData = new FormData();//new一个formData事件
|
||
formData.append("file", arrFile[i].File); //将file属性添加到formData里
|
||
var url = serverUrl.getSpareElementOrder+"?Name=" + filename + "&Number=" + i + "&BufferSize=" + bufferSize + "&Count=" + count + "&Start=" + arrFile[i].Start + "&End=" + arrFile[i].End + "&Size=" + size;
|
||
axios.post(url, formData, {
|
||
headers: {
|
||
"Content-Type": "multipart/form-data;",
|
||
}
|
||
}).then(r => {
|
||
if (r.data.code!=200) {
|
||
|
||
}else{
|
||
if(r.data.data==null){
|
||
this.dis = true
|
||
}else{
|
||
this.dis = false
|
||
loadingN.close();
|
||
this.$message({
|
||
message: r.data.msg,
|
||
type: 'success'
|
||
});
|
||
this.form.videoStreamAddress=r.data.data
|
||
}
|
||
}
|
||
}).catch(e => {
|
||
console.log(e);
|
||
});
|
||
}
|
||
},
|
||
goToPage(id,num,name,type,status) {
|
||
|
||
this.$router.push({path:'index',query: {id:id,num:num,name:name,type:type,status:status
|
||
}})
|
||
|
||
},
|
||
//获取视频数据
|
||
getVideoList(){
|
||
getGetShipjk().then(res=>{
|
||
console.log("res",res)
|
||
if(res.data.msg=='成功'){
|
||
|
||
var arr = [];
|
||
res.data.data.forEach((item)=>{
|
||
arr.push({
|
||
id: item.videoId,
|
||
type: item.videoType,
|
||
title: item.videoName,
|
||
num:item.number,
|
||
status:item.status,
|
||
videoStreamAddress:item.videoStreamAddress,
|
||
videoPath:item.videoPath,
|
||
img: require('@/assets/img/AnalysisMain/img1.png'),
|
||
});
|
||
})
|
||
this.videoList=arr
|
||
if(this.videoList.length=='0'){
|
||
this.videoTypeShow = true
|
||
}else{
|
||
this.videoTypeShow = false
|
||
}
|
||
console.log("this.videoList",this.videoList)
|
||
}
|
||
})
|
||
},
|
||
|
||
handleRemove(file, fileList) {
|
||
console.log(file, fileList);
|
||
},
|
||
handlePreview(file) {
|
||
console.log(file);
|
||
},
|
||
handleExceed(files, fileList) {
|
||
this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
|
||
},
|
||
beforeRemove(file, fileList) {
|
||
return this.$confirm(`确定移除 ${ file.name }?`);
|
||
},
|
||
},
|
||
|
||
|
||
components: {
|
||
editModal
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style>
|
||
.time {
|
||
font-size: 13px;
|
||
color: #999;
|
||
}
|
||
.bot{
|
||
/* padding: 14px; */
|
||
padding: 8px 15px;
|
||
}
|
||
.streamAddress{
|
||
color: coral;
|
||
font-size: 12px;
|
||
padding-top: 5px;
|
||
|
||
}
|
||
.bottom {
|
||
margin-top: 10px;
|
||
line-height: 12px;
|
||
display: inline-block;
|
||
margin-left: 15px;
|
||
width: 67%;
|
||
text-overflow:ellipsis;
|
||
white-space:nowrap;
|
||
overflow:hidden;
|
||
}
|
||
.st{
|
||
position: absolute;
|
||
right: 4%;
|
||
top: 80%;
|
||
display: inline-block;
|
||
|
||
}
|
||
.st span{
|
||
color: #999;
|
||
}
|
||
.button {
|
||
padding: 0;
|
||
float: right;
|
||
}
|
||
|
||
.image {
|
||
width: 100%;
|
||
display: block;
|
||
|
||
}
|
||
|
||
.clearfix:before,
|
||
.clearfix:after {
|
||
display: table;
|
||
content: "";
|
||
}
|
||
|
||
.clearfix:after {
|
||
clear: both
|
||
}
|
||
.middle{
|
||
width: 100%;
|
||
/* height: 100%; */
|
||
height: 284px;
|
||
}
|
||
.el-col-6 {
|
||
width: 25%;
|
||
padding-left: 20px;
|
||
padding-top: 20px;
|
||
}
|
||
.type{
|
||
position: absolute;
|
||
left: 0;
|
||
top:0px;
|
||
z-index: 98;
|
||
}
|
||
.del{
|
||
position: absolute;
|
||
right: 0px;
|
||
top:0px;
|
||
width: 25px;
|
||
height: 25px;
|
||
z-index: 9999;
|
||
/* background-color: #999 */
|
||
}
|
||
.videoTypeBox{
|
||
background: #fff;
|
||
width: 98%;
|
||
margin-left: 1%;
|
||
display: flex;
|
||
padding-top: 20px;
|
||
padding-left: 30px;
|
||
}
|
||
.card{
|
||
position: relative;
|
||
cursor: pointer;
|
||
}
|
||
.name{
|
||
position: absolute;
|
||
left: 7px;
|
||
top:0px;
|
||
z-index: 99;
|
||
}
|
||
.statusN{
|
||
position: absolute;
|
||
left: 30px;
|
||
top:0px;
|
||
z-index: 97;
|
||
}
|
||
.statusName{
|
||
position: absolute;
|
||
left: 13px;
|
||
top: 6px;
|
||
z-index: 99;
|
||
color: #eee;
|
||
}
|
||
.el_dialog {
|
||
position: fixed;
|
||
width: 100%;
|
||
height: 100%;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
margin: 0;
|
||
padding: 0;
|
||
}
|
||
.el_dialog__content {
|
||
width: v-bind(width1);
|
||
height: 400px;
|
||
background-color: white;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
#dialog .el-dialog__header {
|
||
border-bottom: 1px solid #eee;
|
||
}
|
||
|
||
|
||
#dialog .el-dialog__title {
|
||
font-weight: bold;
|
||
color: #000;
|
||
}
|
||
.btn{
|
||
position: absolute;
|
||
right: 10%;
|
||
bottom: 18%;
|
||
}
|
||
</style>
|
||
|
||
|