EasyNVR二次开发云台控制接口实例

1.背景需求

  • 通过EasyNVR接口,二次开发集成在自己的原有的web业务系统上云台控制及实时直播功能,demo效果入下。

在这里插入图片描述

  • demo是通过vue-cli脚手架搭建起来,简单说一下,目录结构
    在这里插入图片描述
  • 对easy-player不了解的这是播放器插件地址可以参看 https://www.npmjs.com/package/easy-player
  • 这里主要讲解一下App.vue内容文件
<template>
  <div id="app">
    <!-- 测试鉴权 如果鉴权已关闭请忽略 -->
    <div class="div-btn">
      <el-button-group>
        <el-button size="mini" type="success" @click="login">测试登录</el-button>
        <el-button size="mini" type="success" @click="loginout">测试退出</el-button>
        <el-button size="mini" type="success" @click="testapi">测试鉴权</el-button>
      </el-button-group>
    </div>
    <el-row>
      <!-- 播放窗口组件 -->
      <el-col :span="12">
        <EasyPlayer :videoUrl="videoUrl" fluent autoplay live stretch></EasyPlayer>
        <el-input v-model="input" placeholder="请输入播放地址接口" size="mini"></el-input>
        <p>列如:http://127.0.0.1:10800/api/v1/getchannelstream?channel=1&protocol=RTMP</p>
        <el-button class="player-button" size="mini" type="success" @click="player">播放</el-button>
      </el-col>
      <!-- 云台控制组件 -->
      <el-col :span="12">
          <div class="control-box">
            <!-- 云台控制按钮列表 -->
            <span @click="testControl('zoomin')"><i class="el-icon-circle-plus-outline"></i></span>
            <span @click="testControl('up')"><i class="el-icon-arrow-up"></i></span>
            <span @click="testControl('zoomout')"><i class="el-icon-remove-outline"></i></span>
            <span @click="testControl('left')"><i class="el-icon-arrow-left"></i></span>
            <span @click="testControl('stop')">停止</span>
            <span @click="testControl('right')"><i class="el-icon-arrow-right"></i></span>
            <span></span>
            <span @click="testControl('down')"><i class="el-icon-arrow-down"></i></span>
            <span></span>
          </div>
      </el-col>
    </el-row>
  </div>
</template>

