emergencyEvacuationBigOne.vue 29 KB

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