海康监控H5 实时视频监控

一、先上图

二、码农的代码吐槽下

<template>

  <div class="app-container home">

    <div class="header">

      <div>

        <div>今日在校:{{ SchoolCountdata.allInSchoolCount }}人</div>

        <div>教职工:{{ SchoolCountdata.teacherInSchoolCount }}人</div>

        <div>学生:{{ SchoolCountdata.studentInSchoolCount }}人</div>

      </div>

      <div>智慧校园</div>

      <div>

        <div v-html="yeartxt"></div>

        <div v-html="daytxt"></div>

        <!--  <div>{{$moment().format('YYYY年MM年DD HH:mm')}}</div> -->

        <div @click="goTarget">退出大屏</div>

      </div>

    </div>

    <div class="main">

      <div class="left">

        <!--   style="width:446px; padding:40px 20px 0px; overflow: hidden;" -->

        <div>

          <div style="overflow: hidden; width: 415px; margin-left: 10px">

            <vue-seamless-scroll

              class="seamless-scroll"

              :data="lastWeekRankdata"

              :class-option="classOption2"

            >

              <ul style="width: 1000px; padding-top: 30px">

                <li v-for="(v, i) in lastWeekRankdata" :key="i">

                  <div>{{ i + 1 }}</div>

                  <div v-if="i + 1 == 1">

                    <img src="@/assets/images/2@2x.png" alt="" width="45" />

                  </div>

                  <div v-if="i + 1 == 2">

                    <img src="@/assets/images/3@2x.png" alt="" width="45" />

                  </div>

                  <div v-if="i + 1 == 3">

                    <img src="@/assets/images/1@2x.png" alt="" width="45" />

                  </div>

                  <div v-if="i + 1 > 3">

                    <div></div>

                  </div>

                  <div>

                    <img

                      :src="baseUrl_src(v.image)"

                      alt=""

                      width="72"

                      height="72"

                    />

                  </div>

                  <span>{{ v.attendanceRatio }}</span>

                  <div>{{ v.teacherName }}</div>

                </li>

              </ul>

            </vue-seamless-scroll>

          </div>

        </div>

        <div>

          <!-- {{attendancedata}} === -->

          <div>

            实到人数<span> {{ attendancedata.realNumber }}</span

            >人

          </div>

          <div>

            较昨日 <img src="@/assets/images/up.png" v-if="Accounted" />

            <img src="@/assets/images/down.png" v-else />

            <span>{{ attendancedata.realRatio }} </span>

          </div>

          <div>

            <div ref="commandstats" style="height: 200px; width: 180px" />

            <ul>

              <li>

                <div></div>

                <div>正常</div>

                <div>{{ attendancedata.normalNumber }}</div>

              </li>

              <li>

                <div style="background: #fde64e"></div>

                <div style="color: #fde64e">迟到</div>

                <div>{{ attendancedata.lateNumber }}</div>

              </li>

              <li>

                <div style="background: #fd6767"></div>

                <div style="color: #fd6767">早退</div>

                <div>{{ attendancedata.leaveEarlyNumber }}</div>

              </li>

              <li>

                <div style="background: #a1e6ce"></div>

                <div style="color: #a1e6ce">不在岗</div>

                <div>{{ attendancedata.notOnDutyNumber }}</div>

              </li>

            </ul>

          </div>

        </div>

      </div>

      <div class="center">

        <div class="bannerBox">

          <div

            id="player"

            v-loading="loading"

            style="width: 100%; height: 100%"

          ></div>

          <!-- <div class="swiper-container gallery-top">

            <div class="swiper-wrapper">

              <div class="swiper-slide" v-for="(item,index) of bigImg" :key="index">

                <img class="img" :src="item">

              </div>

            </div>

          </div>

          <div class="swiper-container gallery-thumbs">

            <div class="swiper-wrapper">

              <div class="swiper-slide swiper-bottom" v-for="(item,index) of bigImg" :key="index">

                <img class="img" :src="item">

              </div>

            </div>

          </div> -->

        </div>

      </div>

      <!-- 学生当日考勤 -->

      <div class="right">

        <div class="race-lamp-card">

          <ul class="horseLamp_list" style="height: 30px">

            <li>

              <div>序号</div>

              <div>班级</div>

              <div>出勤率(%)</div>

            </li>

          </ul>

          <ul class="horseLamp_list">

            <vue-seamless-scroll

              class="seamless-scroll"

              :data="classattendancedata"

              :class-option="classOption"

            >

              <li v-for="(item, index) in classattendancedata" :key="index">

                <div>{{ index + 1 }}</div>

                <div>{{ item.organizedName }}</div>

                <div>

                  {{ item.attendanceRatio

                  }}{{ item.attendanceRatio ? "%" : "%" }}

                </div>

              </li>

              <li class="bottom_fade"></li>

            </vue-seamless-scroll>

          </ul>

        </div>

        <!-- 学生考勤排行 -->

        <div class="race-lamp-card">

          <ul class="horseLamp_list" style="height: 30px">

            <li>

              <div>班级</div>

              <div></div>

              <div>出勤率(%)</div>

            </li>

          </ul>

          <ul class="horseLamp_list">

            <vue-seamless-scroll

              class="seamless-scroll"

              :data="WeekAttendancedata"

              :class-option="classOption"

            >

              <li v-for="(item, index) in WeekAttendancedata" :key="index">

                <div>{{ item.organizedName }}</div>

                <div>

                  <el-progress

                    color="#81FF00"

                    :show-text="false"

                    :percentage="item.attendanceRatio"

                  >

                  </el-progress>

                </div>

                <div>{{ item.attendanceRatio }}%</div>

              </li>

              <li class="bottom_fade"></li>

            </vue-seamless-scroll>

          </ul>

        </div>

      </div>

    </div>

    <!-- 教师出勤率 -->

    <div class="bottom">

      <!-- {{attendanceRatiodata}} -->

      <div class="commandstatsPie">

        <div ref="commandstatsPie" style="width: 420px; height: 160px"></div>

        <div class="teacherbg">

          <div style="color: rgb(109, 86, 249)">

            <!-- <img src="@/assets/images/e38378266ec5cc32918654fa1388384.png" alt=""> -->

            {{ this.attendanceRatiodata.nowRatio }}

          </div>

          <div style="color: #00e1fe">

            {{ this.attendanceRatiodata.weekRatio }}

            <!-- <img src="@/assets/images/ae447071c20f3fcab87839017414677.png" alt=""> -->

          </div>

          <div style="color: gold">

            {{ this.attendanceRatiodata.monthRatio }}

            <!-- <img src="@/assets/images/761bf03b9b5943d164b93e5b58c5422.png" alt=""> -->

          </div>

        </div>

        <div>

          <div>当日</div>

          <div>当周</div>

          <div>当月</div>

        </div>

      </div>

      <!-- 学生作品 -->

      <div class="race-lamp-card" v-if="progresList.length > 0">

        <ul class="horseLamp_list" :class="{ horseLamp_top: animate }">

          <li>

            <div>序号</div>

            <div>作品名称</div>

            <div>作者</div>

            <div>班级</div>

          </li>

          <li v-for="(item, index) in broadcastdata" v-bind:key="index">

            <div>{{ item.areaId }}</div>

            <div>{{ item.broadcastName }}</div>

            <div>{{ item.broadcastName }}</div>

            <div>{{ item.groupName }}</div>

          </li>

          <li class="bottom_fade"></li>

        </ul>

      </div>

      <!-- 广播节目 -->

      <div class="race-lamp-card" v-if="broadcastdata.length > 0">

        <ul class="horseLamp_list reshorseLamp_list" style="height: 30px">

          <li>

            <div>序号</div>

            <div>节目播放设备</div>

            <div>时间</div>

          </li>

        </ul>

        <ul class="horseLamp_list reshorseLamp_list">

          <vue-seamless-scroll

            class="seamless-scroll"

            :data="broadcastdata"

            :class-option="broadcastscroll"

          >

            <li v-for="(item, index) in broadcastdata" v-bind:key="index">

              <div>{{ index + 1 }}</div>

              <div>{{ item.broadcastName }}</div>

              <!-- <div title="item.program">{{programsplice(item.program)}}</div> -->

              <div>{{ item.playTime }}</div>

              <!--  <div>{{item.createTime.substring(11,item.createTime.length)}}</div> -->

            </li>

            <li class="bottom_fade"></li>

          </vue-seamless-scroll>

        </ul>

      </div>

    </div>

  </div>

