123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776 |
- <template>
- <div>
- <transition name="fade">
- <div class="panel monitor" >
- <div class="panel-tit">
- 视频监控
- <img
- class="setting"
- src="@/assets/setting.png"
- alt=""
- @click="open"
- />
- </div>
- <ul class="monitor-list" >
- <!-- <div @click="opeanfullwin()" class="opean"></div> -->
- <li v-for="(hls, index) in hls_video" :key="index">
- <video
- v-if="hls.boolhls"
- class="hlsVideo monitor-height"
- @click="hlsVideo(hls.name)"
- :ref="hls.ref"
- controls
- preload="true"
- muted
- ></video>
- <p style="width:90%;margin:6px 5%;font-size: 1.4rem">{{hls.name}}</p>
- </li>
- </ul>
- <div class="panel-footer"></div>
- <div class="panel monitor-setting" v-if="showModal">
- <div class="panel-tit">
- 画面配置<img
- class="close"
- src="@/assets/close.png"
- alt=""
- @click="showModal = false"
- />
- </div>
- <div class="monitor-option">
- <el-form ref="form" :model="form" label-width="10rem">
- <el-form-item label="画面一:">
- <el-select class="main-select-tree" ref="selectTree" v-model="selectVideoHc[0].label" >
- <el-option v-for="item in formatData(list)" :key="item.value" :label="item.label" :value="item.label" class="select1" />
- <el-tree class="main-select-el-tree" ref="selecteltree"
- :data="list"
- node-key="id"
- highlight-current
- :props="defaultProps"
- @node-click="handleNodeClick($event,1)"
- :expand-on-click-node="expandOnClickNode"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="画面二:">
- <el-select class="main-select-tree" ref="selectTree" v-model="selectVideoHc[1].label" >
- <el-option v-for="item in formatData(list)" :key="item.value" :label="item.label" :value="item.label" class="select1" />
- <el-tree class="main-select-el-tree" ref="selecteltree"
- :data="list"
- node-key="id"
- highlight-current
- :props="defaultProps"
- @node-click="handleNodeClick($event,2)"
- :expand-on-click-node="expandOnClickNode"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="画面三:">
- <el-select class="main-select-tree" ref="selectTree" v-model="selectVideoHc[2].label" >
- <el-option v-for="item in formatData(list)" :key="item.value" :label="item.label" :value="item.label" class="select1" />
- <el-tree class="main-select-el-tree" ref="selecteltree"
- :data="list"
- node-key="id"
- highlight-current
- :props="defaultProps"
- @node-click="handleNodeClick($event,3)"
- :expand-on-click-node="expandOnClickNode"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="画面四:">
- <el-select class="main-select-tree" ref="selectTree" v-model="selectVideoHc[3].label" >
- <el-option v-for="item in formatData(list)" :key="item.value" :label="item.label" :value="item.label" class="select1" />
- <el-tree class="main-select-el-tree" ref="selecteltree"
- :data="list"
- node-key="id"
- highlight-current
- :props="defaultProps"
- @node-click="handleNodeClick($event,4)"
- :expand-on-click-node="expandOnClickNode"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="画面五:">
- <el-select class="main-select-tree" ref="selectTree" v-model="selectVideoHc[4].label" >
- <el-option v-for="item in formatData(list)" :key="item.value" :label="item.label" :value="item.label" class="select1" />
- <el-tree class="main-select-el-tree" ref="selecteltree"
- :data="list"
- node-key="id"
- highlight-current
- :props="defaultProps"
- @node-click="handleNodeClick($event,5)"
- :expand-on-click-node="expandOnClickNode"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="画面六:">
- <el-select class="main-select-tree" ref="selectTree" v-model="selectVideoHc[5].label" >
- <el-option v-for="item in formatData(list)" :key="item.value" :label="item.label" :value="item.label" class="select1" />
- <el-tree class="main-select-el-tree" ref="selecteltree"
- :data="list"
- node-key="id"
- highlight-current
- :props="defaultProps"
- @node-click="handleNodeClick($event,6)"
- :expand-on-click-node="expandOnClickNode"
- />
- </el-select>
- </el-form-item>
- <el-form-item style="margin-left:-2rem">
- <el-button @click="cancel">取消</el-button>
- <el-button type="primary" @click="submit"
- >保存</el-button
- >
- </el-form-item>
- </el-form>
- </div>
- <div class="panel-footer"></div>
- </div>
- </div>
- </transition>
- <iframe
- id="otherPage"
- align="middle"
- :src="iframe_Url"
- :style="'width:' + width + ';'"
- ></iframe>
- </div>
- </template>
- <script>
- import Hls from "hls.js";
- import { getLocalDeviceList, getLocalUnitNodes, getLocalChannel } from "@/api/device/camera";
- import api from "@/api/monitor";
- import { Message } from 'element-ui'
- export default {
- name: "monitor",
- props: {
- width: String,
- required: true,
- },
- data() {
- return {
- configKey: undefined,
- configName: undefined,
- configId:undefined,
- video:false,
- selectVideo:[
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- ],
- selectVideoHc:[
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- {
- name:undefined,
- id:undefined,
- url:undefined,
- label:undefined
- },
- ],
- expandOnClickNode: true,
- options:[],
- list:[],
- defaultProps: {
- children: 'children',
- label: 'label'
- },
- showModal_tow: false,
- showModal: false,
- hls: "",
- form: {
- name: "",
- region: "",
- region2: "",
- region3: "",
- region4: "",
- region5: "",
- region6: "",
- date1: "",
- date2: "",
- delivery: false,
- type: [],
- resource: "",
- desc: "",
- },
- hls_video: [],
- iframe_Url: "",
- tableData:[]
- };
- },
- created(){
- this.getVideoUrl()
- this.getList()
- },
- mounted() {
- let _this = this;
- _this.iframe_Url = window.PLATFROM_IFRAME.iframeUrl;
- // _this.getLocalChannel();
- window.addEventListener(
- "message",
- function (event) {
- var isDOM = typeof event.data === "object";
- // // 监听父窗口发送过来的数据向服务器发送post请求
- var data = event.data;
- if (isDOM == true) {
- if ("param" in data == true) {
- if (data.param.name === "17楼监控2") {
- _this.opeanfullwin(data.param.id);
- }
- } else {
- }
- }
- },
- false
- );
- },
- methods: {
- //获取视频配置数据
- getList(){
- getLocalDeviceList().then(Response =>{
- if(Response.data.pageList){
- let arr = []
- for(let a = 0; a<Response.data.pageList.length; a++){
- arr[a] = {}
- arr[a].label = Response.data.pageList[a].name
- arr[a].id = Response.data.pageList[a].id
- arr[a].children = []
- getLocalUnitNodes({deviceId:Response.data.pageList[a].id}).then(Response =>{
- for(let b = 0; b<Response.data.pageList.length; b++){
- arr[a].children[b] = {}
- arr[a].children[b].label = Response.data.pageList[b].deviceName
- arr[a].children[b].id = Response.data.pageList[b].id + 1000001 + b
- arr[a].children[b].children = []
- getLocalChannel({unitNdesUuid:Response.data.pageList[b].unitUuid,unitType:1}).then(Response =>{
- let data = Response.data.pageList
- for(let c = 0; c<data.length; c++){
- arr[a].children[b].children[c] = {}
- arr[a].children[b].children[c].id = data[c].id
- arr[a].children[b].children[c].name = arr[a].label + "/" + arr[a].children[b].label + "/" + data[c].name
- arr[a].children[b].children[c].label = data[c].name
- arr[a].children[b].children[c].url = "http://" + data[c].nvr_ip + ":" + data[c].hls_port + "/live/cameraid/" + arr[a].id + "%24" + data[c].id.split("$")[(data[c].id.split("$")).length-1] + "/substream/1.m3u8"
- }
- })
- }
- })
- }
- this.list = arr
- }
- })
- },
- //增加视频参数
- addVideoUrl(){
- var video = {}
- video.video = this.selectVideo
- api.addVideoUrl(
- {
- configKey: "video.top.device",
- configName: "video",
- configValue: JSON.stringify(video)
- }
- ).then(Response =>{
- if(Response.status == "SUCCESS"){
- Message({
- message: "摄像头配置添加成功",
- type: 'success'
- })
- }
- })
- },
- //获取视频参数
- getVideoUrl(){
- api.getVideoUrl("video.top.device").then(Response =>{
- if(Response.status == "SUCCESS"){
- this.selectVideo = this.deepClone(JSON.parse(Response.data.configValue).video)
- this.selectVideoHc = this.deepClone(JSON.parse(Response.data.configValue).video)
- for(let i =0;i<this.selectVideo.length;i++){
- this.hls_video.push({
- ref: "hlsVideo" + (i),
- name: (this.selectVideo[i].name).split("/")[2],
- hls: "hlsVideo" + (i),
- url:this.selectVideo[i].url,
- boolhls: true,
- boolimg: false,
- });
- this.loadVideoFn(this.hls_video[i].url, this.hls_video[i].ref, i)
- }
- }
- })
- },
- //修改数据
- updateVideoUrl(){
- var video = {}
- video.video = this.selectVideoHc
- api.updateVideoUrl(
- {
- configId:11,
- configKey: "video.top.device",
- configName: "video",
- configValue: JSON.stringify(video)
- }
- ).then(Response =>{
- if(Response.status == "SUCCESS"){
- Message({
- message: "摄像头配置修改成功",
- type: 'success'
- })
- }
- })
- },
- //下拉数据
- formatData(data){
- let options = [];
- data.forEach((item,key) => {
- options.push({label:item.label,value:item.id});
- if(item.children){
- item.children.forEach((items,keys) => {
- options.push({label:items.label,value:items.id});
- if(items.children){
- items.children.forEach((itemss,keyss) => {
- options.push({label:itemss.label,value:itemss.id});
- if(itemss.children){
- itemss.children.forEach((itemsss,keysss) => {
- options.push({label:itemsss.label,value:itemsss.id});
- });
- }
- });
- }
- });
- }
- });
- return options;
- },
- //下拉点击
- handleNodeClick(data,type) {
- if(data.name){
- var x = document.getElementsByClassName("el-select-dropdown");
- var i;
- for (i = 0; i < x.length; i++) {
- x[i].style.display = "none"
- }
- this.selectVideoHc[type-1].id = data.id
- this.selectVideoHc[type-1].name = data.name
- this.selectVideoHc[type-1].url = data.url
- this.selectVideoHc[type-1].label = data.label
- }
- },
- //下拉取消
- cancel(){
- this.selectVideoHc = []
- this.showModal = false
- },
- deepClone(obj){ //可传入对象 或 数组
- // 判断是否为 null 或 undefined 直接返回该值即可,
- if(obj === null || !obj)return obj;
- // 判断 是要深拷贝 对象 还是 数组
- if(Object.prototype.toString.call(obj)==="[object Object]"){ //对象字符串化的值会为 "[object Object]"
- let target = {}; //生成新的一个对象
- const keys = Object.keys(obj); //取出对象所有的key属性 返回数组 keys = [ ]
- //遍历复制值, 可用 for 循环代替性能较好
- keys.forEach(key=>{
- if(obj[key]&&typeof obj[key] === "object")
- //如果遇到的值又是 引用类型的 [ ] {} ,得继续深拷贝
- target[key] = this.deepClone(obj[key]);//递归
- else
- target[key] = obj[key];
- })
- return target //返回新的对象
- }else if(Array.isArray(obj)){
- // 数组同理
- let arr = [];
- obj.forEach((item,index)=>{
- if(item&&typeof item === "object")
- arr[index] = this.deepClone(item);
- else
- arr[index] = item;
- })
- return arr
- }
- },
- //
- open(){
- this.selectVideoHc = this.deepClone(this.selectVideo)
- this.showModal = true
- },
- //下拉保存
- submit(){
- this.updateVideoUrl()
- setTimeout(()=>{
- this.$emit('monitorChange')
- },1000)
- this.showModal = false
- },
- //画面配置事件处理
- video_hmpz(video, i) {
- var _this = this;
- var ref_video = this.hls_video[i].ref;
- var hls_video = this.hls_video[i].hls;
- if ((ref_video, this.$refs[ref_video][0] != undefined)) {
- this.$refs[ref_video][0].pause();
- hls_video.destroy();
- hls_video = null;
- }
- _this.loadVideoFn(video, _this.hls_video[i].ref, i);
- },
- abnormal() {},
- hlsVideo(name) {
- var myframe = document.getElementById("otherPage"); //获取iframe
- myframe.contentWindow.postMessage({ name: name }, "*"); //childDomain是子页面的源(协议+主机+端口号)
- },
- loadVideoFn: function (url, ref, i) { //播放器
- var that = this;
- var ref = ref
- setTimeout(() =>{
- if (Hls.isSupported()) {
- that.hls_video[i].hls = new Hls();
- that.hls_video[i].hls.loadSource(url);
- that.hls_video[i].hls.attachMedia(that.$refs[ref][0]);
- that.hls_video[i].hls.on(Hls.Events.MANIFEST_PARSED, () => {
- that.hls_video[i].boolhls = true;
- that.hls_video[i].boolimg = false;
- that.$refs["hlsVideo" + i][0].play();
- });
- that.hls_video[i].hls.on(Hls.Events.ERROR, (event, data) => {
- if (data.type === "networkError") {
- // 监听出错事件
- console.log("加载失败");
- // that.hls_video[i].boolhls = false;
- // that.hls_video[i].boolimg = true;
- }
- });
- }
- },1000)
- },
- //销毁hls 视频流
- destroyHls() {
- if(this.hls_video){
- for (let i = 0; i < this.hls_video.length; i++) {
- var ref_video = this.hls_video[i].ref;
- var hls_video = this.hls_video[i].hls;
- if ((ref_video, this.$refs[ref_video][0] != undefined)) {
- this.$refs[ref_video][0].pause();
- hls_video.destroy();
- hls_video = null;
- }
- }
- }
- },
- onSubmit() {
- },
- },
- // created: function () {
- // let _this = this;
- // _this.$once("hook:beforeDestroy", () => {
- // _this.destroyHls();
- // });
- // },
- };
- </script>
- <style lang="scss" scoped>
- .el-input__inner{
- width:130% !important;
- margin-left:-20%;
- }
- .el-select__caret{
- margin-right:-20px
- }
- // .opean{
- // position: absolute;
- // width: 100px;
- // height:100px;
- // background-color: red;
- // z-index: 100;
- // margin: 0 auto;
- // }
- .scene {
- position: fixed;
- z-index: 2000;
- top: 0;
- width: 100%;
- height: 100%;
- -webkit-perspective: 600;
- perspective: 600;
- display: flex;
- align-items: center;
- justify-content: center;
- }
- .scene svg {
- width: 240px;
- height: 240px;
- }
- .dc-logo {
- position: fixed;
- right: 10px;
- bottom: 10px;
- }
- .dc-logo:hover svg {
- -webkit-transform-origin: 50% 50%;
- transform-origin: 50% 50%;
- -webkit-animation: arrow-spin 2.5s 0s cubic-bezier(0.165, 0.84, 0.44, 1)
- infinite;
- animation: arrow-spin 2.5s 0s cubic-bezier(0.165, 0.84, 0.44, 1) infinite;
- }
- .dc-logo:hover:hover:before {
- padding: 6px;
- font: 10px/1 Monaco, sans-serif;
- font-size: 10px;
- color: #00fffe;
- text-transform: uppercase;
- position: absolute;
- left: -70px;
- top: -30px;
- white-space: nowrap;
- z-index: 20px;
- box-shadow: 0px 0px 4px #222;
- background: rgba(0, 0, 0, 0.4);
- }
- .dc-logo:hover:hover:after {
- content: "Digital Craft";
- padding: 6px;
- font: 10px/1 Monaco, sans-serif;
- font-size: 10px;
- color: #6e6f71;
- text-transform: uppercase;
- position: absolute;
- right: 0;
- top: -30px;
- white-space: nowrap;
- z-index: 20px;
- box-shadow: 0px 0px 4px #222;
- background: rgba(0, 0, 0, 0.4);
- background-image: none;
- }
- @-webkit-keyframes arrow-spin {
- 50% {
- -webkit-transform: rotateY(360deg);
- transform: rotateY(360deg);
- }
- }
- @keyframes arrow-spin {
- 50% {
- -webkit-transform: rotateY(360deg);
- transform: rotateY(360deg);
- }
- }
- .monitor-setting1 {
- width: 35%;
- height: 45rem;
- position: fixed;
- left: 0;
- right: 0;
- top: 20rem;
- z-index: 15;
- margin: 0 auto;
- }
- .height_clone {
- height: 45rem;
- }
- .hlsVideo {
- width: 18.5rem;
- // width: 100%;
- border: none;
- margin: 0 auto;
- margin-left: 5%;
- }
- // .monitor-height {
- // height: 150px;
- // }
- //视频监控
- .panel.monitor {
- margin-top: 2rem;
- z-index: 3;
- .panel-tit {
- position: relative;
- }
- }
- .monitor-list {
- padding: 1.2rem;
- height: calc(100vh - 51rem);
- overflow-y: scroll;
- }
- .monitor-list li {
- width: 50%;
- position: relative;
- display: block;
- float: left;
- }
- .monitor-list li img {
- width: 100%;
- display: block;
- }
- .monitor-tit {
- position: absolute;
- bottom: 0;
- width: 100%;
- left: 0;
- font-size: 1.2rem;
- line-height: 3rem;
- text-indent: 1rem;
- // display:none;
- background: rgba(0, 0, 0, 0.7);
- }
- .setting,
- .close {
- position: absolute;
- width: 2rem;
- right: 1.5rem;
- top: 1.3rem;
- cursor: pointer;
- z-index: 1;
- }
- .close {
- width: 1.7rem;
- cursor: pointer;
- }
- .monitor-setting {
- position: absolute;
- left: 105%;
- width: 100%;
- top: 0;
- margin: 0 auto;
- text-align: center;
- .monitor-option {
- position: relative;
- padding: 2rem 1rem 1rem 2rem;
- }
- }
- ::-webkit-scrollbar {
- display: none
- }
- </style>
- <style lang="scss">
- .monitor-setting .el-form-item__label {
- font-size: 1.6rem;
- color: #fff;
- line-height: 3.4rem;
- text-align: left;
- }
- .monitor-setting .el-form-item__content {
- line-height: 3.4rem;
- }
- .monitor-setting .el-form-item {
- margin-bottom: 1.6rem;
- }
- .monitor-setting .el-input__inner {
- height: 3.4rem;
- line-height: 3.4rem;
- border-radius: 0;
- font-size: 1.4rem;
- background-color: rgba(0, 0, 0, 0);
- border: 1px solid #3486da;
- }
- .monitor-setting .el-input__icon {
- line-height: 2.4rem;
- }
- .monitor-setting .el-button {
- border-radius: 0;
- font-size: 1.6rem;
- padding: 1rem 2.3rem;
- margin-top: 3rem;
- }
- .monitor-setting .el-select .el-input .el-select__caret {
- color: #3486da;
- font-size: 1.6rem;
- }
- .monitor-setting .el-select:hover .el-input__inner {
- border: 1px solid #3486da;
- opacity: 0.7;
- }
- .main-select-el-tree .el-tree-node .is-current > .el-tree-node__content{font-weight: bold; color: #409eff;}
- .main-select-el-tree .el-tree-node.is-current > .el-tree-node__content{font-weight: bold; color: #409eff;}
- .select1{
- display:none;
- }
- </style>
|