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,getRedis,getDeviceList,textParseUrlIps,getCameraByFloor,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. },
  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. let videoList = response.data;
  222. subjectInfo(this.subId,0).then(res => {
  223. if (res.data.labHardwareVOList){
  224. for(let i=0;i<res.data.labHardwareVOList.length;i++){
  225. if(res.data.labHardwareVOList[i].hardwareTypeEnum.enumName == 'VIDEO_MONITOR'){
  226. videoList.unshift(res.data.labHardwareVOList[i].hardwareNUM);
  227. }
  228. }
  229. }
  230. videoList = [...new Set(videoList)]
  231. if (videoList[0]){
  232. this.startUrl(videoList);
  233. }
  234. })
  235. });
  236. },
  237. //文字转语音播放
  238. textParseUrlIps(){
  239. let self = this;
  240. let num = 0;
  241. let newList = [];
  242. for(let i=0;i<self.trumpetList.length;i++){
  243. if(self.trumpetList[i].type){
  244. let obj = {
  245. sn:self.trumpetList[i].deviceSn,
  246. port:self.trumpetList[i].port,
  247. deviceIp:self.trumpetList[i].deviceIp,
  248. type:"",
  249. name:"",
  250. speed:"",
  251. params:{
  252. tid:"",
  253. vol:self.trumpetList[i].deviceVol,
  254. urls:[]
  255. }
  256. };
  257. newList.push(obj);
  258. num++
  259. }
  260. }
  261. if(num == 0){
  262. this.msgError("请选择要播放的喇叭")
  263. return
  264. }
  265. if(!this.textarea){
  266. this.msgError("请输入要播放的内容")
  267. return
  268. }
  269. textParseUrlIps(newList,this.textarea).then(response => {
  270. this.textarea = "";
  271. let newObj = {
  272. date:response.data.date,
  273. text:response.data.text,
  274. };
  275. this.informationList.push(newObj);
  276. this.msgSuccess("操作成功")
  277. });
  278. },
  279. //喇叭选中
  280. trumpetClick(item){
  281. item.type = !item.type;
  282. if(item.type==true){
  283. this.trumpetList.forEach(function(item2) {
  284. if(item2.deviceSn==item.deviceSn){
  285. item2.type=true
  286. }else{
  287. item2.type=false
  288. }
  289. })
  290. }
  291. },
  292. //获取喇叭列表
  293. getDeviceList(){
  294. let obj ={
  295. subId:this.subId,
  296. floorId:this.buttonId,
  297. page:1,
  298. pageSize:100,
  299. };
  300. getDeviceList(obj).then(response => {
  301. for(let i=0;i<response.data.length;i++){
  302. response.data[i].type = false;
  303. }
  304. this.$set(this,'trumpetList',response.data)
  305. });
  306. },
  307. //MQTT订阅
  308. subscriptionMQTT(){
  309. let self = this;
  310. this.client = mqtt.connect(localStorage.getItem('mqttUrl'), {
  311. username: localStorage.getItem('mqttUser'),
  312. password: localStorage.getItem('mqttPassword')
  313. });
  314. this.client.on("connect", e =>{
  315. this.client.subscribe(this.mtopic, (err) => {
  316. if (!err) {
  317. }
  318. });
  319. });
  320. this.client.on("message", (topic, message) => {
  321. if (message){
  322. let data = JSON.parse(message)
  323. if(topic == this.mtopic){
  324. //应急疏散数据变更
  325. if(data.data.EXIT_LINE_MESSAGE){
  326. this.evacuate();
  327. self.evacuationType = false;
  328. }else{
  329. if(self.evacuationType){
  330. self.msgSuccess("应急疏散已结束");
  331. }
  332. self.evacuationType = true;
  333. // self.$router.push({
  334. // path: "/emergencyManagement/evacuation/performEvacuation"
  335. // })
  336. // this.$parent.backPage();
  337. }
  338. }
  339. }
  340. });
  341. },
  342. //获取当前疏散状态
  343. getRedis(){
  344. let self = this;
  345. getRedis().then( data => {
  346. if(data.data){
  347. this.subId = data.data.subId;
  348. this.title = data.data.subName;
  349. this.buildingId = data.data.buildId;
  350. this.buttonId = data.data.floorId;
  351. this.address = data.data.deptName+'-'+data.data.buildName+'-'+data.data.floorName;
  352. this.evacuationType = false;
  353. this.evacuate();
  354. this.getDeviceList();
  355. }else{
  356. if(localStorage.getItem('evacuationSubId')){
  357. this.subId = localStorage.getItem('evacuationSubId');
  358. this.title = localStorage.getItem('evacuationTitel');
  359. this.buttonId = localStorage.getItem('evacuationButtonId');
  360. this.buildingId = localStorage.getItem('evacuationBuildingId');
  361. this.address = localStorage.getItem('evacuationAddress');
  362. localStorage.removeItem('evacuationSubId')
  363. localStorage.removeItem('evacuationTitel')
  364. localStorage.removeItem('evacuationButtonId')
  365. localStorage.removeItem('evacuationBuildingId')
  366. localStorage.removeItem('evacuationAddress')
  367. }else{
  368. this.subId = this.$route.query.subId;
  369. this.title = this.$route.query.text;
  370. this.buttonId = this.$route.query.buttonId;
  371. this.buildingId = this.$route.query.buildingId;
  372. this.address = this.$route.query.address;
  373. }
  374. this.evacuationType = true;
  375. this.lineEvacuateTow(this.subId,0);
  376. this.getDeviceList();
  377. }
  378. this.lablayout();
  379. });
  380. },
  381. //获取实验室数据
  382. lablayout(){
  383. let self = this;
  384. let id = this.buildingId;
  385. lablayout(id).then(response => {
  386. for(let i=0;i<response.data.length;i++){
  387. if(response.data[i].id == this.buttonId){
  388. self.fjList = response.data[i].list;
  389. }
  390. }
  391. });
  392. },
  393. //执行预案
  394. evacuate(){
  395. let self = this;
  396. evacuate(this.subId).then( data => {
  397. if(data.code == 200){
  398. if(data.data){
  399. this.initialization(data.data);
  400. }
  401. }
  402. });
  403. },
  404. //结束预案
  405. clickClosure(){
  406. let self = this;
  407. if (this.evacuationType){
  408. this.$confirm('是否确认执行疏散?', "警告", {
  409. confirmButtonText: "确定",
  410. cancelButtonText: "取消",
  411. type: "warning"
  412. }).then(function() {
  413. self.lineEvacuate(0);
  414. }).then(() => {
  415. }).catch(() => {});
  416. } else {
  417. this.$confirm('是否确认结束疏散?', "警告", {
  418. confirmButtonText: "确定",
  419. cancelButtonText: "取消",
  420. type: "warning"
  421. }).then(function() {
  422. self.closure();
  423. }).then(() => {
  424. }).catch(() => {});
  425. }
  426. },
  427. closure(){
  428. let self = this;
  429. closure(this.subId).then( data => {
  430. if(data.code == 200){
  431. this.evacuationType = true;
  432. self.msgSuccess("操作成功")
  433. // self.$router.push({
  434. // path: "/emergencyManagement/evacuation/performEvacuation"
  435. // })
  436. // this.$parent.backPage();
  437. }
  438. });
  439. },
  440. //切换线路
  441. lineEvacuate(e){
  442. let self = this;
  443. lineEvacuate(this.subId,e).then( data => {
  444. if(data.code == 200){
  445. self.msgSuccess("操作成功")
  446. if(data.data){
  447. this.initialization(data.data);
  448. this.evacuationType = false;
  449. }
  450. }
  451. });
  452. },
  453. //灯初始化
  454. initialization(list){
  455. let self = this;
  456. let newList = [
  457. {
  458. id:"5",
  459. type:false,
  460. },
  461. {
  462. id:"2",
  463. type:false,
  464. },
  465. {
  466. id:"3",
  467. type:false,
  468. },
  469. {
  470. id:"4",
  471. type:false,
  472. },
  473. {
  474. id:"1",
  475. type:false,
  476. },
  477. {
  478. id:"6",
  479. type:false,
  480. },
  481. ];
  482. for(let i=0;i<list.length;i++){
  483. for(let o=0;o<newList.length;o++){
  484. if(list[i].lightId == newList[o].id){
  485. newList[o].type = true;
  486. }
  487. }
  488. }
  489. this.lightList = newList;
  490. this.getCameraByFloor();
  491. },
  492. goAllBig(){
  493. this.$router.push({
  494. path: "/emergencyEvacuationBig",
  495. query: {
  496. subId: this.subId,
  497. text:this.title,
  498. buttonId : this.buttonId,
  499. buildingId : this.buildingId,
  500. type:"2",
  501. }
  502. })
  503. },
  504. //返回方法
  505. clickBack(){
  506. let self = this;
  507. self.$router.push({
  508. path: "/emergencyManagement/evacuation/performEvacuation",
  509. query: {
  510. subId: self.subId,
  511. text:self.title,
  512. buttonId : self.buttonId,
  513. buildingId : self.buildingId,
  514. }
  515. })
  516. },
  517. //返回按钮
  518. backButton(){
  519. let self = this;
  520. for(let i=0;i<self.videoNewList.length;i++){
  521. self.videoNewList[i].flvPlayer.pause();
  522. self.videoNewList[i].flvPlayer.unload();
  523. self.videoNewList[i].flvPlayer.detachMediaElement();
  524. self.videoNewList[i].flvPlayer.destroy();
  525. self.videoNewList[i].flvPlayer = null
  526. }
  527. this.$set(this,'videoNewList',[]);
  528. this.$parent.goPage(1);
  529. },
  530. //视屏全屏方法
  531. videoFullScreen(index){
  532. this.$refs.videoRef[index].webkitRequestFullScreen();
  533. },
  534. //获取摄像头地址
  535. async startUrl(rows){
  536. let self = this;
  537. let list = "";
  538. for(let i=0;i<rows.length;i++){
  539. list = list + rows[i]+","
  540. }
  541. let obj = {
  542. page:"1",
  543. count:"100",
  544. deviceIds:list,
  545. };
  546. let urlText = window.location.href;
  547. if(urlText.indexOf(localStorage.getItem('ipIdentify')) != -1){
  548. const { data } = await startUrl(obj);
  549. if(data){
  550. self.videoPageList = [];
  551. for(let i=0;i<data.length;i++){
  552. let obj = {
  553. divId:'divId'+i,
  554. hasAudio:false,
  555. height:false,
  556. videoError:"",
  557. videoUrl:data[i].result.body.data.ws_flv,
  558. }
  559. self.videoPageList.push(obj)
  560. }
  561. this.videoMaxNum = this.videoPageList.length
  562. this.videoPageNumButton({page:1,limit:4});
  563. }
  564. } else {
  565. const { data } = await startUrl(obj);
  566. if(data){
  567. self.videoPageList = [];
  568. for(let i=0;i<data.length;i++){
  569. let text = localStorage.getItem('cameraUrl');
  570. let url = data[i].result.body.data.ws_flv;
  571. url = url.split("rtp/");
  572. let newUrl = text+'rtp/'+url[1];
  573. let obj = {
  574. divId:'divId'+i,
  575. hasAudio:false,
  576. height:false,
  577. videoError:"",
  578. videoUrl:newUrl,
  579. }
  580. self.videoPageList.push(obj)
  581. }
  582. this.videoMaxNum = this.videoPageList.length
  583. this.videoPageNumButton({page:1,limit:4});
  584. }
  585. }
  586. },
  587. //视频翻页处理
  588. videoPageNumButton(val){
  589. this.loading = true;
  590. let self = this;
  591. //清除已有播放流
  592. if(self.videoNewList[0]){
  593. for(let i=0;i<self.videoNewList.length;i++){
  594. self.videoNewList[i].flvPlayer.pause();
  595. self.videoNewList[i].flvPlayer.unload();
  596. self.videoNewList[i].flvPlayer.detachMediaElement();
  597. self.videoNewList[i].flvPlayer.destroy();
  598. self.videoNewList[i].flvPlayer = null;
  599. }
  600. self.videoNewList = [];
  601. }
  602. //计算新数据
  603. let num = 0;
  604. let numMax = val.page * val.limit;
  605. if(val.page!=0){
  606. num = ( val.page - 1 ) * val.limit
  607. }
  608. if(numMax>self.videoPageList.length){
  609. numMax = self.videoPageList.length;
  610. }
  611. let list = [];
  612. for(let i=num;i<numMax;i++){
  613. list.push(self.videoPageList[i]);
  614. }
  615. this.$set(this,'videoList',list);
  616. setTimeout(function(){
  617. self.videoPlay();
  618. },500);
  619. },
  620. videoPlay(){
  621. let self = this;
  622. this.loading = false;
  623. for(let i=0;i<self.videoList.length;i++){
  624. let obj = {
  625. player :{},
  626. flvPlayer:{}
  627. };
  628. obj.player = document.getElementById(self.videoList[i].divId);
  629. obj.flvPlayer = flvjs.createPlayer(
  630. {
  631. // isLive: true, //=> 是否为直播流
  632. // hasAudio: false, //=> 是否开启声音
  633. type: 'flv', //媒体类型 flv 或 mp4
  634. url: self.videoList[i].videoUrl //视频流地址
  635. },
  636. {
  637. enableStashBuffer: true,//启用 IO 存储缓冲区。 如果您需要实时流播放(最小延迟),请设置为 false,但如果存在网络抖动,则可能会停止。
  638. stashInitialSize: 128,//IO 存储缓冲区初始大小。 默认值为 384KB。 指示合适的大小可以改善视频加载/搜索时间。
  639. isLive: true,//是否是直播
  640. lazyLoadRecoverDuration: 30,//指示以秒为单位的lazyLoad 恢复时间边界。
  641. autoCleanupSourceBuffer: true,//进行自动清理
  642. autoCleanupMaxBackwardDuration: 3 * 60,//3 * 60 当向后缓冲持续时间超过这个值(以秒为单位)时,对 SourceBuffer 进行自动清理
  643. autoCleanupMinBackwardDuration: 2 * 60,//2 * 60 指示在执行自动清理时为后向缓冲区保留的持续时间(以秒为单位)。
  644. }
  645. );
  646. self.videoNewList.push(obj);
  647. // }
  648. }
  649. for(let i=0;i<self.videoNewList.length;i++){
  650. self.videoNewList[i].flvPlayer.attachMediaElement(self.videoNewList[i].player);
  651. self.videoNewList[i].flvPlayer.load(); //加载
  652. self.videoNewList[i].flvPlayer.play(); //加载
  653. }
  654. },
  655. videoFunction(){
  656. let self = this;
  657. // self.videoList = [];
  658. for(let i=0;i<self.checkedSubject.videoData.length;i++){
  659. let obj = {
  660. player :{},
  661. flvPlayer:{}
  662. };
  663. obj.player = document.getElementById(self.checkedSubject.videoData[i].divId);
  664. // if (flvjs.isSupported()) {
  665. obj.flvPlayer = flvjs.createPlayer(
  666. {
  667. // isLive: true, //=> 是否为直播流
  668. // hasAudio: false, //=> 是否开启声音
  669. type: self.checkedSubject.videoData[i].videoType, //媒体类型 flv 或 mp4
  670. url: self.checkedSubject.videoData[i].url //视频流地址
  671. },
  672. {
  673. enableStashBuffer: true,//启用 IO 存储缓冲区。 如果您需要实时流播放(最小延迟),请设置为 false,但如果存在网络抖动,则可能会停止。
  674. stashInitialSize: 128,//IO 存储缓冲区初始大小。 默认值为 384KB。 指示合适的大小可以改善视频加载/搜索时间。
  675. isLive: true,//是否是直播
  676. lazyLoadRecoverDuration: 30,//指示以秒为单位的lazyLoad 恢复时间边界。
  677. autoCleanupSourceBuffer: true,//进行自动清理
  678. autoCleanupMaxBackwardDuration: 3 * 60,//3 * 60 当向后缓冲持续时间超过这个值(以秒为单位)时,对 SourceBuffer 进行自动清理
  679. autoCleanupMinBackwardDuration: 2 * 60,//2 * 60 指示在执行自动清理时为后向缓冲区保留的持续时间(以秒为单位)。
  680. }
  681. );
  682. self.videoList.push(obj);
  683. // }
  684. }
  685. for(let i=0;i<self.videoList.length;i++){
  686. self.videoList[i].flvPlayer.attachMediaElement(self.videoList[i].player);
  687. self.videoList[i].flvPlayer.load(); //加载
  688. self.videoList[i].flvPlayer.play(); //加载
  689. }
  690. },
  691. //取消订阅关闭MQTT连接
  692. offMQTT(){
  693. this.client.unsubscribe(this.mtopic, error => {
  694. if (error) {
  695. }
  696. })
  697. this.client.end();
  698. this.client = {};
  699. },
  700. },
  701. beforeDestroy() {
  702. //清除定时器
  703. let self = this;
  704. self.offMQTT();
  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>