<template>
|
<div class="content">
|
<div class="content-top">
|
<div class="grid-check">
|
<span
|
:class="guid === 1 ? 'iconfont icongongge1 activegongge':'iconfont icongongge1'"
|
@click="setGuid(1)"
|
></span>
|
<span
|
:class="guid === 2 ? 'iconfont icongongge activegongge':'iconfont icongongge'"
|
@click="setGuid(2)"
|
></span>
|
<span
|
:class="guid === 3 ? 'iconfont icongongge2 activegongge':'iconfont icongongge2'"
|
@click="setGuid(3)"
|
></span>
|
</div>
|
<div class="video-area">
|
<div class="info-list block">
|
<p class="title-partment">相关视频</p>
|
<!-- <div class="video-name" v-for="video in videoDetails.videoList" :key="video.id">
|
<i class="el-icon-film"></i>
|
<span>{{video.name}}</span>
|
</div>-->
|
<div
|
class="video-name"
|
:class="{'current':curVideo.ID==video.ID}"
|
@click="checkVideo(video,index)"
|
v-for="(video,index) in relativeVideos"
|
:key="video.ID"
|
>
|
<i class="el-icon-film"></i>
|
<span>{{video.Camera}}</span>
|
</div>
|
</div>
|
<div class="players" ref="playerWrap">
|
<template v-if="guid==1">
|
<div
|
class="video-item"
|
:ref="`gridVideoItem_${index}`"
|
v-for="(item,index) in videoWrapArr"
|
:key="index"
|
>
|
<div class="currentPlayer">
|
<!-- {{curVideo.ID}} -->
|
<!-- <img :src="curVideo.VideoCover" style="width:100px" /> -->
|
<ali-player
|
:source="'http://' + curVideo.VideoPath"
|
:markers="curVideo.marks"
|
:ref="`player_${curVideo.ID}`"
|
/>
|
</div>
|
</div>
|
</template>
|
<template v-else>
|
<div
|
class="video-item"
|
:ref="`gridVideoItem_${index}`"
|
v-for="(item,index) in videoWrapArr"
|
:key="index"
|
>
|
<template v-if="index<=videoArrs.length-1">
|
<div :class="{'currentPlayer':curVideo.ID==videoArrs[index].ID}">
|
<!-- {{videoArrs[index].ID}} -->
|
<!-- <img
|
:src="videoArrs[index].VideoCover"
|
style="width:100px"
|
/>-->
|
<ali-player
|
:source="'http://' + videoArrs[index].VideoPath"
|
:markers="videoArrs[index].marks"
|
:ref="`player_${videoArrs[index].ID}`"
|
/>
|
</div>
|
</template>
|
</div>
|
</template>
|
|
<!-- <div
|
class="video-item"
|
:class="{'active':item.ID==curVideo.ID}"
|
:ref="`gridVideoItem_${index}`"
|
v-for="(item,index) in videoWrapArr"
|
:key="index"
|
>
|
</div>-->
|
</div>
|
</div>
|
</div>
|
<div class="content-bottom">
|
<div class="bot-left block">
|
<p class="title-partment">快速标注</p>
|
<div class="flex-box" style="height:28px;">
|
<label style="padding-right:10px;">隐患问题:</label>
|
<el-radio v-model="curVideo.IsUnusual" label="0">无异常</el-radio>
|
<el-radio v-model="curVideo.IsUnusual" label="1">有异常</el-radio>
|
<el-button
|
icon="el-icon-plus"
|
size="mini"
|
v-show="curVideo.IsUnusual==1"
|
type="primary"
|
@click="addLabel(curVideo)"
|
>添加标注</el-button>
|
</div>
|
<div class="flex-box">
|
<label>标注信息:</label>
|
<div class="mark-list">
|
<div class="mark" v-for="mark in curVideo.LableLst" :key="mark.ID">
|
<div class="time">
|
<span>{{mark.Time}}</span>
|
<i class="el-icon-edit" @click="editCurLabel(mark)"></i>
|
<i class="el-icon-delete" @click="removeCurLabel(mark)"></i>
|
</div>
|
<div class="label-content">
|
<span>{{mark.Desc}}</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</div>
|
<div class="bot-right block">
|
<p class="title-partment">视频详情</p>
|
<div class="base-info">
|
<div>
|
<label>车号:</label>
|
<span>{{videoDetails.CarNumber}}</span>
|
</div>
|
<div>
|
<label>车次:</label>
|
<span>{{videoDetails.TrainNumber}}</span>
|
</div>
|
<div>
|
<label>时间:</label>
|
<span>{{videoDetails.VideoDate}}</span>
|
</div>
|
<div>
|
<label>司机|副司机:</label>
|
<span>{{videoDetails.Driver1}}|{{videoDetails.Driver2}}</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<el-dialog
|
class="label-dialog"
|
:visible="labelDialogVisible"
|
@close="labelDialogVisible=false"
|
:append-to-body="false"
|
>
|
<div class="label-check">
|
<el-checkbox-group v-model="labelCheckedList">
|
<el-checkbox v-for="item in labelOptions" :key="item.ID" :label="item.ID">{{item.Name}}</el-checkbox>
|
</el-checkbox-group>
|
</div>
|
<div class="btns">
|
<el-button @click="cancelLabelChecked" size="small">取消</el-button>
|
<el-button @click="submitLabelChecked()" size="small" type="primary">确定</el-button>
|
</div>
|
</el-dialog>
|
</div>
|
</template>
|
|
<script>
|
import { getlstInit, updateVideoAnalyze, getlst, getRelatedVideoInfo, getLabelMap, delLabel, editLabel } from '@/api/shuohuang';
|
import AliPlayer from './aliPlayer/index';
|
|
export default {
|
name: "VideoAnalyze",
|
components: {
|
AliPlayer
|
},
|
props: {
|
videoDetails: {
|
default: () => { return {} },
|
type: Object
|
}
|
},
|
data() {
|
return {
|
guid: 1,
|
labelDialogVisible: false,
|
curVideo: {},
|
videoArrs: [],
|
relativeVideos: [],
|
labelCheckedList: [],
|
videoWrapArr: [],
|
labelOptions: [],
|
selectedLabelId: '',
|
setLabelTime: 0,
|
}
|
},
|
watch: {
|
videoDetails: {
|
handler(newVal, oldVal) {
|
this.getVideos(newVal)
|
},
|
deep: true
|
},
|
},
|
mounted() {
|
this.renderLabelOpts();
|
this.setGuid(1);
|
this.getVideos(this.videoDetails);
|
},
|
methods: {
|
getVideos(video) {
|
let _this = this;
|
getRelatedVideoInfo({ UniqeID: video.UniqeID }).then(res => {
|
console.log(res)
|
_this.curVideo = res.data[0];
|
_this.videoArrs = res.data;
|
// _this.videoWrapArr.push(res.data[0]);
|
// _this.setGuid(1)
|
|
res.data.forEach(element => {
|
element.marks = _this.mergeMarks(element)
|
console.log(element.marks)
|
});
|
|
_this.relativeVideos = res.data;
|
|
})
|
},
|
renderLabelOpts() {
|
let _this = this;
|
getLabelMap().then(res => {
|
_this.labelOptions = res.data
|
})
|
},
|
checkVideo(video, index) {
|
this.curVideo = video;
|
if (index > 0 && this.guid == 1) {
|
//this.videoWrapArr =
|
}
|
},
|
|
setGuid(guid) {
|
let _this = this;
|
this.guid = guid;
|
// for(var i = 0; i < Math.pow(guid,2); i++){
|
// if(i>this.videoArrs.length-1){
|
// this.videoWrapArr[i] = this.videoArrs[i]
|
// }else{
|
// this.videoWrapArr[i] = {}
|
// }
|
// }
|
this.videoWrapArr = Math.pow(guid, 2);
|
|
this.$nextTick(() => {
|
for (var i = 0; i < Math.pow(guid, 2); i++) {
|
this.$refs[`gridVideoItem_${i}`][0].style.width = this.$refs['playerWrap'].offsetWidth / guid + 'px';
|
this.$refs[`gridVideoItem_${i}`][0].style.height = this.$refs['playerWrap'].offsetHeight / guid + 'px';
|
|
}
|
})
|
},
|
|
cancelLabelChecked() {
|
this.labelDialogVisible = false;
|
},
|
submitLabelChecked() {
|
let desc = this.labelCheckedList.map(lableId => {
|
for (let label of this.labelOptions) {
|
if (label.ID == lableId) {
|
return label.Name;
|
}
|
}
|
})
|
|
let query = {
|
ID: this.selectedLabelId,
|
ParentID: this.curVideo.ID + '',
|
Time: Math.round(this.setLabelTime) + '',
|
Codes: this.labelCheckedList.join(','),
|
Desc: desc.join(',')
|
};
|
|
editLabel(query).then(rsp => {
|
if (rsp && rsp.success) {
|
this.labelDialogVisible = false;
|
this.curVideo.LableLst = rsp.data;
|
this.$message.success("添加成功")
|
|
// 标注
|
this.setMarks(this.curVideo)
|
} else {
|
this.$message.warning(rsp.msg)
|
}
|
})
|
},
|
addLabel(video) {
|
this.labelCheckedList = [];
|
this.selectedLabelId = '';
|
this.labelDialogVisible = true;
|
|
// 保存点击标注的时间
|
this.setLabelTime = this.$refs[`player_${video.ID}`][0].getCurrentTime();
|
},
|
editCurLabel(mark) {
|
this.selectedLabelId = mark.ID;
|
this.labelCheckedList = mark.Codes.split(",");
|
this.labelDialogVisible = true;
|
},
|
removeCurLabel(mark) {
|
delLabel({ ID: mark.ID, ParentID: this.curVideo.ID }).then(rsp => {
|
if (rsp && rsp.success) {
|
this.curVideo.LableLst = rsp.data;
|
this.$message.success("删除成功")
|
// 标注
|
this.setMarks(this.curVideo)
|
} else {
|
this.$message.warning(rsp.msg)
|
}
|
})
|
},
|
mergeMarks(videoInfo) {
|
let marks = videoInfo.HotPoint.concat(videoInfo.LableLst).map(lable => {
|
return {
|
offset: lable.Time,
|
text: lable.Desc
|
}
|
})
|
|
return marks;
|
},
|
setMarks(video) {
|
let marks = this.mergeMarks(video);
|
this.$refs[`player_${video.ID}`][0].setProgressMarkers(marks);
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.content {
|
padding: 15px;
|
text-align: left;
|
.content-top {
|
margin-bottom: 10px;
|
.grid-check {
|
text-align: right;
|
margin-bottom: 6px;
|
span {
|
font-size: 20px;
|
color: #cacaca;
|
padding-left: 12px;
|
cursor: pointer;
|
&.activegongge {
|
color: #3d68e1;
|
}
|
}
|
}
|
.video-area {
|
display: flex;
|
.info-list {
|
width: 160px;
|
margin-right: 10px;
|
.video-name {
|
cursor: pointer;
|
color: #777;
|
margin-bottom: 10px;
|
&.current {
|
color: #409eff;
|
}
|
i {
|
padding-right: 4px;
|
}
|
}
|
}
|
.players {
|
width: 960px;
|
height: 540px;
|
display: flex;
|
flex-wrap: wrap;
|
.video-item {
|
background: black;
|
border: 1px solid #fff;
|
box-sizing: border-box;
|
.currentPlayer {
|
border: 2px solid aqua;
|
}
|
}
|
}
|
}
|
}
|
.content-bottom {
|
display: flex;
|
.bot-left {
|
flex: 1;
|
.flex-box {
|
align-items: baseline;
|
label {
|
padding-right: 10px;
|
}
|
.mark-list {
|
.time {
|
cursor: pointer;
|
font-size: 15px;
|
font-weight: bold;
|
color: #409eff;
|
span {
|
padding-right: 5px;
|
}
|
i[class^="el-icon"] {
|
padding: 3px;
|
}
|
}
|
.label-content {
|
font-size: 13px;
|
padding: 4px 0;
|
color: #888;
|
}
|
}
|
}
|
}
|
.bot-right {
|
width: 210px;
|
margin-left: 10px;
|
label {
|
color: #999;
|
padding-right: 8px;
|
}
|
}
|
}
|
|
.label-dialog {
|
.el-dialog {
|
width: 700px;
|
.label-check {
|
min-height: 400px;
|
margin-bottom: 20px;
|
.el-checkbox-group {
|
display: flex;
|
flex-wrap: wrap;
|
> label {
|
width: 50%;
|
text-align: left;
|
margin: 0;
|
}
|
}
|
}
|
}
|
}
|
}
|
</style>
|