Monitor.vue 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006
  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:2,//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: "list_camera",
  351. data: this.qs.stringify({ page: this.currPage,equip_type:2 }),
  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: "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: "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: "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: "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: "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: "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: "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: "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: #000;
  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. display: flex;
  755. justify-content: flex-start;
  756. padding: 15px 0;
  757. .sp {
  758. width: 17px;
  759. height: 17px;
  760. display: inline-block;
  761. margin-right: 10px;
  762. cursor: pointer;
  763. }
  764. .sp00 {
  765. background: url(../assets/images/monitor/1.png);
  766. }
  767. .sp01 {
  768. background: url(../assets/images/monitor/2.png);
  769. }
  770. .sp02 {
  771. background: url(../assets/images/monitor/9.png);
  772. }
  773. .sp03 {
  774. background: url(../assets/images/monitor/12.png);
  775. }
  776. .sp0 {
  777. background: url(../assets/images/monitor/11.png);
  778. }
  779. .sp1 {
  780. background: url(../assets/images/monitor/22.png);
  781. }
  782. .sp2 {
  783. background: url(../assets/images/monitor/99.png);
  784. }
  785. .sp3 {
  786. background: url(../assets/images/monitor/122.png);
  787. }
  788. }
  789. }
  790. .nav-box {
  791. width: 240px;
  792. background: #474e60;
  793. color: #fff;
  794. font-size: 14px;
  795. .viewLists {
  796. height: 50%;
  797. overflow: auto;
  798. padding: 0;
  799. li {
  800. padding-left: 25px;
  801. padding-right: 25px;
  802. line-height: 34px;
  803. cursor: pointer;
  804. .viewPhoto {
  805. color: #eba219;
  806. float: right;
  807. font-size: 12px;
  808. cursor: pointer;
  809. }
  810. .viewPhoto:hover {
  811. text-decoration: underline;
  812. }
  813. .dot {
  814. display: inline-block;
  815. width: 7px;
  816. height: 7px;
  817. border-radius: 100%;
  818. margin-right: 15px;
  819. }
  820. .onLine {
  821. background: #15bb88;
  822. }
  823. .outLine {
  824. background: #c1c1c1;
  825. }
  826. }
  827. li.active {
  828. background: #37414d;
  829. color: yellow;
  830. }
  831. li:hover {
  832. background: #37414d;
  833. }
  834. }
  835. .splitPage {
  836. height: 3%;
  837. margin-top: 2%;
  838. text-align: center;
  839. color: #15bb88;
  840. -webkit-user-select: none;
  841. -moz-user-select: none;
  842. -ms-user-select: none;
  843. .arrow {
  844. font-size: 20px;
  845. cursor: pointer;
  846. }
  847. }
  848. .direc {
  849. position: relative;
  850. z-index: 0;
  851. text-align: center;
  852. width: 160px;
  853. height: 160px;
  854. margin: 10px auto;
  855. // position: relative;
  856. background: url(../assets/images/monitor/direction-btn.png)
  857. no-repeat center;
  858. background-size: contain;
  859. & > div {
  860. position: absolute;
  861. width: 53px;
  862. height: 53px;
  863. cursor: pointer;
  864. }
  865. .upCtr {
  866. top: 0px;
  867. transform: translateX(-50%);
  868. margin-left: 50%;
  869. }
  870. .downCtr {
  871. bottom: 0px;
  872. transform: translateX(-50%);
  873. margin-left: 50%;
  874. }
  875. .leftCtr {
  876. transform: translateY(-50%);
  877. left: 0;
  878. margin-top: 50%;
  879. }
  880. .rightCtr {
  881. transform: translateY(-50%);
  882. right: 0;
  883. margin-top: 50%;
  884. }
  885. .cameraCtr {
  886. top: 0;
  887. bottom: 0;
  888. left: 0;
  889. right: 0;
  890. margin: auto;
  891. }
  892. }
  893. .btnBox {
  894. .zoom,
  895. .playBack,
  896. .playtype0,
  897. .playtype1,
  898. .addequip,
  899. .fSBtn1,
  900. .fSBtn2 {
  901. width: 140px;
  902. height: 32px;
  903. margin: auto;
  904. margin-bottom: 5px;
  905. cursor: pointer;
  906. }
  907. .zoom {
  908. background: no-repeat center / 100%
  909. url(../assets/images/monitor/zoom-btn.png);
  910. display: flex;
  911. & > span {
  912. flex: 1;
  913. height: 32px;
  914. }
  915. }
  916. .playBack {
  917. background: url(../assets/images/monitor/playback-btn.png)
  918. no-repeat center;
  919. }
  920. .playtype0 {
  921. background: url(../assets/images/monitor/playtype0.png)
  922. no-repeat center;
  923. }
  924. .playtype1 {
  925. background: url(../assets/images/monitor/playtype1.png)
  926. no-repeat center;
  927. }
  928. .addequip {
  929. background: url(../assets/images/monitor/addequip.png) no-repeat
  930. center;
  931. }
  932. .fSBtn1 {
  933. background: url(../assets/images/monitor/fS.png) no-repeat
  934. center;
  935. position: relative;
  936. }
  937. }
  938. }
  939. }
  940. .vedio_btn_control {
  941. display: none;
  942. position: absolute;
  943. right: 10px;
  944. bottom: 10px;
  945. z-index: 20;
  946. width: 140px;
  947. height: 200px;
  948. .direc {
  949. position: relative;
  950. text-align: center;
  951. width: 100px;
  952. height: 100px;
  953. margin: 10px auto;
  954. background: url(../assets/images/monitor/direction-btn.png)
  955. no-repeat center;
  956. background-size: contain;
  957. & > div {
  958. position: absolute;
  959. width: 33px;
  960. height: 33px;
  961. cursor: pointer;
  962. }
  963. .upCtr {
  964. top: 0px;
  965. transform: translateX(-50%);
  966. margin-left: 50%;
  967. }
  968. .downCtr {
  969. bottom: 0px;
  970. transform: translateX(-50%);
  971. margin-left: 50%;
  972. }
  973. .leftCtr {
  974. transform: translateY(-50%);
  975. left: 0;
  976. margin-top: 50%;
  977. }
  978. .rightCtr {
  979. transform: translateY(-50%);
  980. right: 0;
  981. margin-top: 50%;
  982. }
  983. .cameraCtr {
  984. top: 0;
  985. bottom: 0;
  986. left: 0;
  987. right: 0;
  988. margin: auto;
  989. }
  990. }
  991. .zoom {
  992. width: 140px;
  993. height: 32px;
  994. background: no-repeat center / 100%
  995. url(../assets/images/monitor/zoom-btn.png);
  996. display: flex;
  997. & > span {
  998. flex: 1;
  999. height: 32px;
  1000. }
  1001. }
  1002. }
  1003. }
  1004. </style>