海康摄像头 web 对接

真的烦躁,一个月拿着死工资,每天写着增删改查,不知道以后能做什么,有时候真的想离职,进广东电子厂....

这段时间,XXXX 要加一个海康监控,哎。

苦命开发

从官网下载下来的web包

\webs\codebase 目录中有,第一个是插件,必须安装的, 后面两个JS文件是开发必要的。还要一个 JQ的,它内部使用了jq

初始化插件

引入了提供的jS后,就可以开始牛马了。。。。

首先注册插件,并检查更新

因为我这是4个摄像头,所以窗口是 2 * 2

WebVideoCtrl.I_InitPlugin 是用于初始化插件,成功回调是cbInitPluginComplete

WebVideoCtrl.I_CheckPluginVersion 用于检查更新。

在自动登录这里,我准备了数组,包含登录端口密码等信息,建议每一个之后都要等1秒。多个账号登录,插件只加载一次即可。

js 复制代码
init() {
    // 这里的代码会在文档完全加载后执行
    WebVideoCtrl.I_InitPlugin({
        iWndowType: 2,    // 设置分屏类型为 2*2,显示 4 个窗口
        bWndFull: true,    // 支持单窗口双击全屏
        bDebugMode: true, // 关闭调试模式
        cbInitPluginComplete: async () => {
            console.log("插件初始化完成")
            try {
                // 加载插件
                await WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin")
                // 检查插件是否最新
                const bFlag = await WebVideoCtrl.I_CheckPluginVersion()
                if (bFlag) {
                    alert("检测到新的插件版本,双击开发包目录里的HCWebSDKPlugin.exe升级!")
                }

                for (const item of this.channel) {
                    // 自动登陆
                    this.clickLogin(item)
                    await new Promise(resolve => setTimeout(resolve, 1000))
                }
            } catch {
                alert("插件初始化失败,请确认是否已安装插件;如果未安装,请双击开发包目录里的HCWebSDKPlugin.exe安装!")
            }
        },
        iTopHeight: 0 // 插件窗口的最高高度
    })
}

实现登录

WebVideoCtrl.I_Login 是登录接口

  • 参数1:ip地址
  • 参数2:1 是http,2 是https
  • 参数3:端口
  • 参数4:平台账户
  • 参数5:平台密码
js 复制代码
// 登陆
clickLogin(item) {
    WebVideoCtrl.I_Login(item.ip, 1, item.port, 'admin', 'admin123', {
        timeout: 3000,
        success: () => {
            console.log('登陆成功')
            setTimeout(() => {
                setTimeout(() => {
                    this.getChannelInfo(item)
                }, 1000)
            }, 10)
        },
        error: (oError) => {
            if (this.ERROR_CODE_LOGIN_REPEATLOGIN === oError.errorCode) {
                console.log('已登录过!')
            } else {
                console.log(" 登录失败!", oError.errorCode, oError.errorMsg)

            }
        }
    })
}

获取通道信息

getChannelInfo 函数需要传递一个当前控制摄像头的信息对象。

模拟通道接口:WebVideoCtrl.I_GetAnalogChannelInfo

这里会使用 jq的一些方法,会对获取的xml元素进行遍历,并将获取的信息,加入到数组集合中,进行预览视频。

  • id:获取的通道号是预览的必要字段。
  • 数字通道:支持高清甚至超高清分辨率,如 1080P、2K、4K 等,但是对网络要求较高
  • 零通道:无法播放,坏掉了。
  • 模拟通道:成本小,实时性高。
js 复制代码
// 初始化通道
getChannelInfo(item) {
    // 模拟通道
    WebVideoCtrl.I_GetAnalogChannelInfo(item.ip, {
        success: (xmlDoc) => {
            const oChannels = $(xmlDoc).find('VideoInputChannel')
            $.each(oChannels, (i, channelObj) => {
                let id = $(channelObj).find('id').eq(0).text(),
                    name = $(channelObj).find('name').eq(0).text()
                if ("" === name) {
                    name = "Camera " + (i < 9 ? "0" + (i + 1) : (i + 1))
                }
                const ch = this.channel.find(arr => arr.ip === item.ip)
                ch.channelId = id
                ch.name = name
            })
            console.log(item.ip + '获取模拟通道成功!')

        },
        error: function (oError) {
            console.log(ip + '获取模拟通道失败!', oError.errorCode, oError.errorMsg)

        }
    })
    // 数字通道
    WebVideoCtrl.I_GetDigitalChannelInfo(item.ip, {
        success: function () {
            // console.log(item.ip + '获取数字通道成功!')
        },
        error: function (oError) {
            // console.log(item.ip + '获取数字通道失败!', oError.errorCode, oError.errorMsg)
        }
    })
    // 零通道
    WebVideoCtrl.I_GetZeroChannelInfo(item.ip, {
        success: function () {
            // console.log(item.ip + '获取零通道成功!')
        },
        error: function (oError) {
            // console.log(item.ip + '获取零通道失败!', oError.errorCode, oError.errorMsg)
        }
    })
    // 直接预览
    this.clickStartRealPlay(item)
}

