emergencyEvacuationBig.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. <!--应急疏散大屏-->
  2. <template>
  3. <div class="emergencyEvacuationBig scrollbar-box">
  4. <div class="top-max-title-box">
  5. <p>{{title}}<span>{{minTitle}}</span></p>
  6. <!--<p class="inquire-button-one" @click="clickClosure">{{evacuationType?'执行疏散':'结束疏散'}}</p>-->
  7. <p></p>
  8. <p></p>
  9. <p class="reset-button-one" v-if="buttonType" @click="goAllBig"><i class="el-icon-full-screen" style="margin-right:10px;"></i>全屏</p>
  10. <p class="reset-button-one" v-if="!buttonType" @click="clickBack"><i class="el-icon-full-screen" style="margin-right:10px;"></i>退出全屏</p>
  11. <p class="reset-button-one" style="margin-left:20px;" v-if="buttonType" @click="backButton">返回</p>
  12. </div>
  13. <div class="video-max-box">
  14. <div class="video-for-box" v-for="(item,index) in videoList" :key="index">
  15. <div class="video-for-title-box">
  16. <div class="video-for-title">{{item.name}}</div>
  17. <div class="video-for-button" @click="videoFullScreen(index)">
  18. <img src="@/assets/newImages/icon_monitor_enlarge.png">
  19. </div>
  20. </div>
  21. <video class="video-box" :id="item.divId" ref="videoRef" autoplay controls muted width="610px" height="429px"></video>
  22. </div>
  23. </div>
  24. <pagination
  25. layout="total, prev, pager, next, jumper"
  26. style="margin:0 40px 50px;"
  27. v-show="videoMaxNum>0"
  28. :page-sizes="[4]"
  29. :total="videoMaxNum"
  30. :page.sync="videoPage"
  31. :limit.sync="videoPageSize"
  32. @pagination="videoPageNumButton"
  33. />
  34. <div class="map-max-box">
  35. <div class="map-left-box">
  36. <!--<div class="max-title-box">-->
  37. <!--<p>{{minTitle}}</p>-->
  38. <!--<p>疏散路径:</p>-->
  39. <!--<el-select v-model="value" placeholder="请选择" @change="lineEvacuate">-->
  40. <!--<el-option-->
  41. <!--v-for="item in routeList"-->
  42. <!--:key="item.id"-->
  43. <!--:label="item.name"-->
  44. <!--:value="item.id">-->
  45. <!--</el-option>-->
  46. <!--</el-select>-->
  47. <!--</div>-->
  48. <div class="map-big-box">
  49. <div class="map-min-box">
  50. <div class="map-min-for-box" :class="item.subjectId == subId?'map-min-for-box-color':''"
  51. v-for="(item,index) in fjList" :key="index">
  52. {{item.room}}
  53. </div>
  54. <img class="map-min-img" src="@/assets/ZDimages/icon_sjt.gif" v-show="lightList[0].type">
  55. <img class="map-min-img" src="@/assets/ZDimages/icon_yjt.gif" v-show="lightList[1].type">
  56. <img class="map-min-img" src="@/assets/ZDimages/icon_zjt.gif" v-show="lightList[2].type">
  57. <img class="map-min-img" src="@/assets/ZDimages/icon_yjt.gif" v-show="lightList[3].type">
  58. <img class="map-min-img" src="@/assets/ZDimages/icon_zjt.gif" v-show="lightList[4].type">
  59. <img class="map-min-img" src="@/assets/ZDimages/icon_yjt.gif" v-show="lightList[5].type">
  60. </div>
  61. </div>
  62. </div>
  63. <div class="map-right-box">
  64. <div class="bottom-max-box">
  65. <div class="select-button-box">
  66. <p class="select-button-title">疏散路径:</p>
  67. <div class="select-button-min-box">
  68. <el-select v-model="value" placeholder="请选择" @change="lineEvacuate" style="flex:1;">
  69. <el-option
  70. v-for="item in routeList"
  71. :key="item.id"
  72. :label="item.name"
  73. :value="item.id">
  74. </el-option>
  75. </el-select>
  76. <p class="inquire-button-one" @click="clickClosure">{{evacuationType?'执行疏散':'结束疏散'}}</p>
  77. </div>
  78. </div>
  79. <div class="select-button-box">
  80. <p class="select-button-title">疏散喇叭:</p>
  81. <div class="top-for-max-box">
  82. <div class="top-for-min-box" @click="trumpetClick(item)"
  83. :class="item.type?'for-color-a':'for-color-b'"
  84. v-for="(item,index) in trumpetList" :key="index">
  85. {{item.name}}
  86. <img v-if="item.type" src="@/assets/ZDimages/icon_30.png">
  87. </div>
  88. </div>
  89. </div>
  90. <div class="scrollbar-list scrollbar-box">
  91. <div class="for-scrollbar-box" v-for="(item,index) in informationList" :key="index">
  92. <p>{{item.date}}</p>
  93. <p>{{item.text}}</p>
  94. </div>
  95. <p v-if="!informationList[0]" style="line-height:40px;text-align: center;color:#999;font-size:14px;">暂无喇叭数据</p>
  96. </div>
  97. <div class="bottom-input-text-box">
  98. <el-input
  99. type="textarea"
  100. :rows="4"
  101. resize='none'
  102. maxLength="100"
  103. placeholder="请输入播报内容"
  104. v-model="textarea">
  105. </el-input>
  106. </div>
  107. <p class="bottom-button-p" @click="textParseUrlIps">发送</p>
  108. </div>
  109. </div>
  110. </div>
  111. </div>
  112. </template>
  113. <script>
  114. import { lablayout, lineEvacuateTow } from "@/api/laboratory/emergencyEvacuation";
  115. import { getListStatus } from '@/api/bigData/index.js'
  116. import flvjs from 'flv.js'
  117. import { evacuate, closure, lineEvacuate, IntelligentGuidance,getRedis,getDeviceList,textParseUrlIps,getCameraByFloor,startUrlJiNanDaXue,startUrl } from '@/api/executeThePlan.js'
  118. import mqtt from 'mqtt'
  119. export default {
  120. name: 'emergencyEvacuationBig',
  121. props:{
  122. routerType:{},
  123. },
  124. data() {
  125. return {
  126. mtopic:"lab/exit/line",
  127. client:{},
  128. buttonType:false,
  129. subId:"",
  130. type:"",
  131. value:"0",
  132. title:"",
  133. minTitle:"环境学院-祈福楼 环境与气象研究所",
  134. //疏散方向数据
  135. routeList:[
  136. {
  137. id:"1",
  138. name:"向左疏散",
  139. },
  140. {
  141. id:"2",
  142. name:"向右疏散",
  143. },
  144. {
  145. id:"0",
  146. name:"两侧疏散",
  147. },
  148. ],
  149. //监控列表
  150. videoNewList:[],
  151. videoList:[],
  152. //房间列表
  153. fjList:[],
  154. //灯列表
  155. lightList:[
  156. {
  157. id:"5",
  158. type:false,
  159. },
  160. {
  161. id:"2",
  162. type:false,
  163. },
  164. {
  165. id:"3",
  166. type:false,
  167. },
  168. {
  169. id:"4",
  170. type:false,
  171. },
  172. {
  173. id:"1",
  174. type:false,
  175. },
  176. {
  177. id:"6",
  178. type:false,
  179. },
  180. ],
  181. //喇叭列表
  182. trumpetList:[],
  183. //消息列表
  184. informationList:[],
  185. textarea:"",
  186. evacuationType:false,
  187. //视频数据
  188. videoMaxNum:0,
  189. videoPage:1,
  190. videoPageSize:4,
  191. videoPageList:[],
  192. }
  193. },
  194. created(){
  195. this.getRedis();
  196. //判断入口是否全屏路由地址
  197. if(this.routerType){
  198. //应急疏散页面进入
  199. this.buttonType = true;
  200. }else {
  201. //预案报警进入
  202. this.buttonType = false;
  203. }
  204. this.lablayout();
  205. },
  206. mounted(){
  207. this.subscriptionMQTT();
  208. this.getDeviceList();
  209. },
  210. methods:{
  211. //获取实验室的疏散数据
  212. lineEvacuateTow(id,type){
  213. lineEvacuateTow(id,type).then(response => {
  214. this.initialization(response.data);
  215. });
  216. },
  217. getCameraByFloor(){
  218. getCameraByFloor({floorId:5}).then(response => {
  219. this.startUrl(response.data);
  220. });
  221. },
  222. //文字转语音播放
  223. textParseUrlIps(){
  224. let self = this;
  225. let num = 0;
  226. let newList = [];
  227. for(let i=0;i<self.trumpetList.length;i++){
  228. if(self.trumpetList[i].type){
  229. let obj = {
  230. sn:self.trumpetList[i].deviceSn,
  231. port:self.trumpetList[i].port,
  232. deviceIp:self.trumpetList[i].deviceIp,
  233. type:"",
  234. name:"",
  235. speed:"",
  236. params:{
  237. tid:"",
  238. vol:"",
  239. urls:[]
  240. }
  241. };
  242. newList.push(obj);
  243. num++
  244. }
  245. }
  246. if(num == 0){
  247. this.msgError("请选择要播放的喇叭")
  248. return
  249. }
  250. if(!this.textarea){
  251. this.msgError("请输入要播放的内容")
  252. return
  253. }
  254. textParseUrlIps(newList,this.textarea).then(response => {
  255. console.log('response',response);
  256. this.textarea = "";
  257. let newObj = {
  258. date:response.data.date,
  259. text:response.data.text,
  260. };
  261. this.informationList.push(newObj);
  262. this.msgSuccess("操作成功")
  263. });
  264. },
  265. //喇叭选中
  266. trumpetClick(item){
  267. item.type = !item.type;
  268. },
  269. //获取喇叭列表
  270. getDeviceList(){
  271. let obj ={
  272. floorId:5,
  273. page:1,
  274. pageSize:100,
  275. };
  276. getDeviceList(obj).then(response => {
  277. for(let i=0;i<response.data.length;i++){
  278. response.data[i].type = false;
  279. }
  280. this.$set(this,'trumpetList',response.data)
  281. });
  282. },
  283. //MQTT订阅
  284. subscriptionMQTT(){
  285. let self = this;
  286. this.client = mqtt.connect(process.env.VUE_APP_BASE_MQTT_API, {
  287. username: process.env.VUE_APP_BASE_MQTT_USERNAME,
  288. password: process.env.VUE_APP_BASE_MQTT_PASSWORD
  289. });
  290. this.client.on("connect", e =>{
  291. console.log("连接成功");
  292. this.client.subscribe(this.mtopic, (err) => {
  293. if (!err) {
  294. console.log("订阅成功:" + this.mtopic);
  295. }
  296. });
  297. });
  298. this.client.on("message", (topic, message) => {
  299. if (message){
  300. let data = JSON.parse(message)
  301. if(topic == this.mtopic){
  302. console.log("应急疏散数据变更",data);
  303. //应急疏散数据变更
  304. if(data.data.EXIT_LINE_MESSAGE){
  305. this.evacuate();
  306. self.evacuationType = false;
  307. }else{
  308. if(self.evacuationType){
  309. self.msgSuccess("应急疏散已结束");
  310. }
  311. self.evacuationType = true;
  312. // self.$router.push({
  313. // path: "/emergencyManagement/evacuation/performEvacuation"
  314. // })
  315. // this.$parent.backPage();
  316. }
  317. }
  318. }
  319. });
  320. },
  321. //获取当前疏散状态
  322. getRedis(){
  323. let self = this;
  324. getRedis().then( data => {
  325. if(data.data){
  326. this.subId = data.data.subId;
  327. this.title = data.data.subName;
  328. this.evacuationType = false;
  329. this.evacuate();
  330. }else{
  331. if(localStorage.getItem('evacuationSubId')){
  332. this.subId = localStorage.getItem('evacuationSubId');
  333. this.title = localStorage.getItem('evacuationTitel');
  334. localStorage.removeItem('evacuationSubId')
  335. localStorage.removeItem('evacuationTitel')
  336. }else{
  337. this.subId = this.$route.query.subId;
  338. this.title = this.$route.query.text;
  339. }
  340. this.evacuationType = true;
  341. this.lineEvacuateTow(this.subId,0);
  342. }
  343. });
  344. },
  345. //获取实验室数据
  346. lablayout(){
  347. let self = this;
  348. let id = 137;
  349. lablayout(id).then(response => {
  350. for(let i=0;i<response.data.length;i++){
  351. if(response.data[i].id == 5){
  352. self.fjList = response.data[i].list;
  353. }
  354. }
  355. });
  356. },
  357. //执行预案
  358. evacuate(){
  359. let self = this;
  360. evacuate(this.subId).then( data => {
  361. if(data.code == 200){
  362. if(data.data){
  363. this.initialization(data.data);
  364. }
  365. }
  366. });
  367. },
  368. //结束预案
  369. clickClosure(){
  370. let self = this;
  371. if (this.evacuationType){
  372. this.$confirm('是否确认执行疏散?', "警告", {
  373. confirmButtonText: "确定",
  374. cancelButtonText: "取消",
  375. type: "warning"
  376. }).then(function() {
  377. self.lineEvacuate(0);
  378. }).then(() => {
  379. }).catch(() => {});
  380. } else {
  381. this.$confirm('是否确认结束疏散?', "警告", {
  382. confirmButtonText: "确定",
  383. cancelButtonText: "取消",
  384. type: "warning"
  385. }).then(function() {
  386. self.closure();
  387. }).then(() => {
  388. }).catch(() => {});
  389. }
  390. },
  391. closure(){
  392. let self = this;
  393. closure(this.subId).then( data => {
  394. if(data.code == 200){
  395. this.evacuationType = true;
  396. self.msgSuccess("操作成功")
  397. // self.$router.push({
  398. // path: "/emergencyManagement/evacuation/performEvacuation"
  399. // })
  400. // this.$parent.backPage();
  401. console.log("结束",data)
  402. }
  403. });
  404. },
  405. //切换线路
  406. lineEvacuate(e){
  407. let self = this;
  408. lineEvacuate(this.subId,e).then( data => {
  409. if(data.code == 200){
  410. self.msgSuccess("操作成功")
  411. if(data.data){
  412. this.initialization(data.data);
  413. this.evacuationType = false;
  414. }
  415. }
  416. });
  417. },
  418. //灯初始化
  419. initialization(list){
  420. let self = this;
  421. let newList = [
  422. {
  423. id:"5",
  424. type:false,
  425. },
  426. {
  427. id:"2",
  428. type:false,
  429. },
  430. {
  431. id:"3",
  432. type:false,
  433. },
  434. {
  435. id:"4",
  436. type:false,
  437. },
  438. {
  439. id:"1",
  440. type:false,
  441. },
  442. {
  443. id:"6",
  444. type:false,
  445. },
  446. ];
  447. for(let i=0;i<list.length;i++){
  448. for(let o=0;o<newList.length;o++){
  449. if(list[i].lightId == newList[o].id){
  450. newList[o].type = true;
  451. }
  452. }
  453. }
  454. this.lightList = newList;
  455. this.getCameraByFloor();
  456. },
  457. goAllBig(){
  458. this.$router.push({
  459. path: "/emergencyEvacuationBig",
  460. query: {
  461. subId: this.subId,
  462. text:this.title,
  463. type:"2",
  464. }
  465. })
  466. },
  467. //返回方法
  468. clickBack(){
  469. let self = this;
  470. self.$router.push({
  471. path: "/emergencyManagement/evacuation/performEvacuation",
  472. query: {
  473. subId: self.subId,
  474. text:self.title,
  475. }
  476. })
  477. },
  478. //返回按钮
  479. backButton(){
  480. let self = this;
  481. for(let i=0;i<self.videoNewList.length;i++){
  482. self.videoNewList[i].flvPlayer.pause();
  483. self.videoNewList[i].flvPlayer.unload();
  484. self.videoNewList[i].flvPlayer.detachMediaElement();
  485. self.videoNewList[i].flvPlayer.destroy();
  486. self.videoNewList[i].flvPlayer = null
  487. }
  488. this.$set(this,'videoNewList',[]);
  489. this.$parent.goPage(1);
  490. },
  491. //视屏全屏方法
  492. videoFullScreen(index){
  493. this.$refs.videoRef[index].webkitRequestFullScreen();
  494. },
  495. //获取摄像头地址
  496. async startUrl(rows){
  497. let self = this;
  498. let list = "";
  499. for(let i=0;i<rows.length;i++){
  500. list = list + rows[i]+","
  501. }
  502. let obj = {
  503. page:"1",
  504. count:"100",
  505. deviceIds:list,
  506. };
  507. let urlText = window.location.href;
  508. if(urlText.indexOf("192.168") != -1){
  509. const { data } = await startUrl(obj);
  510. if(data){
  511. self.videoPageList = [];
  512. for(let i=0;i<data.length;i++){
  513. let obj = {
  514. divId:'divId'+i,
  515. hasAudio:false,
  516. height:false,
  517. videoError:"",
  518. videoUrl:data[i].result.body.data.ws_flv,
  519. }
  520. self.videoPageList.push(obj)
  521. }
  522. this.videoMaxNum = this.videoPageList.length
  523. this.videoPageNumButton({page:1,limit:4});
  524. }
  525. } else {
  526. const { data } = await startUrlJiNanDaXue(obj);
  527. if(data){
  528. self.videoPageList = [];
  529. for(let i=0;i<data.length;i++){
  530. let text = 'ws://lab.sxitdlc.com/jinandaxue/stream/';
  531. let url = data[i].result.body.data.ws_flv;
  532. url = url.split("rtp/");
  533. let newUrl = text+'rtp/'+url[1];
  534. let obj = {
  535. divId:'divId'+i,
  536. hasAudio:false,
  537. height:false,
  538. videoError:"",
  539. videoUrl:newUrl,
  540. }
  541. self.videoPageList.push(obj)
  542. }
  543. this.videoMaxNum = this.videoPageList.length
  544. this.videoPageNumButton({page:1,limit:4});
  545. }
  546. }
  547. },
  548. //视频翻页处理
  549. videoPageNumButton(val){
  550. this.loading = true;
  551. let self = this;
  552. //清除已有播放流
  553. if(self.videoNewList[0]){
  554. for(let i=0;i<self.videoNewList.length;i++){
  555. self.videoNewList[i].flvPlayer.pause();
  556. self.videoNewList[i].flvPlayer.unload();
  557. self.videoNewList[i].flvPlayer.detachMediaElement();
  558. self.videoNewList[i].flvPlayer.destroy();
  559. self.videoNewList[i].flvPlayer = null;
  560. }
  561. self.videoNewList = [];
  562. }
  563. //计算新数据
  564. let num = 0;
  565. let numMax = val.page * val.limit;
  566. if(val.page!=0){
  567. num = ( val.page - 1 ) * val.limit
  568. }
  569. if(numMax>self.videoPageList.length){
  570. numMax = self.videoPageList.length;
  571. }
  572. let list = [];
  573. for(let i=num;i<numMax;i++){
  574. list.push(self.videoPageList[i]);
  575. }
  576. this.$set(this,'videoList',list);
  577. setTimeout(function(){
  578. self.videoPlay();
  579. },500);
  580. },
  581. videoPlay(){
  582. let self = this;
  583. this.loading = false;
  584. for(let i=0;i<self.videoList.length;i++){
  585. let obj = {
  586. player :{},
  587. flvPlayer:{}
  588. };
  589. obj.player = document.getElementById(self.videoList[i].divId);
  590. obj.flvPlayer = flvjs.createPlayer(
  591. {
  592. // isLive: true, //=> 是否为直播流
  593. // hasAudio: false, //=> 是否开启声音
  594. type: 'flv', //媒体类型 flv 或 mp4
  595. url: self.videoList[i].videoUrl //视频流地址
  596. },
  597. {
  598. enableStashBuffer: true,//启用 IO 存储缓冲区。 如果您需要实时流播放(最小延迟),请设置为 false,但如果存在网络抖动,则可能会停止。
  599. stashInitialSize: 128,//IO 存储缓冲区初始大小。 默认值为 384KB。 指示合适的大小可以改善视频加载/搜索时间。
  600. isLive: true,//是否是直播
  601. lazyLoadRecoverDuration: 30,//指示以秒为单位的lazyLoad 恢复时间边界。
  602. autoCleanupSourceBuffer: true,//进行自动清理
  603. autoCleanupMaxBackwardDuration: 3 * 60,//3 * 60 当向后缓冲持续时间超过这个值(以秒为单位)时,对 SourceBuffer 进行自动清理
  604. autoCleanupMinBackwardDuration: 2 * 60,//2 * 60 指示在执行自动清理时为后向缓冲区保留的持续时间(以秒为单位)。
  605. }
  606. );
  607. self.videoNewList.push(obj);
  608. // }
  609. console.log("i",i)
  610. }
  611. for(let i=0;i<self.videoNewList.length;i++){
  612. self.videoNewList[i].flvPlayer.attachMediaElement(self.videoNewList[i].player);
  613. self.videoNewList[i].flvPlayer.load(); //加载
  614. self.videoNewList[i].flvPlayer.play(); //加载
  615. }
  616. },
  617. videoFunction(){
  618. let self = this;
  619. // self.videoList = [];
  620. for(let i=0;i<self.checkedSubject.videoData.length;i++){
  621. let obj = {
  622. player :{},
  623. flvPlayer:{}
  624. };
  625. obj.player = document.getElementById(self.checkedSubject.videoData[i].divId);
  626. // if (flvjs.isSupported()) {
  627. obj.flvPlayer = flvjs.createPlayer(
  628. {
  629. // isLive: true, //=> 是否为直播流
  630. // hasAudio: false, //=> 是否开启声音
  631. type: self.checkedSubject.videoData[i].videoType, //媒体类型 flv 或 mp4
  632. url: self.checkedSubject.videoData[i].url //视频流地址
  633. },
  634. {
  635. enableStashBuffer: true,//启用 IO 存储缓冲区。 如果您需要实时流播放(最小延迟),请设置为 false,但如果存在网络抖动,则可能会停止。
  636. stashInitialSize: 128,//IO 存储缓冲区初始大小。 默认值为 384KB。 指示合适的大小可以改善视频加载/搜索时间。
  637. isLive: true,//是否是直播
  638. lazyLoadRecoverDuration: 30,//指示以秒为单位的lazyLoad 恢复时间边界。
  639. autoCleanupSourceBuffer: true,//进行自动清理
  640. autoCleanupMaxBackwardDuration: 3 * 60,//3 * 60 当向后缓冲持续时间超过这个值(以秒为单位)时,对 SourceBuffer 进行自动清理
  641. autoCleanupMinBackwardDuration: 2 * 60,//2 * 60 指示在执行自动清理时为后向缓冲区保留的持续时间(以秒为单位)。
  642. }
  643. );
  644. self.videoList.push(obj);
  645. // }
  646. console.log("i",i)
  647. }
  648. for(let i=0;i<self.videoList.length;i++){
  649. self.videoList[i].flvPlayer.attachMediaElement(self.videoList[i].player);
  650. self.videoList[i].flvPlayer.load(); //加载
  651. self.videoList[i].flvPlayer.play(); //加载
  652. }
  653. },
  654. //取消订阅关闭MQTT连接
  655. offMQTT(){
  656. this.client.unsubscribe(this.mtopic, error => {
  657. if (error) {
  658. console.log('Unsubscribe error', error)
  659. }
  660. })
  661. this.client.end();
  662. this.client = {};
  663. },
  664. },
  665. beforeDestroy() {
  666. //清除定时器
  667. let self = this;
  668. self.offMQTT();
  669. console.log("beforeDestroy");
  670. },
  671. }
  672. </script>
  673. <style scoped lang="scss">
  674. .emergencyEvacuationBig{
  675. height:100%;
  676. width:100%;
  677. display: flex !important;
  678. flex-direction: column;
  679. box-shadow: 0 0 8px 2px rgba(0, 0, 0, 0.1);
  680. overflow-y:scroll;
  681. p{
  682. margin:0;
  683. }
  684. .top-max-title-box{
  685. display: flex;
  686. padding:0 30px;
  687. p{
  688. margin:27px 0;
  689. }
  690. p:nth-child(1){
  691. font-size:18px;
  692. font-weight:700;
  693. color:#0045AF;
  694. line-height:40px;
  695. span{
  696. color:#999;
  697. font-size:14px;
  698. margin-left:20px;
  699. }
  700. }
  701. p:nth-child(2){
  702. margin-left:70px;
  703. width:120px;
  704. }
  705. p:nth-child(3){
  706. flex:1;
  707. }
  708. p:nth-child(4){
  709. width:120px;
  710. }
  711. }
  712. .video-max-box{
  713. .video-for-box{
  714. display: inline-block;
  715. width:348px;
  716. /*height:260px;*/
  717. height:196px;
  718. position: relative;
  719. margin:0 0 30px 30px;
  720. .video-for-title-box{
  721. position: absolute;
  722. top:0;
  723. left:0;
  724. width:348px;
  725. height:40px;
  726. background: rgba(0,0,0,0.2);
  727. display: flex;
  728. z-index:10;
  729. .video-for-title{
  730. flex:1;
  731. color:#fff;
  732. font-size:14px;
  733. line-height:40px;
  734. display: block;
  735. overflow:hidden;
  736. text-overflow:ellipsis;
  737. white-space:nowrap;
  738. padding:0 17px;
  739. }
  740. .video-for-button{
  741. width:40px;
  742. height:40px;
  743. cursor: pointer;
  744. img{
  745. height:20px;
  746. width:20px;
  747. margin:10px;
  748. }
  749. }
  750. }
  751. .video-box{
  752. /*height:260px;*/
  753. height:196px;
  754. width:348px;
  755. }
  756. }
  757. }
  758. .pagination-container{
  759. margin:0;
  760. }
  761. .map-max-box{
  762. flex:1;
  763. margin-left:18px;
  764. display: flex;
  765. .map-left-box{
  766. width:1143px;
  767. .max-title-box{
  768. display: flex;
  769. margin:0 0 25px;
  770. p:nth-child(1){
  771. line-height:40px;
  772. font-size:18px;
  773. font-weight:700;
  774. color:#094CB2;
  775. }
  776. p:nth-child(2){
  777. flex:1;
  778. line-height:40px;
  779. text-align: right;
  780. font-size:16px;
  781. }
  782. }
  783. .map-big-box{
  784. width:1143px;
  785. height:610px;
  786. border:1px solid #E0E0E0;
  787. margin-bottom:20px;
  788. overflow: hidden;
  789. .map-min-box{
  790. height:505px;
  791. width:1133px;
  792. margin:50px auto;
  793. background: url("../assets/ZDimages/icon_bj_syspmtcy_jinan.png");
  794. position: relative;
  795. .map-min-for-box{
  796. overflow: hidden;
  797. display: inline-block;
  798. line-height:150px;
  799. text-align: center;
  800. }
  801. .map-min-for-box-color{
  802. background: rgba(0,189,255,0.3);
  803. }
  804. .map-min-for-box:nth-child(1){
  805. margin:4px 143px 0 0;
  806. width:162px;
  807. height:162px;
  808. }
  809. .map-min-for-box:nth-child(2){
  810. margin:4px 0 0 0;
  811. width:101px;
  812. height:162px;
  813. }
  814. .map-min-for-box:nth-child(3){
  815. margin:4px 0 0 0;
  816. width:101px;
  817. height:162px;
  818. }
  819. .map-min-for-box:nth-child(4){
  820. margin:4px 0 0 0;
  821. width:100px;
  822. height:162px;
  823. }
  824. .map-min-for-box:nth-child(5){
  825. margin:4px 0 0 0;
  826. width:100px;
  827. height:162px;
  828. }
  829. .map-min-for-box:nth-child(6){
  830. margin:4px 0 0 0;
  831. width:100px;
  832. height:162px;
  833. }
  834. .map-min-for-box:nth-child(7){
  835. margin:4px 0 0 0;
  836. width:100px;
  837. height:162px;
  838. }
  839. .map-min-for-box:nth-child(8){
  840. margin:4px 60px 0 0;
  841. width:100px;
  842. height:162px;
  843. }
  844. .map-min-for-box:nth-child(9){
  845. margin: 90px 0 0 0;
  846. width: 92px;
  847. height: 240px;
  848. line-height:230px;
  849. }
  850. .map-min-for-box:nth-child(10){
  851. margin: 90px 0 0 0;
  852. width: 107px;
  853. height: 240px;
  854. line-height:230px;
  855. }
  856. .map-min-for-box:nth-child(11){
  857. margin: 90px 0 0 0;
  858. width: 107px;
  859. height: 240px;
  860. line-height:230px;
  861. }
  862. .map-min-for-box:nth-child(12){
  863. margin: 90px 0 0 0;
  864. width: 100px;
  865. height: 240px;
  866. line-height:230px;
  867. }
  868. .map-min-for-box:nth-child(13){
  869. margin: 90px 0 0 0;
  870. width: 100px;
  871. height: 240px;
  872. line-height:230px;
  873. }
  874. .map-min-for-box:nth-child(14){
  875. margin: 90px 0 0 0;
  876. width: 100px;
  877. height: 240px;
  878. line-height:230px;
  879. }
  880. .map-min-for-box:nth-child(15){
  881. margin: 90px 0 0 0;
  882. width: 100px;
  883. height: 240px;
  884. line-height:230px;
  885. }
  886. .map-min-for-box:nth-child(16){
  887. margin: 90px 0 0 0;
  888. width: 100px;
  889. height: 240px;
  890. line-height:230px;
  891. }
  892. .map-min-for-box:nth-child(17){
  893. margin: 90px 0 0 0;
  894. width: 100px;
  895. height: 240px;
  896. line-height:230px;
  897. }
  898. .map-min-for-box:nth-child(18){
  899. margin: 90px 60px 0 0;
  900. width: 100px;
  901. height: 240px;
  902. line-height:230px;
  903. }
  904. .map-min-img{
  905. position: absolute;
  906. width:40px;
  907. height:28px;
  908. }
  909. .map-min-img:nth-child(19){
  910. top: 128px;
  911. left: 175px;
  912. }
  913. .map-min-img:nth-child(20){
  914. top: 194px;
  915. left: 231px;
  916. }
  917. .map-min-img:nth-child(21){
  918. top: 194px;
  919. left: 540px;
  920. }
  921. .map-min-img:nth-child(22){
  922. top: 194px;
  923. left: 630px;
  924. }
  925. .map-min-img:nth-child(23){
  926. top: 194px;
  927. left: 940px;
  928. }
  929. .map-min-img:nth-child(24){
  930. top: 194px;
  931. left: 1030px;
  932. }
  933. }
  934. }
  935. }
  936. .map-right-box{
  937. flex:1;
  938. display: flex;
  939. flex-direction: column;
  940. height:610px;
  941. overflow: hidden;
  942. margin:0 10px 20px;
  943. .top-for-max-box{
  944. margin-left:15px;
  945. .top-for-min-box{
  946. width:110px;
  947. height:40px;
  948. line-height:40px;
  949. font-size:14px;
  950. padding:0 10px;
  951. display: inline-block;
  952. margin:0 13px 18px 0;
  953. border-radius:4px;
  954. cursor: pointer;
  955. position: relative;
  956. overflow: hidden;
  957. img{
  958. width:25px;
  959. height:25px;
  960. position: absolute;
  961. right:0;
  962. bottom:0;
  963. }
  964. }
  965. .for-color-a{
  966. border:1px solid #0183FA;
  967. color:#0183FA;
  968. }
  969. .for-color-b{
  970. border:1px solid #CCCCCC;
  971. color:#CCCCCC;
  972. }
  973. }
  974. .bottom-max-box{
  975. flex:1;
  976. display: flex;
  977. flex-direction: column;
  978. border:1px solid #E0E0E0;
  979. overflow: hidden;
  980. .select-button-box{
  981. font-weight:500;
  982. .select-button-title{
  983. font-size:14px;
  984. margin-left:15px;
  985. line-height:40px;
  986. color:#333;
  987. }
  988. .select-button-min-box{
  989. display: flex;
  990. margin-left:15px;
  991. .inquire-button-one{
  992. margin:0 20px;
  993. width:100px;
  994. font-size:14px;
  995. line-height:40px;
  996. height:40px;
  997. }
  998. }
  999. }
  1000. .scrollbar-list{
  1001. flex:1;
  1002. .for-scrollbar-box{
  1003. font-size:14px;
  1004. margin:0 15px;
  1005. p:nth-child(1){
  1006. line-height:40px;
  1007. text-align: center;
  1008. color:#999;
  1009. font-weight:500;
  1010. }
  1011. p:nth-child(2){
  1012. color:#666;
  1013. line-height:18px;
  1014. font-weight:500;
  1015. }
  1016. }
  1017. }
  1018. .bottom-input-text-box{
  1019. height:96px;
  1020. margin:20px 20px 0;
  1021. }
  1022. .bottom-button-p{
  1023. background:#0183FA;
  1024. color:#fff;
  1025. font-size:16px;
  1026. text-align: center;
  1027. line-height:40px;
  1028. border-radius:10px;
  1029. margin:20px 40px;
  1030. cursor: pointer;
  1031. }
  1032. }
  1033. }
  1034. }
  1035. }
  1036. </style>