</template>

<script>

import {

  arearoot,

  areasubArea,

  apicameralist,

  camerapreview,

} from "@/api/HKcamera/index";

import Swiper from "swiper";

import echarts from "echarts";

import "moment/locale/zh-cn";

import { mapGetters } from "vuex";

let moment = require("moment");

const IS_MOVE_DEVICE = document.body.clientWidth < 992; // 是否移动设备

const MSE_IS_SUPPORT = !!window.MediaSource; // 是否支持mse

//公共广播

import {

  inSchoolCount,

  lastWeekRank,

  attendance,

  attendanceRatio,

  broadcast,

  lastWeekAttendance,

  classattendance,

} from "@/api/home";

import vueSeamlessScroll from "vue-seamless-scroll";

export default {

  name: "Index",

  components: {

    vueSeamlessScroll,

  },

  data() {

    return {

      yeartxt: "",

      daytxt: "",

      //在校人数

      SchoolCountdata: {

        studentInSchoolCount: null,

        teacherInSchoolCount: null,

        allInSchoolCount: null,

      },

      baseUrl: process.env.VUE_APP_BASE_API,

      //教师考勤排行

      lastWeekRankdata: [],

      //教师出勤数

      attendancedata: {

        abnormalNumber: 6,

        lateNumber: 4,

        leaveEarlyNumber: 1,

        missingCardNumber: 3,

        normalNumber: 4,

        notOnDutyNumber: 0,

        realNumber: 4,

        realRatio: "0%",

      },

      //教师出勤率

      attendanceRatiodata: {

        monthRatio: "83.95%",

        nowRatio: "90%",

        weekRatio: "90%",

      },

      //广播节目

      broadcastdata: [],

      //学生考勤排行

      WeekAttendancedata: [],

      //学生考勤

      classattendancedata: [],

      // bigImg: [

      //   "https://t7.baidu.com/it/u=3165657288,4248157545&fm=193&f=GIF",

      //   "https://t7.baidu.com/it/u=2942499027,2479446682&fm=193&f=GIF",

      //   "https://t7.baidu.com/it/u=2610975262,3538281461&fm=193&f=GIF",

      //   "https://t7.baidu.com/it/u=4138158235,3956816634&fm=193&f=GIF",

      // ],

      animate: false,

      progresList: [],

      //视频播放

      // 摄像头个数列表

      videoList: 2,

      loading: true,

      zh_CN: "",

      isMoveDevice: IS_MOVE_DEVICE,

      player: null,

      splitNum: IS_MOVE_DEVICE ? 1 : 2,

      mseSupport: MSE_IS_SUPPORT,

      tabActive: MSE_IS_SUPPORT ? "mse" : "decoder",

      labelCol: { span: 5 },

      wrapperCol: { span: 18 },

      urls: {

        realplay: "ws://172.16.7.250:559/openUrl/Isj35ug",

        talk: "ws://172.16.7.250:559/openUrl/Isj35ug",

        playback: "ws://172.16.7.250:559/openUrl/Isj35ug",

      },

      playback: {

        startTime: "2022-01-26T00:00:00",

        endTime: "2022-01-26T23:59:59",

        valueFormat: moment.HTML5_FMT.DATETIME_LOCAL_SECONDS,

        seekStart: "2022-01-26T12:00:00",

        rate: "",

      },

      muted: true,

      volume: 50,

      timerTwo: null,

      //倒计时 两分钟

      maxtime: 10,

      //视频长度轮询对比

      cameraIndexCodelength: 0,

      cameraIndexCodecir: "",

      //本地视频

      getitemindexCode: "",

      //两分钟去取视频

      videIndex: 0,

      //转成二维数组

      videUrl: [],

      //两分钟下一组视频

      videTimeUrl: [],

      //摄像头播放

      deptOptions: [],

    };

  },

  created() {

    window.setInterval(this.showTime, 1000);

    this.funinSchoolCount();

    this.funlastWeekRank();

    this.funattendance();

    this.funattendanceRatio();

    this.funlastWeekAttendance();

    this.funclassattendance();

    this.funbroadcast();

    let _this = this;

    this.$nextTick(function () {

      this.galleryThumbsLunbo();

      this.galleryTopLunbo();

    });

    setInterval(function () {

      _this.showhorseLamp();

    }, 2500);

    //轮询视频即时

    this.timerTwo = setInterval(function () {

      _this.CountDown();

    }, 1000);

  },

  mounted() {

    //获取摄像头

    this.init();

    //获取视频

    this.getTreeselect();

    this.$el.style.setProperty("display", "block");

    //暂无用处

    this.drawPieTwo();

    //!window.JSPlugin

    if (!window.JSPlugin) {

      this.loadScript("/demo/h5player.min.js").then(() => {

        this.createPlayerIns();

      });

      console.log("ABC=!window.JSPlugin");

    } else {

      console.log("!window.JSPlugin=>>>>>>>>>>>>>>>>>>>>ELSE");

    }

  },

  methods: {

    getTreeselect() {

      arearoot({}).then((e) => {

        if (e && e.code === 200) {

          if (e.data) {

            apicameralist(e.data.indexCode).then((readList) => {

              let indexCode = readList.data.map((item) => item.cameraIndexCode);

              localStorage.setItem("indexCode", JSON.stringify(indexCode));

              this.getitemindexCode = JSON.parse(

                localStorage.getItem("indexCode")

              );

              this.cameraIndexCodelength = this.getitemindexCode.length / 4;

              this.cameraIndexCodecir = this.cameraIndexCodelength + "";

              this.videUrl = this.listToMatrix(this.getitemindexCode, 4);

              //视频配置&事件回调绑定

              this.createPlayer();

              //初始化视频播放

              this.setTimecode(this.videUrl[0]);

            });

          }

        }

      });

    },

    init() {

      // 设置播放容器的宽高并监听窗口大小变化

      window.addEventListener("resize", () => {

        this.player.JS_Resize();

      });

    },

    createPlayer() {

      let szBasePath = "";

      //因为项目配置在二级域名,所以文件需改变路径

      // if (process.env.NODE_ENV == "production") {

      //   szBasePath = "/bzsv/js/";

      // } else {

      //   szBasePath = "/js/";

      // }

      console.log(`szBasePath======》》》`, szBasePath, process.env.NODE_ENV);

      this.player = new window.JSPlugin({

        szId: "player",

        szBasePath: "/demo/",

        iMaxSplit: 4,

        iCurrentSplit: IS_MOVE_DEVICE ? 1 : 2,

        //分屏播放

        openDebug: true,

        oStyle: {

          // borderSelect: IS_MOVE_DEVICE ? "#000" : "#FFCC00",

        },

      });

      // 事件回调绑定

      this.player.JS_SetWindowControlCallback({

        windowEventSelect: function (iWndIndex) {

          //插件选中窗口回调

          console.log(

            "windowSelect callbac====================>>>>: ",

            iWndIndex

          );

        },

        pluginErrorHandler: function (iWndIndex, iErrorCode, oError) {

          //插件错误回调

          console.log("pluginError callback: ", iWndIndex, iErrorCode, oError);

        },

        windowEventOver: function (iWndIndex) {

          //鼠标移过回调

          //console.log(iWndIndex);

        },

        windowEventOut: function (iWndIndex) {

          //鼠标移出回调

          //console.log(iWndIndex);

        },

        windowEventUp: function (iWndIndex) {

          //鼠标mouseup事件回调

          //console.log(iWndIndex);

        },

        windowFullCcreenChange: function (bFull) {

          //全屏切换回调

          console.log("fullScreen callback: ", bFull);

        },

        firstFrameDisplay: function (iWndIndex, iWidth, iHeight) {

          //首帧显示回调

          console.log(

            "firstFrame loaded callback: ",

            iWndIndex,

            iWidth,

            iHeight

          );

        },

        performanceLack: function () {

          //性能不足回调

          console.log("performanceLack callback: ");

        },

      });

    },

    listToMatrix(list, elementsPerSubArray) {

      var matrix = [],

        i,

        k;

      for (i = 0, k = -1; i < list.length; i++) {

        if (i % elementsPerSubArray === 0) {

          k++;

          matrix[k] = [];

        }

        matrix[k].push(list[i]);

      }

      return matrix;

    },

    //轮询倒计时两分钟

    CountDown() {

      if (this.cameraIndexCodelength <= 0) {

        //回归以前视频长度

        this.cameraIndexCodelength = parseInt(this.cameraIndexCodecir);

      } else {

        if (this.maxtime <= 0) {

          //时间

          this.maxtime = 10;

          //视频长度

          this.cameraIndexCodelength -= 1;

          //下一条视频

          this.videIndex += 1;

        } else {

          this.maxtime -= 1;

          // clearInterval(this.timerTwo);

          // alert("时间到,结束!");

        }

      }

      // console.log(this.cameraIndexCodelength, "=====================8888");

      // console.log(this.maxtime, "=============>>");

    },

    //视频播放

    setTimecode(item) {

      let { player, mode, videUrl, videTimeUrl, videIndex } = this;

      for (let i = 0; i <= 3; i++) {

        camerapreview(item[i]).then((item) => {

          console.log(item, "item 视频请求地址======");

          let url = item.data;

          player.JS_Play(

            url,

            {

              playURL: url,

              mode: mode,

            },

            i

            //回放参数

            // startTime,

            // endTime

          );

        });

      }

    },

    arrangeWindow() {

      let splitNum = this.splitNum;

      this.player.JS_ArrangeWindow(splitNum).then(

        () => {

          console.log(`arrangeWindow to ${splitNum}x${splitNum} success`);

        },

        (e) => {

          console.error(e);

        }

      );

    },

    wholeFullScreen() {

      this.player.JS_FullScreenDisplay(true).then(

        () => {

          console.log(`wholeFullScreen success`);

        },

        (e) => {

          console.error(e);

        }

      );

    },

    /* 预览&对讲 */

    realplay() {

      let { player, mode, urls } = this,

        index = player.currentWindowIndex,

        playURL = urls.realplay;

      // player.currentWindowIndex += 1;

      player.JS_Play(playURL, { playURL, mode }, index).then(

        () => {

          console.log("realplay success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    stopPlay() {

      this.player.JS_Stop().then(

        () => {

          this.playback.rate = 0;

          console.log("stop realplay success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    talkStart() {

      let url = this.urls.talk;

      this.player.JS_StartTalk(url).then(

        () => {

          console.log("talkStart success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    talkStop() {

      this.player.JS_StopTalk().then(

        () => {

          console.log("talkStop success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    stopAllPlay() {

      this.player.JS_StopRealPlayAll().then(

        () => {

          this.playback.rate = 0;

          console.log("stopAllPlay success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    /* 回放 */

    playbackStart() {

      let { player, mode, urls, playback } = this,

        index = player.currentWindowIndex,

        playURL = urls.playback,

        { startTime, endTime } = playback;

      startTime += "Z";

      endTime += "Z";

      player

        .JS_Play(playURL, { playURL, mode }, index, startTime, endTime)

        .then(

          () => {

            console.log("playbackStart success");

            this.playback.rate = 1;

          },

          (e) => {

            console.error(e);

          }

        );

    },

    playbackPause() {

      this.player.JS_Pause().then(

        () => {

          console.log("playbackPause success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    playbackResume() {

      this.player.JS_Resume().then(

        () => {

          console.log("playbackResume success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    seekTo() {

      let { seekStart, endTime } = this.playback;

      seekStart += "Z";

      endTime += "Z";

      this.player

        .JS_Seek(this.player.currentWindowIndex, seekStart, endTime)

        .then(

          () => {

            console.log("seekTo success");

          },

          (e) => {

            console.error(e);

          }

        );

    },

    playbackSlow() {

      this.player.JS_Slow().then(

        (rate) => {

          this.playback.rate = rate;

        },

        (e) => {

          console.error(e);

        }

      );

    },

    playbackFast() {

      this.player.JS_Fast().then(

        (rate) => {

          this.playback.rate = rate;

        },

        (e) => {

          console.error(e);

        }

      );

    },

    frameForward() {

      this.player.JS_FrameForward(this.player.currentWindowIndex).then(

        () => {

          this.playback.rate = 1;

          console.log("frameForward success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    /* 声音、抓图、录像 */

    openSound() {

      this.player.JS_OpenSound().then(

        () => {

          console.log("openSound success");

          this.muted = false;

        },

        (e) => {

          console.error(e);

        }

      );

    },

    closeSound() {

      this.player.JS_CloseSound().then(

        () => {

          console.log("closeSound success");

          this.muted = true;

        },

        (e) => {

          console.error(e);

        }

      );

    },

    setVolume(value) {

      let player = this.player,

        index = player.currentWindowIndex;

      this.player.JS_SetVolume(index, value).then(

        () => {

          console.log("setVolume success", value);

        },

        (e) => {

          console.error(e);

        }

      );

    },

    capture(imageType) {

      let player = this.player,

        index = player.currentWindowIndex;

      player.JS_CapturePicture(index, "img", imageType).then(

        () => {

          console.log("capture success", imageType);

        },

        (e) => {

          console.error(e);

        }

      );

    },

    recordStart(type) {

      const codeMap = { MP4: 5, PS: 2 };

      let player = this.player,

        index = player.currentWindowIndex,

        fileName = `${moment().format("YYYYMMDDHHmm")}.mp4`;

      typeCode = codeMap[type];

      player.JS_StartSaveEx(index, fileName, typeCode).then(

        () => {

          console.log("record start ...");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    recordStop() {

      let player = this.player;

      index = player.currentWindowIndex;

      player.JS_StopSave(index).then(

        () => {

          console.log("record stoped, saving ...");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    /* 电子放大、智能信息 */

    enlarge() {

      let player = this.player,

        index = player.currentWindowIndex;

      player.JS_EnableZoom(index).then(

        () => {

          console.log("enlarge start..., select range...");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    enlargeClose() {

      let player = this.player,

        index = player.currentWindowIndex;

      player.JS_DisableZoom(index).then(

        () => {

          console.log("enlargeClose success");

        },

        (e) => {

          console.error(e);

        }

      );

    },

    intellectTrigger(openFlag) {

      let player = this.player,

        index = player.currentWindowIndex;

      let result = player.JS_RenderALLPrivateData(index, openFlag);

      console.log(

        `${openFlag ? "open" : "close"} intellect ${

          result === 1 ? "success" : "failed"

        }`

      );

    },

    getvideoInfo() {

      let player = this.player,

        index = player.currentWindowIndex;

      player.JS_GetVideoInfo(index).then(function (videoInfo) {

        console.log("videoInfo:", videoInfo);

      });

    },

    getOSDTime() {

      let player = this.player,

        index = player.currentWindowIndex;

      player.JS_GetOSDTime(index).then(function (time) {

        console.log("osdTime:", new Date(time));

      });

    },

    //摄像头 end

    //学生考勤

    funclassattendance() {

      classattendance()

        .then((e) => {

          if (e.code == 200) {

            if (e.data.length > 0) {

              this.classattendancedata = e.data;

            }

          }

        })

        .catch((err) => {

          console.log(err, `学生考勤`);

        });

    },

    //上周班级考勤率

    funlastWeekAttendance() {

      lastWeekAttendance()

        .then((e) => {

          // console.log(`上周班级考勤率`, e);

          if (e.code == 200) {

            if (e.data.length > 0) {

              this.WeekAttendancedata = e.data;

            }

          }

        })

        .catch((Error) => {

          // console.log(Error, "上周班级考勤率");

        });

    },

    // moment库实现的倒计时

    showTime() {

      var time = this.$moment(new Date(), "YYYY-MM-DD HH:mm:ss").add(1, "s"),

        o;

      o = time.add(1, "s").format("yyyy年MM月DD日-dddd HH:mm:ss").split("-");

      this.yeartxt = o[0];

      this.daytxt = o[1];

    },

    //广播节目

    funbroadcast() {

      broadcast({})

        .then((e) => {

          if (e.code == 200) {

            if (e.data.length > 0) {

              this.broadcastdata = e.data;

              this.progresList = e.data;

              //console.log("广播节目", e.data);

            }

          }

        })

        .catch((err) => {

          //  console.log("广播节目", err);

        });

    },

    //教师出勤率

    funattendanceRatio() {

      attendanceRatio()

        .then((e) => {

          if (e.code == 200) {

            //console.log("教师出勤率", e.data);

            this.attendanceRatiodata = e.data;

          }

        })

        .catch((err) => {

          //console.log("教师出勤数", err);

        });

    },

    //教师当日出勤数

    funattendance() {

      attendance()

        .then((e) => {

          if (e.code == 200) {

            this.attendancedata = e.data;

            //教师数据图表

            this.drawPie();

            // console.log("教师出勤数", this.attendancedata);

          }

        })

        .catch((err) => {

          //console.log("教师出勤数", err);

        });

    },

    //上周教师考勤排行

    funlastWeekRank() {

      lastWeekRank()

        .then((e) => {

          if (e.code == 200) {

            if (e.data.length > 0) {

              this.lastWeekRankdata = e.data;

              // console.log(this.lastWeekRankdata.length, "长度是多少==========>>>")

            }

          }

        })

        .catch((err) => {

          //  console.log('上周教师考勤排行', err);

        });

    },

    //在校人数

    funinSchoolCount() {

      inSchoolCount()

        .then((e) => {

          if (e.code == 200) {

            let {

              allInSchoolCount,

              studentInSchoolCount,

              teacherInSchoolCount,

            } = {

              ...e.data,

            };

            //console.log('//在校人数', e);

            this.SchoolCountdata.allInSchoolCount = allInSchoolCount;

            this.SchoolCountdata.studentInSchoolCount = studentInSchoolCount;

            this.SchoolCountdata.teacherInSchoolCount = teacherInSchoolCount;

          }

        })

        .catch((err) => {

          //console.log(err, "=========>>")

        });

    },

    goTarget() {

      // alert(11);

      this.$router.push({

        // path:'/control/control'

        path: "/student/student",

      });

      // window.open(val, '_blank');

    },

    //滚屏方法取消

    showhorseLamp() {

      // this.animate = true;

      // setTimeout(() => {

      //  this.horseLampList.push(this.horseLampList[0]);

      //  this.horseLampList.shift();

      //  this.progresList.push(this.progresList[0]);

      //  this.progresList.shift();

      //  this.animate = false;

      // }, 300);

    },

    galleryTopLunbo() {

      this.galleryTop = new Swiper(".gallery-top", {

        spaceBetween: 0,

        loop: true,

        loopedSlides: 4,

        // 左右按钮

        navigation: {

          nextEl: ".swiper-button-next",

          prevEl: ".swiper-button-prev",

        },

        thumbs: {

          //thumbs组件专门用于制作带缩略图的swiper

          swiper: this.galleryThumbs,

          slideThumbActiveClass: "swiper-slide-thumb-active",

        },

        // autoplay: {

        //     "delay": 2500,

        //     "disableOnInteraction": false

        // }

      });

    },

    galleryThumbsLunbo() {

      this.galleryThumbs = new Swiper(".gallery-thumbs", {

        spaceBetween: 15, //在slide之间设置距离(单位px)

        slidesPerView: 3, //设置slider容器能够同时显示的slides数量

        loop: true, //设置为true 则开启loop模式

        freeMode: true, //默认为false,普通模式:slide滑动时只滑动一格

        loopedSlides: 3, //一般设置大于可视slide个数2个即可

        watchSlidesVisibility: true, //开启watchSlidesVisibility选项前需要先开启watchSlidesProgress

        watchSlidesProgress: true, //开启这个参数来计算每个slide的progress(进度、进程)

        autoplay: {

          delay: 2500,

          disableOnInteraction: false,

        },

      });

    },

    drawPie() {

      // 基于准备好的dom,初始化echarts实例,所以只能在mounted中调用

      let myChart = echarts.init(this.$refs.commandstats);

      // console.log(this.attendancedata, "==========");

      // 绘制图表

      myChart.setOption({

        color: ["#81FF00", "#FDE64E", "#FD6767", "#A1E6CE"],

        series: [

          {

            type: "pie",

            radius: [30, 60],

            center: ["37%", "42%"],

            roseType: "radius",

            label: {

              show: false,

            },

            emphasis: {

              label: {

                show: false,

              },

            },

            data: [

              {

                value: this.attendancedata.normalNumber,

              },

              {

                value: this.attendancedata.lateNumber,

              },

              {

                value: this.attendancedata.leaveEarlyNumber,

              },

              {

                value: this.attendancedata.notOnDutyNumber,

              },

            ],

          },

        ],

      });

    },

    //取消此方法

    drawPieTwo() {

      // 基于准备好的dom,初始化echarts实例,所以只能在mounted中调用

      let myChart = echarts.init(this.$refs.commandstatsPie);

    },

    event() {

      const self = this;

      return {};

    },

    network() {

      const self = this;

      return {};

    },

  },

  computed: {

    mode: function () {

      return this.tabActive === "mse" ? 0 : 1;

    },

    ...mapGetters(["avatar"]),

    Accounted() {

      let len = this.attendancedata.realRatio.length;

      let tex = Number(this.attendancedata.realRatio.substring(0, len - 1));

      if (tex > 1) {

        return true;

      } else {

        return false;

      }

    },

    classOption() {

      return {

        step: 0.1, // 数值越大速度滚动越快

        limitMoveNum: this.classattendancedata.length, // 开始无缝滚动的数据量 this.poleAlarmList.length

        hoverStop: true, // 是否开启鼠标悬停stop

        direction: 1, // 0向下 1向上 2向左 3向右

        openWatch: true, // 开启数据实时监控刷新dom

        singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1

        singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3

        waitTime: 100, // 单步运动停止的时间(默认值1000ms)

      };

    },

    classOption2() {

      return {

        step: 0.8, // 数值越大速度滚动越快

        limitMoveNum: 10, // 开始无缝滚动的数据量 this.poleAlarmList.length

        hoverStop: true, // 是否开启鼠标悬停stop

        direction: 2, // 0向下 1向上 2向左 3向右

        openWatch: true, // 开启数据实时监控刷新dom

        singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1

        singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3

        waitTime: 100, // 单步运动停止的时间(默认值1000ms)

      };

    },

    //广播节目

    broadcastscroll() {

      return {

        step: 0.2, // 数值越大速度滚动越快

        limitMoveNum: this.broadcastdata.length, // 开始无缝滚动的数据量 this.poleAlarmList.length

        hoverStop: true, // 是否开启鼠标悬停stop

        direction: 1, // 0向下 1向上 2向左 3向右

        openWatch: true, // 开启数据实时监控刷新dom

        singleHeight: 0, // 单步运动停止的高度(默认值0是无缝不停止的滚动) direction => 0/1

        singleWidth: 0, // 单步运动停止的宽度(默认值0是无缝不停止的滚动) direction => 2/3

        waitTime: 100, // 单步运动停止的时间(默认值1000ms)

      };

    },

    programsplice() {

      return (val) => {

        let T;

        // if (val) {

        //  if (val.length > 5) {

        //    T = val.substr(0, 6) + "..."

        //  }

        // }

        return T;

      };

    },

    //图片路径拼接

    baseUrl_src() {

      return function (item) {

        let url = this.avatar;

        var quote = item;

        var part = "";

        if (quote != null || quote) {

          part = quote.slice(1, quote.length);

          // part = quote.slice(0, quote.length);

        }

        // console.log(this.baseUrl, part, "图片路径===========>>>");

        if (item) {

          url = this.baseUrl + part;

        }

        // console.log(url, "========cccc");

        return url;

      };

    },

  },

  watch: {

    videIndex: {

      handler(n, v) {

        this.videTimeUrl = this.videUrl[n];

        this.setTimecode(this.videTimeUrl);

        console.log(this.videTimeUrl, n, "=============nnnn>>");

      },

      deep: true,

      immediate: true,

    },

  },

};

</script>

<style scoped lang="scss">

.teacherbg {

  background: url(../assets/images/teacherbg.png) no-repeat;

  width: 372px;

  height: 148px;

}

.home {

  background-image: url("../assets/images/20211221094951.png");

  padding: 0;

  width: 1910px;

  height: 1080px;

  .header {

    display: flex;

    align-items: center;

    height: 128px;

    padding: 0 39px;

    > div {

      display: flex;

      align-items: center;

      font-size: 25px;

      font-family: PingFangSC-Regular, PingFang SC;

      font-weight: 400;

      color: #6cdbde;

      > div {

        margin-right: 36px;

      }

      &:nth-child(2) {

        font-size: 48px;

        font-family: AlibabaPuHuiTiM;

        color: #42e2d0;

        line-height: 65px;

        letter-spacing: 1px;

        width: 594px;

        justify-content: center;

      }

      &:last-child {

        flex: 1;

        justify-content: flex-end;

        > div:last-child {

          margin: 0;

          font-family: PingFangSC-Medium, PingFang SC;

          font-weight: 500;

          color: #42e2d0;

          cursor: pointer;

        }

      }

    }

  }

  .main {

    padding: 20px 97px 0;

    display: flex;

    align-content: center;

    .left {

      > div {

        &:first-child,

        &:last-child {

          background: url("../assets/images/33@2x.png") no-repeat;

          // width: 444px;

          height: 277px;

          overflow: hidden;

          margin: 0 35px 23px 0;

        }

        &:first-child {

          ul {

            // width: 390px;

            // height: 247px;

            height: 251px;

            overflow: hidden;

            li {

              text-align: center;

              margin-right: 10px;

              display: inline-block;

              float: left;

              width: 88px;

              font-size: 28px;

              font-family: PingFangSC-Regular, PingFang SC;

              font-weight: 400;

              color: #fde64e;

              span {

                font-size: 16px;

                display: block;

              }

              &:last-child {

                margin: 0;

              }

              &:nth-child(2) {

                color: #259cfe;

              }

              &:nth-child(3) {

                color: #ffa55c;

              }

              &:nth-child(4) {

                color: #6cdbde;

              }

              > div {

                &:nth-child(2) {

                  height: 42px;

                  position: relative;

                  z-index: 100;

                }

                &:nth-child(3) {

                  width: 72px;

                  height: 72px;

                  border-radius: 100%;

                  overflow: hidden;

                  position: relative;

                  top: -12px;

                  left: 10px;

                }

                &:last-child {

                  font-size: 16px;

                  font-family: PingFangSC-Regular, PingFang SC;

                  font-weight: 400;

                  color: #6cdbde;

                  height: 45px;

                  overflow: hidden;

                }

              }

            }

          }

        }

        &:last-child {

          background-image: url("../assets/images/37@2x.png");

          background-size: cover;

          width: 444px;

          height: 277px;

          padding: 51px 39px 49px;

          font-size: 18px;

          font-family: PingFangSC-Regular, PingFang SC;

          font-weight: 400;

          color: #6cdbde;

          > div {

            &:nth-child(2) {

              font-size: 14px;

              margin-top: 5px;

            }

            &:last-child {

              display: flex;

              ul {

                li {

                  display: flex;

                  align-items: center;

                  > div {

                    font-size: 12px;

                    font-family: PingFangSC-Regular, PingFang SC;

                    font-weight: 400;

                    color: #81ff00;

                    margin-bottom: 13px;

                    &:first-child {

                      width: 44px;

                      height: 6px;

                      background: #81ff00;

                      border-radius: 3px;

                    }

                    &:nth-child(2) {

                      margin-left: 20px;

                      width: 60px;

                    }

                    &:nth-child(3) {

                      color: #ffffff;

                    }

                  }

                }

              }

            }

          }

        }

      }

    }

    .center {

      width: 766px;

      height: 578px;

      background: url("../assets/images/9de015532a42acddb5fe567913aed9d.png")

        no-repeat;

      background-size: contain;

      .bannerBox {

        width: 716px;

        height: 480px;

        margin: 74px auto;

        overflow: hidden;

        border-radius: 2px;

        border: 2px solid rgba(62, 208, 198, 0.4);

        .img {

          width: 100%;

          height: 100%;

        }

        .gallery-top {

          width: 100%;

          height: 311px;

          border-bottom: 2px solid rgba(62, 208, 198, 0.4);

        }

        .gallery-thumbs {

          width: 100%;

          height: 165px;

          .swiper-slide {

            width: 33.3333% !important;

            margin-right: 0 !important;

            border: 2px solid rgba(62, 208, 198, 0.4);

          }

        }

      }

    }

    .right {

      > div {

        &:first-child,

        &:last-child {

          background: url("../assets/images/41@2x.png") no-repeat;

          background-size: cover;

          width: 444px;

          height: 277px;

          margin: 0 0 23px 35px;

        }

        &:first-child {

          padding: 52px 56px 0;

        }

        &:last-child {

          background: url("../assets/images/6@2x.png") no-repeat;

          background-size: cover;

          width: 444px;

          height: 277px;

          padding: 52px 10px 0;

          li {

            > div {

              flex: 1;

            }

          }

        }

      }

    }

  }

  .horseLamp_list {

    height: 175px;

    overflow: hidden;

    mask-image: linear-gradient(

      #121212 calc(100% - 45px),

      transparent calc(100% - 0px)

    );

    li {

      margin-bottom: 12px;

      display: flex;

      align-content: center;

      font-size: 18px;

      font-family: PingFangSC-Regular, PingFang SC;

      font-weight: 400;

      color: #6cdbde;

      &:first-child {

        // font-size: 16px;

        font-family: PingFangSC-Regular, PingFang SC;

        // color: #fbfbfb;

      }

      > div {

        width: 80px;

        text-align: center;

        .el-progress {

          margin-top: 9px;

        }

        &:nth-child(2) {

          width: 140px;

          flex: 1;

        }

        &:nth-child(3) {

          width: 120px;

        }

      }

    }

  }

  ul.reshorseLamp_list {

    li {

      div {

        // overflow: hidden;

        height: 24px;

      }

      div:first-child {

        width: 40px !important;

      }

      div:nth-child(2) {

        width: 120px;

        overflow: hidden;

      }

      div:nth-child(3) {

        width: 180px;

        font-size: 15px;

        overflow: hidden;

      }

      // div:nth-child(4) {

      //  width: 150px;

      //  overflow: hidden;

      //  // font-size: 12px;

      // }

    }

  }

  .bottom {

    padding: 0 97px 0;

    display: flex;

    align-content: center;

    > div {

      background: url("../assets/images/8@2x.png") no-repeat;

      background-size: cover;

      width: 444px;

      height: 277px;

      &:first-child {

        padding: 60px 10px 0;

        position: relative;

        > div {

          &:nth-child(2) {

            position: absolute;

            top: 70px;

            left: 29px;

            display: flex;

            width: 420px;

            > div {

              width: 30%;

              font-size: 18px;

              height: 130px;

              font-weight: 600;

              line-height: 150px;

              color: #fff;

              text-align: center;

            }

          }

          &:last-child {

            position: absolute;

            bottom: 40px;

            display: flex;

            width: 420px;

            > div {

              width: 29%;

              margin-left: 10px;

              text-align: center;

              font-size: 16px;

              font-family: PingFangSC-Medium, PingFang SC;

              font-weight: 500;

              color: #00e1fe;

            }

          }

        }

      }

      &:nth-child(2) {

        background: url("../assets/images/7ba22f92fca396ba3b4885002d8df65.png")

          no-repeat;

        background-size: contain;

        width: 766px;

        height: 278px;

        margin: 0 35px;

        padding: 70px 40px 0;

        font-size: 16px;

        li {

          > div:nth-child(3) {

            width: 200px;

          }

        }

      }

      &:nth-child(3) {

        background: url("../assets/images/16@2x.png") no-repeat;

        background-size: cover;

        padding: 52px 19px 0 14px;

      }

    }

  }

  h4 {

    margin-top: 0px;

  }

  h2 {

    margin-top: 10px;

    font-size: 26px;

    font-weight: 100;

  }

  p {

    margin-top: 10px;

    b {

      font-weight: 700;

    }

  }

  ul {

    list-style-type: none;

    padding: 0;

    margin: 0;

  }

}

</style>

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
要在Unity中播放海康监控视频流,您需要使用海康威视SDK中的播放器组件。以下是一些步骤,供您参考: 1. 下载并安装海康威视SDK。您可以从海康威视官网下载SDK。 2. 在Unity中创建一个新的场景,并创建一个空的游戏对象。 3. 在空的游戏对象上添加一个新的脚本组件,并将其命名为“HikVideoPlayer”。 4. 在“HikVideoPlayer”脚本中,添加以下代码: ```c# using UnityEngine; using System.Collections; using System.Runtime.InteropServices; [RequireComponent(typeof(Renderer))] public class HikVideoPlayer : MonoBehaviour { [DllImport("PlayCtrl")] private static extern bool PlayM4_GetPort(ref int nPort); [DllImport("PlayCtrl")] private static extern bool PlayM4_OpenStream(int nPort, byte[] pFileHeadBuf, int nSize, int nBufPoolSize); [DllImport("PlayCtrl")] private static extern bool PlayM4_Play(int nPort, IntPtr hWnd); [DllImport("PlayCtrl")] private static extern bool PlayM4_Stop(int nPort); [DllImport("PlayCtrl")] private static extern bool PlayM4_CloseStream(int nPort); public string ip = "192.168.1.100"; // 海康监控设备的IP地址 public int port = 8000; // 海康监控设备的端口号 public string username = "admin"; // 海康监控设备的用户名 public string password = "123456"; // 海康监控设备的密码 public int channel = 1; // 海康监控设备的通道号(默认为1) public int streamType = 1; // 海康监控设备的码流类型(主码流为0,子码流为1) public int bufSize = 1024 * 512; // 缓冲区大小 public bool playOnStart = true; // 是否在开始时自动播放视频 private int portNumber = -1; void Start() { if (playOnStart) { Play(); } } public void Play() { if (portNumber == -1) { portNumber = GetPort(); } if (portNumber != -1) { if (OpenStream()) { Play(portNumber); } } } public void Stop() { if (portNumber != -1) { Stop(portNumber); CloseStream(portNumber); portNumber = -1; } } private int GetPort() { int port = -1; PlayM4_GetPort(ref port); return port; } private bool OpenStream() { bool result = false; string url = string.Format("rtsp://{0}:{1}@{2}:{3}/cam/realmonitor?channel={4}&subtype={5}", username, password, ip, port, channel, streamType); byte[] urlBytes = System.Text.Encoding.UTF8.GetBytes(url); result = PlayM4_OpenStream(portNumber, urlBytes, urlBytes.Length, bufSize); return result; } private bool Play(int port) { bool result = false; result = PlayM4_Play(port, IntPtr.Zero); return result; } private bool Stop(int port) { bool result = false; result = PlayM4_Stop(port); return result; } private bool CloseStream(int port) { bool result = false; result = PlayM4_CloseStream(port); return result; } } ``` 5. 在Unity中的场景中,将您想要播放视频的游戏对象上添加一个新的材质,并将材质的Shader设置为“Unlit/Texture”。 6. 将材质的Texture属性设置为“HikVideoPlayer”游戏对象的Renderer组件的Texture属性。 7. 您现在可以在Unity中播放海康监控视频流了。在需要播放视频的地方,只需调用“HikVideoPlayer”脚本的“Play”方法即可。 请注意,上述代码仅是一个示例,并且可能需要根据您的具体需求进行修改。此外,在使用海康威视SDK时,请确保您已经获得了必要的许可证和授权。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三顾科技

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值