预览窗口

clickStartRealPlay 函数需要传递一个当前控制摄像头的信息对象。

WebVideoCtrl.I_GetWindowStatus 可以获取窗口的状态,比如传递 0 ,可以查看 第一个窗口的状态。返回值如果不是null,表示在播放了。

WebVideoCtrl.I_Stop 用于关闭当前播放的窗口,参数 iWndIndex 用于控制关闭的那个窗口,默认会根据当前选中的窗口。

WebVideoCtrl.I_StartRealPlay 预览视频

  • 参数一:ip地址 + 下划线 + 端口,拼接的字符串,比如:'192.168.1.101_80'
  • 参数二:是码流,1 主码流,2 子码流
  • 参数三:是前面通过通道获取的通道ID
  • 参数四:默认是false,表示是否播放零通道
  • 参数五:RTSP端口号
js 复制代码
// 预览窗口
clickStartRealPlay(item) {
    const ips = item.ip + '_' + item.port
    // 获取窗口的状态
    const oWndInfo = WebVideoCtrl.I_GetWindowStatus(item.g_iWndIndex)
    const iRtspPort = ''
    const iChannelID = item.channelId
    const bZeroChannel = item.zeroType
    const szInfo = ''

    const startRealPlay = function () {
        WebVideoCtrl.I_StartRealPlay(ips, {
            iWndIndex: item.g_iWndIndex,
            iStreamType: 1,
            iChannelID: iChannelID,
            bZeroChannel: bZeroChannel,
            iPort: iRtspPort,
            success: function () {
                console.log(ips + '开始预览成功!')
            },
            error: function (oError) {
                console.log(ips + " 开始预览失败!", oError.errorCode, oError.errorMsg)
            }
        })
    }

    if (oWndInfo != null) { // 已经在播放了,先停止
        WebVideoCtrl.I_Stop({
            success: function () {
                startRealPlay()
            }
        })
    } else {
        startRealPlay()
    }
}

摄像头功能控制

