emergencyEvacuationBigOne.vue 30 KB

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