Monitor.vue 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007
  1. <template>
  2. <div class="monitor-container">
  3. <div class="monitor-wrap">
  4. <div class="video-box">
  5. <div class="fbg" v-if="fScreen"></div>
  6. <div
  7. class="fbgBtn"
  8. @click="fScreenFun()"
  9. v-if="!oneFScreen && fScreen"
  10. ></div>
  11. <div
  12. :class="{ 'video-container': true, fScreen: fScreen }"
  13. ref="videoContainerRef"
  14. >
  15. <div
  16. :class="{
  17. videoItem: true,
  18. a1: divNum == 1,
  19. a2: divNum == 2,
  20. a9: divNum == 9,
  21. a12: divNum == 12,
  22. selected: count == selected,
  23. }"
  24. v-for="count in divNum"
  25. :key="String(count) + divNum"
  26. @click="selectVideo($event, count, 'my-video' + count)"
  27. >
  28. <span style="display: none" class="current">{{
  29. Idlist[count - 1]
  30. }}</span>
  31. <div class="vedio_btn_control">
  32. <div class="direc">
  33. <div
  34. @click.stop="configCamera(oneId, 'takephoto', '')"
  35. class="cameraCtr"
  36. ></div>
  37. <div
  38. @mousedown.stop="configCamera(oneId, 'move', 0)"
  39. @mouseup.stop="stopConfigCamera(oneId)"
  40. class="upCtr"
  41. ></div>
  42. <div
  43. @mousedown.stop="configCamera(oneId, 'move', 1)"
  44. @mouseup="stopConfigCamera(oneId)"
  45. class="downCtr"
  46. ></div>
  47. <div
  48. @mousedown.stop="configCamera(oneId, 'move', 2)"
  49. @mouseup="stopConfigCamera(oneId)"
  50. class="leftCtr"
  51. ></div>
  52. <div
  53. @mousedown.stop="configCamera(oneId, 'move', 3)"
  54. @mouseup="stopConfigCamera(oneId)"
  55. class="rightCtr"
  56. ></div>
  57. </div>
  58. <div class="zoom">
  59. <!-- 无论插件还是费插件都可以放大缩小 -->
  60. <span
  61. class="addCtr"
  62. @mousedown.stop="configCamera(oneId, 'move', 8)"
  63. @mouseup="stopConfigCamera(oneId)"
  64. ></span>
  65. <span
  66. class="reduceCtr"
  67. @mousedown.stop="configCamera(oneId, 'move', 9)"
  68. @mouseup="stopConfigCamera(oneId)"
  69. ></span>
  70. </div>
  71. </div>
  72. <i
  73. @click.stop="oneFullFun($event, count)"
  74. class="iconfont icon-quanping fSBtn"
  75. ></i>
  76. <div
  77. style="width: 100%; height: 100%"
  78. :id="'my-video' + count"
  79. ></div>
  80. </div>
  81. </div>
  82. <div class="split-screen">
  83. <span
  84. :class="divNum == 1 ? 'sp0 sp' : 'sp00 sp'"
  85. @click="splitView(1)"
  86. ></span>
  87. <span
  88. :class="divNum == 2 ? 'sp1 sp' : 'sp01 sp'"
  89. @click="splitView(2)"
  90. ></span>
  91. <span
  92. :class="divNum == 9 ? 'sp2 sp' : 'sp02 sp'"
  93. @click="splitView(9)"
  94. ></span>
  95. <span
  96. :class="divNum == 12 ? 'sp3 sp' : 'sp03 sp'"
  97. @click="splitView(12)"
  98. ></span>
  99. </div>
  100. </div>
  101. <div class="nav-box">
  102. <ul class="viewLists">
  103. <li
  104. v-for="(item, index) in Idlist"
  105. :key="index"
  106. :class="{ active: activeIndex == index }"
  107. @click="
  108. selectEquip(item.device_id, item.jktype, index, item.videotape)
  109. "
  110. >
  111. <span
  112. :class="['dot', item.status == 1 ? 'onLine' : 'outLine']"
  113. ></span>
  114. {{ item | formatName }}
  115. </li>
  116. </ul>
  117. <div class="splitPage" onselectstart="return false">
  118. <span
  119. class="arrow el-icon-caret-top"
  120. @click="splitPage('jian')"
  121. ></span>
  122. <span>{{ currPage }}</span>
  123. <span>/</span>
  124. <span>{{ totalPage }}</span>
  125. <span
  126. class="arrow el-icon-caret-bottom"
  127. @click="splitPage('jia')"
  128. ></span>
  129. </div>
  130. <div class="direc">
  131. <div
  132. @click="configCamera(id, 'takephoto', '')"
  133. class="cameraCtr"
  134. ></div>
  135. <div
  136. @mousedown="configCamera(id, 'move', 0)"
  137. @mouseup="stopConfigCamera(id)"
  138. class="upCtr"
  139. ></div>
  140. <div
  141. @mousedown="configCamera(id, 'move', 1)"
  142. @mouseup="stopConfigCamera(id)"
  143. class="downCtr"
  144. ></div>
  145. <div
  146. @mousedown="configCamera(id, 'move', 2)"
  147. @mouseup="stopConfigCamera(id)"
  148. class="leftCtr"
  149. ></div>
  150. <div
  151. @mousedown="configCamera(id, 'move', 3)"
  152. @mouseup="stopConfigCamera(id)"
  153. class="rightCtr"
  154. ></div>
  155. </div>
  156. <div class="btnBox">
  157. <div class="zoom">
  158. <!-- 无论插件还是费插件都可以放大缩小 -->
  159. <span
  160. class="addCtr"
  161. @mousedown="configCamera(id, 'move', 8)"
  162. @mouseup="stopConfigCamera(id)"
  163. ></span>
  164. <span
  165. class="reduceCtr"
  166. @mousedown="configCamera(id, 'move', 9)"
  167. @mouseup="stopConfigCamera(id)"
  168. ></span>
  169. </div>
  170. <div
  171. v-show="videotape == 1"
  172. class="playBack"
  173. @click="playBackDialogVisible = true"
  174. ></div>
  175. <div @click="addEquipDialogVisible = true" class="addequip"></div>
  176. <div @click="fScreenFun()" class="fSBtn1"></div>
  177. </div>
  178. </div>
  179. </div>
  180. <!-- 拍照 -->
  181. <el-dialog
  182. title="手动下载"
  183. :visible.sync="takePhotoDialogVisible"
  184. width="30%"
  185. >
  186. <el-input type="textarea" id="picUrl" v-model="picUrl"></el-input>
  187. <span slot="footer" class="dialog-footer">
  188. <el-button @click="takePhotoDialogVisible = false">取 消</el-button>
  189. <el-button type="primary" @click="copyPicUrl">复制</el-button>
  190. </span>
  191. </el-dialog>
  192. <!-- 查看回放 -->
  193. <el-dialog
  194. title="查看回放"
  195. :visible.sync="playBackDialogVisible"
  196. width="600px"
  197. @close="palyBackClose"
  198. >
  199. <el-form
  200. ref="backFormRef"
  201. :model="backForm"
  202. :rules="backFormRules"
  203. label-width="80px"
  204. >
  205. <el-form-item label="时间范围" prop="time">
  206. <el-date-picker
  207. v-model="backForm.time"
  208. type="datetimerange"
  209. range-separator="至"
  210. start-placeholder="开始日期"
  211. end-placeholder="结束日期"
  212. >
  213. </el-date-picker>
  214. </el-form-item>
  215. <el-form-item label="通道" prop="aisle">
  216. <el-select
  217. style="width: 400px"
  218. v-model="backForm.aisle"
  219. placeholder="请选择"
  220. >
  221. <el-option
  222. v-for="item in Number(jktype)"
  223. :key="item"
  224. :label="'通道' + item"
  225. :value="item"
  226. >
  227. </el-option>
  228. </el-select>
  229. </el-form-item>
  230. <el-form-item>
  231. <el-button type="default" @click="playBackDialogVisible = false"
  232. >取消</el-button
  233. >
  234. <el-button type="primary" @click="playBackSubmit">确定</el-button>
  235. </el-form-item>
  236. </el-form>
  237. <div id="videoBack">
  238. <div id="playWind"></div>
  239. </div>
  240. </el-dialog>
  241. <!-- 添加设备 -->
  242. <el-dialog
  243. title="添加设备"
  244. :visible.sync="addEquipDialogVisible"
  245. width="400px"
  246. >
  247. <el-form
  248. ref="addEquipFormRef"
  249. :model="addEquipForm"
  250. :rules="addEquipFormRules"
  251. label-width="80px"
  252. >
  253. <el-form-item label="设备id" prop="device_id">
  254. <el-input
  255. style="width: 217px"
  256. v-model="addEquipForm.device_id"
  257. ></el-input>
  258. </el-form-item>
  259. <el-form-item label="通道" prop="jk_type">
  260. <el-select v-model="addEquipForm.jk_type" placeholder="请选择">
  261. <el-option
  262. v-for="item in 32"
  263. :key="item"
  264. :label="'通道' + item"
  265. :value="item"
  266. >
  267. </el-option>
  268. </el-select>
  269. </el-form-item>
  270. </el-form>
  271. <div slot="footer" class="dialog-footer">
  272. <el-button @click="addEquipDialogVisible = false">取 消</el-button>
  273. <el-button type="primary" @click="addEquipSubm">确定</el-button>
  274. </div>
  275. </el-dialog>
  276. </div>
  277. </template>
  278. <script>
  279. export default {
  280. data() {
  281. return {
  282. currPage: 1, //当前分页
  283. totalPage: 0, //总分页
  284. id: "", //监控选中状态selected,右侧菜单控制的ID
  285. oneId: "", //单个监控全屏时的监控id
  286. activeIndex: null, //控制设备列表选中状态
  287. jktype: "", //设备的通道数
  288. videotape: "", //0是不支持回放,1支持
  289. divNum: 1, //默认分屏数量
  290. hlsHdSrc: "",
  291. rtmpHdSrc: "",
  292. player: null, //videojs的对象
  293. takePhotoDialogVisible: false, //拍照弹框
  294. Idlist: [], //右侧设备列表
  295. divMainHeight: "", //视频盒子高度
  296. selected: null, //默认选中第一台设备
  297. divName: "", //默认选中第一台设备
  298. html: "", //插件播放内容
  299. picUrl: "", //视频拍照地址
  300. playBackDialogVisible: false,
  301. addEquipDialogVisible: false,
  302. fScreen: false, //默认多个监控非全屏
  303. oneFScreen: false, //单个监控全屏状态
  304. btnFlag: true, //全屏按钮显示控制
  305. backForm: {
  306. time: "",
  307. start: "",
  308. end: "",
  309. aisle: "",
  310. },
  311. backFormRules: {
  312. time: [
  313. { required: true, message: "请选择时间范围", trigger: "change" },
  314. ],
  315. aisle: [{ required: true, message: "请选择通道", trigger: "change" }],
  316. },
  317. addEquipFormRules: {
  318. device_id: [
  319. { required: true, message: "请填写设备id", trigger: "blur" },
  320. ],
  321. jk_type: [{ required: true, message: "请选择通道", trigger: "change" }],
  322. },
  323. playback: {}, //回放
  324. videoObj: {},
  325. addEquipForm: {
  326. device_id: "",
  327. jk_type: "",
  328. equip_type: 1, //1 苗情 2 可视化
  329. },
  330. };
  331. },
  332. filters: {
  333. formatName: function (value) {
  334. //设备名字
  335. if (value.device_name) {
  336. return `${value.device_name}-${value.jktype}`;
  337. } else {
  338. return `${value.device_id}-${value.jktype}`;
  339. }
  340. },
  341. },
  342. created() {
  343. this.getJkList();
  344. },
  345. methods: {
  346. //获取视频列表
  347. getJkList() {
  348. this.$axios({
  349. method: "POST",
  350. url: "/api/list_camera",
  351. data: this.qs.stringify({ page: this.currPage, equip_type: 1 }),
  352. }).then((res) => {
  353. this.Idlist = res.data.data;
  354. this.totalPage = Math.ceil(res.data.counts / 12);
  355. this.initMonitor(); //进入页面默认1屏都显示视频
  356. });
  357. },
  358. getJkList2() {
  359. this.$axios({
  360. method: "POST",
  361. url: "/api/list_camera",
  362. data: this.qs.stringify({ page: this.currPage }),
  363. }).then((res) => {
  364. this.Idlist = res.data.data;
  365. });
  366. },
  367. //视频分页
  368. splitPage(str) {
  369. this.activeIndex = null;
  370. if (str == "jian") {
  371. if (this.currPage > 1) {
  372. this.currPage--;
  373. this.getJkList2();
  374. }
  375. } else {
  376. if (this.currPage < this.totalPage) {
  377. this.currPage++;
  378. this.getJkList2();
  379. }
  380. }
  381. },
  382. //上下左右和拍照
  383. configCamera(id, ctrl, movenum) {
  384. if (id != "") {
  385. if (ctrl == "takephoto") {
  386. this.$axios({
  387. method: "POST",
  388. url: "/api/camera_takephoto",
  389. data: this.qs.stringify({
  390. device_id: id,
  391. ctrl: ctrl,
  392. }),
  393. }).then((res) => {
  394. if (res.data.code == 200) {
  395. let data = res.data.data;
  396. this.picUrl = data.picUrl;
  397. this.takePhotoDialogVisible = true;
  398. } else {
  399. this.$message.error("设备网络异常!");
  400. }
  401. });
  402. } else {
  403. //上下左右、放大、缩小
  404. this.$axios({
  405. method: "POST",
  406. url: "/api/ctrl_camera",
  407. data: this.qs.stringify({
  408. device_id: id,
  409. ctrl: ctrl,
  410. movenum: movenum,
  411. }),
  412. }).then((res) => {
  413. if (res.data == 1) {
  414. this.$message.success("操作成功");
  415. } else {
  416. this.$message.error("操作失败");
  417. }
  418. });
  419. }
  420. } else {
  421. this.$message.error("请选中监控");
  422. }
  423. },
  424. //关闭方向
  425. stopConfigCamera(id) {
  426. if (id != "") {
  427. this.$axios({
  428. method: "POST",
  429. url: "/api/ctrl_camera",
  430. data: this.qs.stringify({
  431. device_id: id,
  432. ctrl: "stop",
  433. }),
  434. });
  435. }
  436. },
  437. //分屏默认显示视频
  438. initMonitor() {
  439. this.id = this.Idlist[0].device_id; //第一台设备id
  440. this.videotape = this.Idlist[0].videotape; //第一台是否有回放
  441. this.divName = "my-video1"; //第一台选中
  442. this.selected = 1; //第一台选中
  443. for (let item = 1; item < this.divNum + 1; item++) {
  444. if (this.Idlist[item - 1]) {
  445. console.log(item);
  446. //避免右侧监控数量少于divNum
  447. this.$axios({
  448. url: "/api/addr_camera",
  449. method: "POST",
  450. data: this.qs.stringify({
  451. device_id: this.Idlist[item - 1].device_id,
  452. jk_type: this.Idlist[item - 1].jktype,
  453. }),
  454. }).then((res) => {
  455. var data = eval("(" + res.data + ")");
  456. var hlsHdSrc = data.hlsHd;
  457. var rtmpHdSrc = data.rtmp;
  458. this.$nextTick(() => {
  459. let playHtml = `<video id="videoitem${item}"
  460. style='width: 100%;height: 100%;' src="${hlsHdSrc}" autoplay poster='' muted controls playsInline webkit-playsinline>
  461. </video>`;
  462. console.log("my-video" + item);
  463. document.getElementById("my-video" + item).innerHTML = playHtml;
  464. this.$nextTick(() => {
  465. this.videoObj["videoitem" + item] = new EZUIKit.EZUIPlayer(
  466. "videoitem" + item
  467. );
  468. });
  469. });
  470. });
  471. }
  472. }
  473. },
  474. //选中右侧菜单设备
  475. selectEquip(device_id, jktype, index, videotape) {
  476. if (this.selected !== "") {
  477. //判断是否选中左侧监控
  478. document
  479. .getElementsByClassName("selected")[0]
  480. .getElementsByClassName("current")[0].innerHTML = device_id; //更换current里的设备id值
  481. console.log(device_id);
  482. this.jktype = jktype;
  483. this.activeIndex = index; //菜单选中状态
  484. this.id = device_id; //保存选中的设备id
  485. this.videotape = videotape;
  486. console.log(this.divName);
  487. this.$axios({
  488. url: "/api/addr_camera",
  489. method: "POST",
  490. data: this.qs.stringify({ device_id: device_id, jk_type: jktype }),
  491. }).then((res) => {
  492. var data = eval("(" + res.data + ")");
  493. let hlsHdSrc = data.hlsHd;
  494. let playHtml = `<video id="n${this.divName}"
  495. style='width: 100%;height: 100%;' src="${hlsHdSrc}" autoplay poster='' muted controls playsInline webkit-playsinline>
  496. </video>`;
  497. let target = document.getElementById(this.divName);
  498. target.removeChild(target.childNodes[0]);
  499. target.innerHTML = playHtml;
  500. this.$nextTick(() => {
  501. new EZUIKit.EZUIPlayer(`n${this.divName}`);
  502. });
  503. });
  504. }
  505. },
  506. //点击分屏
  507. splitView(num) {
  508. this.divNum = num;
  509. console.log(this.videoObj);
  510. for (let item in this.videoObj) {
  511. console.log(item);
  512. this.videoObj[item].stop();
  513. }
  514. this.$nextTick(() => {
  515. this.initMonitor();
  516. });
  517. },
  518. //点击视频
  519. selectVideo(e, i, divName) {
  520. console.log("外");
  521. let current = e.currentTarget.getElementsByClassName("current")[0]
  522. .innerHTML;
  523. if (current.indexOf("device_id") == -1) {
  524. this.id = current;
  525. } else {
  526. this.id = JSON.parse(current).device_id;
  527. }
  528. console.log(this.id);
  529. this.divName = divName; //视频外面div的id
  530. this.selected = i;
  531. },
  532. //复制拍照地址
  533. copyPicUrl() {
  534. document.getElementById("picUrl").select();
  535. this.$message({
  536. showClose: true,
  537. message: "手动复制,在浏览器打开,另存为",
  538. });
  539. },
  540. fScreenFun() {
  541. this.fScreen = !this.fScreen;
  542. },
  543. oneFullFun(el, i) {
  544. this.selected = i;
  545. let par = el.currentTarget.parentNode;
  546. let current = par.getElementsByClassName("current")[0].innerHTML;
  547. if (current == "") {
  548. return false;
  549. } else if (current.indexOf("device_id") == -1) {
  550. this.oneId = current;
  551. } else {
  552. this.oneId = JSON.parse(current).device_id;
  553. }
  554. this.$nextTick(() => {
  555. par.classList.toggle("fullScreen");
  556. this.oneFScreen = !this.oneFScreen; //点击菜单栏全屏按钮后,再点击单个监控全屏时,隐藏恢复按钮
  557. });
  558. },
  559. playBackSubmit() {
  560. this.$refs.backFormRef.validate((valid) => {
  561. if (!valid) {
  562. return false;
  563. }
  564. let start = new Date(this.backForm.time[0]);
  565. let end = new Date(this.backForm.time[1]);
  566. let beginVal = "";
  567. let endVal = "";
  568. function checked(num) {
  569. if (num < 10) {
  570. num = "0" + num;
  571. }
  572. return num;
  573. }
  574. beginVal =
  575. beginVal +
  576. start.getFullYear() +
  577. checked(start.getMonth() + 1) +
  578. checked(start.getDate()) +
  579. checked(start.getHours()) +
  580. checked(start.getMinutes()) +
  581. checked(start.getSeconds());
  582. endVal =
  583. endVal +
  584. end.getFullYear() +
  585. checked(end.getMonth() + 1) +
  586. checked(end.getDate()) +
  587. checked(end.getHours()) +
  588. checked(end.getMinutes()) +
  589. checked(end.getSeconds());
  590. this.$axios({
  591. method: "POST",
  592. url: "/api/nvr_view",
  593. data: this.qs.stringify({
  594. e_id: this.id,
  595. }),
  596. }).then((res) => {
  597. if (!document.getElementById("playWind")) {
  598. document.getElementById("videoBack").innerHTML =
  599. '<div id="playWind"></div>';
  600. }
  601. let accessToken = res.data.jk_token;
  602. let url = `ezopen://open.ys7.com/${this.id}/${this.backForm.aisle}.local.rec?begin=${beginVal}&end=${endVal}`;
  603. this.playback = new EZUIKit.EZUIPlayer({
  604. id: "playWind",
  605. autoplay: true,
  606. url: url,
  607. accessToken: accessToken,
  608. decoderPath: "static/js/",
  609. width: 560,
  610. height: 460,
  611. });
  612. });
  613. });
  614. },
  615. palyBackClose() {
  616. this.$refs.backFormRef.resetFields();
  617. this.playback.stop();
  618. document.getElementById("videoBack").innerHTML = "";
  619. },
  620. addEquipSubm() {
  621. this.$refs.addEquipFormRef.validate((valid) => {
  622. if (!valid) {
  623. return false;
  624. }
  625. this.$axios({
  626. method: "POST",
  627. url: "/api/add_camera",
  628. data: this.qs.stringify(this.addEquipForm),
  629. }).then((res) => {
  630. if (res.data == 1) {
  631. this.addEquipDialogVisible = false;
  632. this.getJkList();
  633. } else {
  634. this.$message.error(res.data);
  635. }
  636. });
  637. });
  638. },
  639. },
  640. destroyed() {
  641. for (let item in this.videoObj) {
  642. this.videoObj[item].stop();
  643. console.log(this.videoObj[item]);
  644. }
  645. },
  646. };
  647. </script>
  648. <style lang='less' scoped>
  649. ul,
  650. li {
  651. list-style-type: none;
  652. margin: 0;
  653. }
  654. .monitor-container {
  655. display: flex;
  656. flex-direction: column;
  657. height: 100%;
  658. .monitor-wrap {
  659. height: 100%;
  660. display: flex;
  661. justify-content: space-between;
  662. background: #ddd;
  663. flex: 1;
  664. .video-box {
  665. flex: 1;
  666. // padding: 10px;
  667. .fScreen {
  668. position: absolute;
  669. z-index: 8;
  670. top: 0;
  671. left: 0;
  672. width: 100%;
  673. height: 100% !important;
  674. }
  675. .fbg {
  676. position: fixed;
  677. top: 0;
  678. bottom: 0;
  679. left: 0;
  680. right: 0;
  681. background: #000;
  682. z-index: 5;
  683. }
  684. .fbgBtn {
  685. position: fixed;
  686. z-index: 9;
  687. right: 20px;
  688. bottom: 20px;
  689. width: 100px;
  690. height: 100px;
  691. background: url(../assets/images/monitor/fS2.png);
  692. }
  693. .video-container {
  694. width: 100%;
  695. height: calc(100% - 45px);
  696. background: #000;
  697. display: flex;
  698. flex-wrap: wrap;
  699. .fullScreen {
  700. position: fixed !important;
  701. width: 100% !important;
  702. height: 100% !important;
  703. top: 0;
  704. right: 0;
  705. bottom: 0;
  706. left: 0;
  707. z-index: 10;
  708. background: #000;
  709. .vedio_btn_control {
  710. display: block;
  711. }
  712. }
  713. .videoItem {
  714. position: relative;
  715. border: 1px solid #000;
  716. box-sizing: border-box;
  717. .fSBtn {
  718. position: absolute;
  719. z-index: 2;
  720. top: 10px;
  721. right: 20px;
  722. color: #fff;
  723. font-size: 20px;
  724. cursor: pointer;
  725. }
  726. .fSBtn:hover {
  727. color: red;
  728. }
  729. }
  730. .videoItem:hover {
  731. border-color: aquamarine;
  732. }
  733. .selected {
  734. border: 1px solid aquamarine;
  735. }
  736. .a1 {
  737. width: 100%;
  738. height: 100%;
  739. }
  740. .a2 {
  741. width: 50%;
  742. height: 100%;
  743. }
  744. .a9 {
  745. width: 33.3%;
  746. height: 33.3%;
  747. }
  748. .a12 {
  749. width: 33.3%;
  750. height: 25%;
  751. }
  752. }
  753. .split-screen {
  754. background: #f0f0f0;
  755. display: flex;
  756. justify-content: flex-start;
  757. padding: 15px 10px;
  758. .sp {
  759. width: 17px;
  760. height: 17px;
  761. display: inline-block;
  762. margin-right: 10px;
  763. cursor: pointer;
  764. }
  765. .sp00 {
  766. background: url(../assets/images/monitor/1.png);
  767. }
  768. .sp01 {
  769. background: url(../assets/images/monitor/2.png);
  770. }
  771. .sp02 {
  772. background: url(../assets/images/monitor/9.png);
  773. }
  774. .sp03 {
  775. background: url(../assets/images/monitor/12.png);
  776. }
  777. .sp0 {
  778. background: url(../assets/images/monitor/11.png);
  779. }
  780. .sp1 {
  781. background: url(../assets/images/monitor/22.png);
  782. }
  783. .sp2 {
  784. background: url(../assets/images/monitor/99.png);
  785. }
  786. .sp3 {
  787. background: url(../assets/images/monitor/122.png);
  788. }
  789. }
  790. }
  791. .nav-box {
  792. width: 240px;
  793. background: #f0f0f0;
  794. color: #000;
  795. font-size: 14px;
  796. .viewLists {
  797. height: 50%;
  798. overflow: auto;
  799. padding: 0;
  800. li {
  801. padding-left: 25px;
  802. padding-right: 25px;
  803. line-height: 34px;
  804. cursor: pointer;
  805. .viewPhoto {
  806. color: #eba219;
  807. float: right;
  808. font-size: 12px;
  809. cursor: pointer;
  810. }
  811. .viewPhoto:hover {
  812. text-decoration: underline;
  813. }
  814. .dot {
  815. display: inline-block;
  816. width: 7px;
  817. height: 7px;
  818. border-radius: 100%;
  819. margin-right: 15px;
  820. }
  821. .onLine {
  822. background: #15bb88;
  823. }
  824. .outLine {
  825. background: #c1c1c1;
  826. }
  827. }
  828. li.active {
  829. color:#fff;
  830. background: #5aae22;
  831. }
  832. li:hover {
  833. color:#fff;
  834. background: #5aae22;
  835. }
  836. }
  837. .splitPage {
  838. height: 3%;
  839. margin-top: 2%;
  840. text-align: center;
  841. color: #15bb88;
  842. -webkit-user-select: none;
  843. -moz-user-select: none;
  844. -ms-user-select: none;
  845. .arrow {
  846. font-size: 20px;
  847. cursor: pointer;
  848. }
  849. }
  850. .direc {
  851. position: relative;
  852. z-index: 0;
  853. text-align: center;
  854. width: 160px;
  855. height: 160px;
  856. margin: 10px auto;
  857. // position: relative;
  858. background: url(../assets/images/monitor/direction-btn.png) no-repeat
  859. center;
  860. background-size: contain;
  861. & > div {
  862. position: absolute;
  863. width: 53px;
  864. height: 53px;
  865. cursor: pointer;
  866. }
  867. .upCtr {
  868. top: 0px;
  869. transform: translateX(-50%);
  870. margin-left: 50%;
  871. }
  872. .downCtr {
  873. bottom: 0px;
  874. transform: translateX(-50%);
  875. margin-left: 50%;
  876. }
  877. .leftCtr {
  878. transform: translateY(-50%);
  879. left: 0;
  880. margin-top: 50%;
  881. }
  882. .rightCtr {
  883. transform: translateY(-50%);
  884. right: 0;
  885. margin-top: 50%;
  886. }
  887. .cameraCtr {
  888. top: 0;
  889. bottom: 0;
  890. left: 0;
  891. right: 0;
  892. margin: auto;
  893. }
  894. }
  895. .btnBox {
  896. .zoom,
  897. .playBack,
  898. .playtype0,
  899. .playtype1,
  900. .addequip,
  901. .fSBtn1,
  902. .fSBtn2 {
  903. width: 140px;
  904. height: 32px;
  905. margin: auto;
  906. margin-bottom: 5px;
  907. cursor: pointer;
  908. }
  909. .zoom {
  910. background: no-repeat center / 100%
  911. url(../assets/images/monitor/zoom-btn.png);
  912. display: flex;
  913. & > span {
  914. flex: 1;
  915. height: 32px;
  916. }
  917. }
  918. .playBack {
  919. background: url(../assets/images/monitor/playback-btn.png) no-repeat
  920. center;
  921. }
  922. .playtype0 {
  923. background: url(../assets/images/monitor/playtype0.png) no-repeat
  924. center;
  925. }
  926. .playtype1 {
  927. background: url(../assets/images/monitor/playtype1.png) no-repeat
  928. center;
  929. }
  930. .addequip {
  931. background: url(../assets/images/monitor/addequip.png) no-repeat
  932. center;
  933. }
  934. .fSBtn1 {
  935. background: url(../assets/images/monitor/fS.png) no-repeat center;
  936. position: relative;
  937. }
  938. }
  939. }
  940. }
  941. .vedio_btn_control {
  942. display: none;
  943. position: absolute;
  944. right: 10px;
  945. bottom: 10px;
  946. z-index: 20;
  947. width: 140px;
  948. height: 200px;
  949. .direc {
  950. position: relative;
  951. text-align: center;
  952. width: 100px;
  953. height: 100px;
  954. margin: 10px auto;
  955. background: url(../assets/images/monitor/direction-btn.png) no-repeat
  956. center;
  957. background-size: contain;
  958. & > div {
  959. position: absolute;
  960. width: 33px;
  961. height: 33px;
  962. cursor: pointer;
  963. }
  964. .upCtr {
  965. top: 0px;
  966. transform: translateX(-50%);
  967. margin-left: 50%;
  968. }
  969. .downCtr {
  970. bottom: 0px;
  971. transform: translateX(-50%);
  972. margin-left: 50%;
  973. }
  974. .leftCtr {
  975. transform: translateY(-50%);
  976. left: 0;
  977. margin-top: 50%;
  978. }
  979. .rightCtr {
  980. transform: translateY(-50%);
  981. right: 0;
  982. margin-top: 50%;
  983. }
  984. .cameraCtr {
  985. top: 0;
  986. bottom: 0;
  987. left: 0;
  988. right: 0;
  989. margin: auto;
  990. }
  991. }
  992. .zoom {
  993. width: 140px;
  994. height: 32px;
  995. background: no-repeat center / 100%
  996. url(../assets/images/monitor/zoom-btn.png);
  997. display: flex;
  998. & > span {
  999. flex: 1;
  1000. height: 32px;
  1001. }
  1002. }
  1003. }
  1004. }
  1005. </style>