接口:WebVideoCtrl.I_PTZControl

  • 参数一:操作类型(1-上,2-下,3-左,4-右,5-左上,6-左下,7-右上,8-右下,9-自转,10-调焦+, 11-调焦-, 12-F聚焦+, 13-聚焦-, 14-光圈+, 15-光圈-
  • 参数二:true 停止,false 启动
  • 参数三:对象:iWndIndex 窗口号,默认为当前选中窗口,iPTZSpeed 云台速度,默认为4
html 复制代码
<div class="jiu" :style="{display: isOpen ? 'flex': 'none'}">
    <div class="remote-control">
        <el-tooltip content="向左上转动" placement="top-start" effect="light">
            <div class="button top-left" @mousedown="mouseDownPTZControl(5, false)"
                @mouseup="mouseDownPTZControl(1, true)"></div>
        </el-tooltip>
        <el-tooltip content="向上转动" placement="top-start" effect="light">
            <div class="button" @mousedown="mouseDownPTZControl(1, false)"
                @mouseup="mouseDownPTZControl(1, true)">
                <i class="iconfont icon-shangjiantou1"></i>
            </div>
        </el-tooltip>
        <el-tooltip content="向右上转动" placement="top-start" effect="light">
            <div class="button top-right" @mousedown="mouseDownPTZControl(7, false)"
                @mouseup="mouseDownPTZControl(1, true)"></div>
        </el-tooltip>
        <el-tooltip content="向左转动" effect="light">
            <div class="button" @mousedown="mouseDownPTZControl(3, false)"
                @mouseup="mouseDownPTZControl(1, true)">
                <i class="iconfont icon-zuojiantou"></i>
            </div>
        </el-tooltip>
        <el-tooltip content="开启自动旋转" effect="light">
            <div class="button center" @click="mouseDownPTZControl(9, false)">
                <i class="iconfont icon-zidongxuanzhuan"></i>
            </div>
        </el-tooltip>
        <el-tooltip content="向右转动" effect="light">
            <div class="button" @mousedown="mouseDownPTZControl(4, false)"
                @mouseup="mouseDownPTZControl(1, true)">
                <i class="iconfont icon-youjiantou"></i>
            </div>
        </el-tooltip>
        <el-tooltip content="向左下转动" effect="light">
            <div class="button bottom-left" @mousedown="mouseDownPTZControl(6, false)"
                @mouseup="mouseDownPTZControl(1, true)"></div>
        </el-tooltip>
        <el-tooltip content="向下转动" effect="light">
            <div class="button" @mousedown="mouseDownPTZControl(2, false)"
                @mouseup="mouseDownPTZControl(1, true)">
                <i class="iconfont icon-xiajiantou1"></i>
            </div>
        </el-tooltip>
        <el-tooltip content="向右下转动" effect="light">
            <div class="button bottom-right" @mousedown="mouseDownPTZControl(8, false)"
                @mouseup="mouseDownPTZControl(1, true)"></div>
        </el-tooltip>
    </div>
</div>
<!-- 下方操作按钮 -->
<div class="div-group" :style="{display: isOpen ? 'block': 'none'}">
    <div style="display: flex; justify-content:space-around;">
        <el-button-group>
            <el-tooltip content="焦距变大" placement="top" effect="light">
                <div class="btn-groups" @mousedown="mouseDownPTZControl(10, false)" @mouseup="mouseDownPTZControl(11, true)">
                    <i class="iconfont icon-fangdajing-jia"></i>
                </div>
            </el-tooltip>
            <el-tooltip content="焦距变小" placement="top" effect="light">
                <div class="btn-groups" @mousedown="mouseDownPTZControl(11, false)" @mouseup="mouseDownPTZControl(11, true)">
                    <i class="iconfont icon-fangdajing-jian"></i>
                </div>
            </el-tooltip>
        </el-button-group>
        <el-button-group>
            <el-tooltip content="焦点前调" placement="top" effect="light">
                <div class="btn-groups" @mousedown="mouseDownPTZControl(12, false)" @mouseup="mouseDownPTZControl(12, true)">
                    <i class="iconfont icon-jiaodianqiantiao"></i>
                </div>
            </el-tooltip>
            <el-tooltip content="焦点后调" placement="top" effect="light">
                <div class="btn-groups" @mousedown="mouseDownPTZControl(13, false)" @mouseup="mouseDownPTZControl(12, true)">
                    <i class="iconfont icon-jiaodianhoutiao"></i>
                </div>
            </el-tooltip>
        </el-button-group>
        <!-- <el-button-group>
            <el-tooltip content="光圈扩大" placement="top" effect="light">
                <el-button>
                    <i class="iconfont icon-guangquankuoda"></i>
                </el-button>
            </el-tooltip>
            <el-tooltip content="光圈缩小" placement="top" effect="light">
                <el-button>
                    <i class="iconfont icon-guangquansuoxiao"></i>
                </el-button>
            </el-tooltip> -->
        </el-button-group>
    </div>
</div>
js 复制代码
mouseDownPTZControl(iPTZIndex, selection) {
    // 获取窗口状态
    const oWndInfo = WebVideoCtrl.I_GetWindowStatus(this.item.g_iWndIndex)
    if (oWndInfo == null) {
        return
    }

    // 如果是零通道,直接返回
    if (this.item.zeroType) {
        return
    }
    let iPTZSpeed = selection ? 0 : 4
    // 表示开启了自动
    if (9 === iPTZIndex && this.g_bPTZAuto) {
        // 将速度置为 0
        iPTZSpeed = 0

    } else {
        this.g_bPTZAuto = false
    }

    // 控制云平台
    WebVideoCtrl.I_PTZControl(iPTZIndex, selection, {
        iWndIndex: this.item.g_iWndIndex, iPTZSpeed,
        success: (xmlDoc) => {
            if (9 == iPTZIndex) {
                this.g_bPTZAuto = !this.g_bPTZAuto
            }
        },
        error: function (oError) {
            console.log(oWndInfo.szDeviceIdentify + " 开启云台失败!", oError.errorCode, oError.errorMsg)
        }
    })

}

到此就结束了,海康这个还不错,就是没有vue webpack的包,在webpack 的环境下,是会报错的。

相关推荐
陌上花开࿈2 分钟前
用户登录认证
java·开发语言·前端
兆。32 分钟前
JS进阶-面向对象-搭建网站-HTML与JS交互
javascript·爬虫·python·html·交互
噢,我明白了32 分钟前
虚拟DOM和实际的DOM有何不同?
前端·javascript·虚拟dom
放逐者-保持本心,方可放逐1 小时前
vue.config.js 简介 及 实例
前端·javascript·vue.js
落日弥漫的橘_1 小时前
js 数组方法总结
前端·javascript
余生H2 小时前
前端的Python入门指南(完):错误和异常处理策略及最佳实践
开发语言·前端·javascript·python
你的牧游哥2 小时前
Mac上使用ln指令创建软链接、硬链接
开发语言·前端·javascript
&活在当下&2 小时前
Element plus 下拉框组件选中一个选项后显示的是 value 而不是 label
前端·javascript·vue3·element plus
zzy_juheng2 小时前
弹出框(Dialog)简易使用指南
前端