<script>
  import md5 from "md5"; //引入md加密密码传给服务端,这里默认是admin *修改在103行*
  import EasyPlayer from "easy-player"
  export default {
    data() {
      return {
        videoUrl:'',                // 这里定义一个变量用来保存视频流地址
        input:'',                   // 接收用户的接口地址
        timer: 0,                   // 定时器用来保活接口
        channels: '',               // 保存接口地址通道地址
        protocols: ''               // 保存接口地址视频类型
      }
    },
    components:{
      EasyPlayer
    },
    mounted() {},
    methods: {
      player() { // 当输入完接口地址按下播放会执行这个函数
        if(!this.input){
          this.$message.error('请输入接口地址!');
        }else{
          let strs = this.input.split('?')[1].split('&')
          for (const iterator of strs) {
            if (iterator.indexOf('channel') != -1) this.channels = parseInt(iterator.split('=')[1])
            if (iterator.indexOf('protocol') != -1) this.protocols = iterator.split('=')[1]
          }
          this.play() //当player函数接收到可用的地址执行play函数
        }
      },
      play() { //play函数会向服务端发送请求对应的通道及视频类型
        this.$axios.get('/api/v1/getchannelstream', {
            params: {
              channel: this.channels,
              protocol: this.protocols
            }
          })
          
          .then((response) => { //请求成功服务端会返回对应的通道的视频流地址把返回的地址传给之前定义videoUrl 就可以播放视频但是视频播放一会就会停止,需要保活接口下面创建一个定时器(注意:保活只是在按需的情况下使用)
            this.videoUrl = response.data.EasyDarwin.Body.URL
            this.timer = setInterval(() => { //当请求成功定时器打开每30秒向服端端发送一下请求告诉服务端客户端需要播放视频,不然服务端就会停止向设备端拉取视频。
              this.touchStream();
            }, 30 * 1000);
            if(!response.data.EasyDarwin.Body.URL)this.$message.error('播放失败,检查接口是否正确或者通道是否启用!');
          })
          .catch((error) => {
            let { status } = error.response
            if (status == 401) Message.error('token值无效,请重新登录')
          });
      },
      touchStream() { //touchStream用来调取保活接口
        this.$axios.get('/api/v1/touchchannelstream', {
            params: {
              channel: this.channels,
              protocol: this.protocols
            }
          })
          .then((response) => {
            this.videoUrl = response.data.EasyDarwin.Body.URL
            if(!response.data.EasyDarwin.Body.URL)this.$message.error('播放失败!');
          })
          .catch((error) => {
            let { status } = error.response
            if (status == 401) Message.error('token值无效,请重新登录')
          });
      },
      login() { //测试登录
        this.$axios.get('/api/v1/login', {
            params: {
              username: "admin",
              password: md5("admin")
            }
          })
          .then((response) => {
            this.$message({
              message: '恭喜你,登录成功!',
              type: 'success'
            });
          })
          .catch((error) => {
            this.$message.error('用户名或密码错误,登录失败!');
          });
      },
      loginout() { //测试推出
        this.$axios.get('/api/v1/logout')
          .then((response) => {
            this.$message({
              message: '成功退出!',
              type: 'success'
            });
          })
          .catch((error) => {
            console.log(error)
          });
      },
      
      testapi() {   //测试接口鉴权是否生效
        this.$axios.get('/api/v1/getchannelsconfig', {
            params: {
              start: 0,
              limit: 1
            }
          })
          .then((response) => {
            this.$message({
              message: '鉴权成功!',
              type: 'success'
            });
          })
          .catch((error) => {
            this.$message.error('鉴权失败!');
          });
      },
      testControl(data) {  // testControl里的data是接收云台控制组件的里按钮传递的参数。
        this.$axios.get('/api/v1/ptzcontrol', {// 调取云台接口地址
            params: {
              channel: this.channelNum,     // 调取对应的设备通道地址
              command: data                 // 调取云台接口的控制参数
            }
          })
          .then((response) => {
            console.log(response)
          })
          .catch((error) => {
            console.log(error)
          });
      }
    }
  }
</script>

<style lang="scss">
  #app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    // text-align: center;
    color: #2c3e50;
  }
  .el-row, .div-btn{
    max-width: 800px;
    margin: auto;
  }
  .div-btn {
    padding: 5px 0;
  }
  .el-col {
    min-height: 300px;
    // border: 1px pink solid
  }
  .el-input {
    padding: 5px;
    box-sizing: border-box;
  }
  .player-button {
    margin: 5px;
    width: 100%;
  }
  .control-box {
    width: 180px;
    height: 180px;
    margin: 50px;
    span {
      display: inline-block;
      text-align: center;
      float: left;
      width: 60px;
      height: 60px;
      padding: 5px;
      border-radius: 50%;
      box-sizing: border-box;
      // border: 1px solid #ccc;
      line-height: 50px;
      cursor: pointer;
      &:hover {
        background-color: #67C23A;
         border: none;
      }
    }
  }
  p {
    font-size: 12px;
  }
</style>

案例github地址:[https://github.com/EasyNVR/EasyNVR/tree/master/EasyNVR_apidemo/apidemo]


关于EasyNVR

EasyNVR能够通过简单的网络摄像机通道配置,将传统监控行业里面的高清网络摄像机IP Camera、NVR等具有RTSP协议输出的设备接入到EasyNVR,EasyNVR能够将这些视频源的音视频数据进行拉取,转换为RTMP/HLS,进行全平台终端H5直播(Web、Android、iOS),并且EasyNVR能够将视频源的直播数据对接到第三方CDN网络,实现互联网级别的直播分发;

详细说明:http://www.easynvr.com

点击链接加入群【EasyNVR解决方案】:857627429

Copyright © EasyDarwin Team 2012-2019

EasyNVR公众号

posted on 2019-04-27 09:34  EasyNVR  阅读(836)  评论(0编辑  收藏  举报