海康摄像头 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 的环境下,是会报错的。

相关推荐
崔庆才丨静觅6 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了7 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅7 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment8 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅8 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊8 小时前
jwt介绍
前端
爱敲代码的小鱼8 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax