注意问题

高版本监控与低版本监控

高版本监控可以在高版本浏览器上使用websocket进行解析播放,低版本监控只能在低版本浏览器上使用插件播放。
针对不同的设备选择不同的集成方案即可。可以在我的资源中下载。

集成方式
  1. 根据demo,输入ip地址、端口、用户名、密码就可以进行预览测试,测试没问题可以根据demo进行集成。
  2. 将对应的demo目录下的资源放到我们项目的静态资源中,以vue为例,在vue.config.js中进行配置,导出对应的全局变量变量,也可以直接引入使用。

以vue为例

  1. 谷歌版本chrome41版本,因为摄像头是低版本,不支持websocket。
  2. 复制demo\codebase下的文件到vue静态资源目录下,并且针对不同的浏览器位数安装不同的WebComponentsKit.exe文件。
    在这里插入图片描述
  3. 配置vue.config.js文件
const JS_CDN = isDevelopment
  ? [
    './static/video/jquery-1.7.1.min.js',
    './static/video/jsPlugin-1.0.0.min.js',
    './static/video/webVideoCtrl.js',
  ]
  : [
    './static/video/jquery-1.7.1.min.js',
    './static/video/jsPlugin-1.0.0.min.js',
    './static/video/webVideoCtrl.js',
  ];
  // 修改默认webpack配置
  configureWebpack: config => {
    // 暴露全局变量(CND方式引入的js)
    config.externals = {
      WebVideoCtrl: 'WebVideoCtrl',
      jquery: 'jQuery',
      jsPlugin: 'jsPlugin'
    }
  },

单个视频监控组件封装

代码
<template>
    <div class="video_wrapper_box" :id="pluginId">
    </div>
</template>

<script>
import WebVideoCtrl from 'WebVideoCtrl';
import { Modal } from 'view-design';
import $ from 'jquery'; // 使用JQ操作XML,获取信息
export default {
    props: {
        loginIp: {
            type: String,
            // default: '192.168.90.xx',
            default: 'xx.95.38.52'
        },
        port: {
            type: String,
            // default: '80',
            default: '17006'
        },
        username: {
            type: String,
            default: 'admin'
        },
        password: {
            type: String,
            default: 'xxx'
        },
        iChannelIDIndex: { // 通道编号的索引,用来获取通道
            type: Number,
            default: 1
        },
    },
    data () {
        return {
            pluginId: 'video_' + this.generateUUID(), // 标识渲染的dom
            channelsList: [], // 通道列表
            currChannels: {},
            iDevicePort: '',
            iRtspPort: '',
            szDeviceIdentify: '', // ip_端口
            iWndowType: 1, // 窗口分割的数量 2*2
            g_iWndIndex: 0, // 窗口
        }
    },
    methods: {
        // 初始化
        initVideoCtrl () {
            // 检查插件是否已经安装过
            var iRet = WebVideoCtrl.I_CheckPluginInstall();
            console.log(iRet, '检测是否安装了WebComponentsKit.exe插件');
            if (iRet === -1) {
                alert("您还未安装过插件,双击开发包目录里的WebComponentsKit.exe安装!");
                return false;
            }

            // 初始化插件参数及插入插件
            WebVideoCtrl.I_InitPlugin('100%', '100%', {
                bWndFull: true,     // 是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
                iPackageType: 2,    // 2:PS 11:MP4
                iWndowType: this.iWndowType,
                bNoPlugin: true,
                cbSelWnd: (xmlDoc) => { // 选择窗口
                    this.g_iWndIndex = parseInt($(xmlDoc).find('SelectWnd').eq(0).text(), 10);
                    console.log('窗口ID-当前选择的窗口编号:', this.g_iWndIndex);
                },
                cbInitPluginComplete: () => {
                    WebVideoCtrl.I_InsertOBJECTPlugin(this.pluginId); // 嵌入插件

                    console.log('嵌入插件');

                    this.$nextTick(() => {
                        //先调用窗口分割方法
                        this.changeWndNum(this.iWndowType);
                        //调用登录方法
                        this.clickLogin();
                    })

                    // 检查插件是否最新
                    if (WebVideoCtrl.I_CheckPluginVersion() === -1) {
                        alert("检测到新的插件版本,双击开发包目录里的WebComponentsKit.exe升级!");
                        return false;
                    }
                }
            });
        },

        // 窗口分割
        changeWndNum (iType) {
            iType = parseInt(iType, 10);
            WebVideoCtrl.I_ChangeWndNum(iType);
        },

        // 登录
        clickLogin () {
            if (this.loginIp === '' || this.port === '') {
                return;
            }
            this.szDeviceIdentify = this.loginIp + '_' + this.port;
            console.log('登录所需参数', this.loginIp, 1, this.port, this.username, this.password);

            const iRet = WebVideoCtrl.I_Login(this.loginIp, 1, this.port, this.username, this.password, {
                success: (xmlDoc) => {
                    console.log(" 登录成功!", xmlDoc);
                    setTimeout(() => {
                        // 获取通道信息
                        this.getChannelInfo();
                        // 获取端口
                        this.getDevicePort();
                    }, 10);

                    // 异步请求,当通道和端口都获取到的时候,开始预览

                    setTimeout(() => {
                        this.clickStartRealPlay();
                    }, 1000)
                },
                error: (status, xmlDoc) => {
                    console.log(" 登录失败!", status, xmlDoc);
                }
            });

            if (iRet === -1) {
                console.log(this.szDeviceIdentify + " 已登录过!");
                // 登录过直接进行预览
                this.clickStartRealPlay();
            }
        },
        // 获取通道信息
        getChannelInfo () {
            this.channelsList = [];

            if (this.szDeviceIdentify === '') {
                return false;
            }

            // 数字通道
            WebVideoCtrl.I_GetDigitalChannelInfo(this.szDeviceIdentify, {
                async: false,
                success: (xmlDoc) => {
                    var oChannels = $(xmlDoc).find("InputProxyChannelStatus");
                    const that = this;
                    $.each(oChannels, function (i) {
                        const id = $(this).find("id").eq(0).text();
                        let name = $(this).find("name").eq(0).text();
                        const online = $(this).find("online").eq(0).text();
                        if (online === "false") { // 过滤禁用的数字通道
                            return true;
                        }
                        if (name === "") {
                            name = "IPCamera " + (i < 9 ? "0" + (i + 1) : (i + 1));
                        }
                        that.channelsList.push({id, name, bZero: false});
                    });
                    console.log(this.szDeviceIdentify + " 获取数字通道成功!");
                    return true;
                },
                error: (status, xmlDoc) => {
                    console.log(this.szDeviceIdentify + " 获取数字通道失败!", status, xmlDoc);
                    return false;
                }
            });
        },
        // 获取端口
        getDevicePort () {
            if (this.szDeviceIdentify === '') {
                return false;
            }
            const oPort = WebVideoCtrl.I_GetDevicePort(this.szDeviceIdentify);
            if (oPort != null) {
                this.iDevicePort = oPort.iDevicePort; // 设备 SDK 端口号,不传的话,插件会自动向设备获取
                this.iRtspPort = oPort.iRtspPort;
                console.log(JSON.stringify(oPort) + " 获取端口成功!");
                return true;
            } else {
                console.log(JSON.stringify(oPort) + " 获取端口失败!");
                return false;
            }
        },
        // 开始预览
        clickStartRealPlay () {
            console.log('开始预览');

            if (!this.channelsList.length) {
                console.log('通道信息获取异常!')
                return false;
            }
            if (!this.iRtspPort) {
                console.log('RTSP端口获取异常!')
                return false;
            }

            const oWndInfo = WebVideoCtrl.I_GetWindowStatus(this.g_iWndIndex);

            const startRealPlay = () => {
                console.log('预览参数iRtspPort:' + this.iRtspPort);
                console.log('预览参数-通道列表:' + JSON.stringify(this.channelsList));
                console.log('预览参数-通道号iChannelID:' + this.channelsList[0].id);

                WebVideoCtrl.I_StartRealPlay(this.szDeviceIdentify, {
                    iRtspPort: this.iRtspPort,
                    iStreamType: 2, // 码流类型  1:主码流 2:子码流 3:第三码流 4:转码码流
                    iChannelID: this.iChannelIDIndex, // 通道 ID 播放通道号,默认通道 1
                    bZeroChannel: false, // 是否播放零通道,默认为 false
                    iWndIndex: this.g_iWndIndex,
                    success: () => {
                        console.log('开始预览成功');
                    },
                    error: (status, xmlDoc) => {
                        if (status === 403) {
                            console.log('设备不支持Websocket取流!');
                        } else {
                            console.log('开始预览失败!');
                        }
                        console.log('预览失败', status + " " + xmlDoc);
                    }
                });
            };
            console.log('窗口信息:' + this.g_iWndIndex + '号' + JSON.stringify(oWndInfo));

            if (oWndInfo !== null) { // 已经在播放了,先停止
                console.log('已经在播放了,先停止!');
                console.log('停止窗口编号:' + this.g_iWndIndex);
                WebVideoCtrl.I_Stop({
                    iWndIndex: this.g_iWndIndex,
                    success: () => {
                        console.log('停止成功,开始播放!');
                        startRealPlay();
                    },
                    error: () => {
                        console.log('停止播放异常!');
                    }
                });
            } else {
                console.log('开始播放!');
                startRealPlay();
            }
        },
        // 退出登录
        clickLogout () {
            // 退出登录
            let szInfo = "";

            var iRet = WebVideoCtrl.I_Logout(this.szDeviceIdentify);
            if (iRet === 0) {
                szInfo = "退出成功!";
                this.getChannelInfo();
                this.getDevicePort();
            } else {
                szInfo = "退出失败!";
            }
            console.log(this.loginIp + '_' + this.port + " " + szInfo);
        },
        // 生成uuid
        generateUUID () {
            let d = new Date().getTime();
            let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
            let r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
            });
            return uuid;
        }
    },
    mounted() {
        setTimeout(() => {
            this.initVideoCtrl();
        }, 200);
    },
    beforeDestroy () {
        this.clickLogout();
    },
}
</script>

<style lang="less" scoped>
    .video_wrapper_box {
        width: 100%;
        height: 100%;

        /deep/ .parent-wnd {
            > div {
            background: none !important;
            }
        }
        /deep/ canvas {
            border: none !important;
        }
    }
</style>
效果

在这里插入图片描述

多个视频监控组件封装

代码
<!--
 * @Author: xxx
 * @Date: 2021-01-12 16:31:38
 * @Description: 基于chrome42版本使用webVideoCtrl集成海康威视监控
-->
<template>
    <div class="video_wrapper_box" :id="pluginId">
    </div>
</template>

<script>
import WebVideoCtrl from 'WebVideoCtrl';
import { Modal } from 'view-design';
import $ from 'jquery'; // 使用JQ操作XML,获取信息
export default {
    props: {
        loginIp: {
            type: String,
            default: '192.168.90.xxx'
        },
        port: {
            type: String,
            default: '80'
        },
        username: {
            type: String,
            default: 'admin'
        },
        password: {
            type: String,
            default: 'a123xxxxxxxxxxxx'
        },
    },
    data () {
        return {
            pluginId: 'video_' + this.generateUUID(), // 标识渲染的dom
            g_iWndIndex: 0, // 窗口ID
            channelsList: [], // 通道列表
            currChannels: {},
            iDevicePort: '',
            iRtspPort: '',
            szDeviceIdentify: '', // ip_端口
            iWndowType: 2, // 窗口分割的数量 2*2
            iChannelIDIndexList: [1, 4, 6, 7], // 选择的通道列表
        }
    },
    methods: {
        // 初始化
        initVideoCtrl () {
            // 检查插件是否已经安装过
            var iRet = WebVideoCtrl.I_CheckPluginInstall();
            console.log(iRet, '检测是否安装了WebComponentsKit.exe插件');
            if (iRet === -1) {
                alert("您还未安装过插件,双击开发包目录里的WebComponentsKit.exe安装!");
                return false;
            }

            // 初始化插件参数及插入插件
            WebVideoCtrl.I_InitPlugin(866, 740, {
                bWndFull: true,     // 是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
                iPackageType: 2,    // 2:PS 11:MP4
                iWndowType: this.iWndowType,
                bNoPlugin: true,
                cbSelWnd: (xmlDoc) => {
                    this.g_iWndIndex = parseInt($(xmlDoc).find("SelectWnd").eq(0).text(), 10);
                    console.log("当前选择的窗口编号:" + this.g_iWndIndex);
                },
                cbInitPluginComplete: () => {
                    WebVideoCtrl.I_InsertOBJECTPlugin(this.pluginId); // 嵌入插件

                    console.log('嵌入插件');

                    this.$nextTick(() => {
                        //先调用窗口分割方法
                        this.changeWndNum(this.iWndowType);
                        //调用登录方法
                        this.clickLogin();
                    })

                    // 检查插件是否最新
                    if (WebVideoCtrl.I_CheckPluginVersion() === -1) {
                        alert("检测到新的插件版本,双击开发包目录里的WebComponentsKit.exe升级!");
                        return false;
                    }
                }
            });
        },

        // 窗口分割
        changeWndNum (iType) {
            iType = parseInt(iType, 10);
            WebVideoCtrl.I_ChangeWndNum(iType);
        },

        // 登录
        clickLogin () {
            if (this.loginIp === '' || this.port === '') {
                return;
            }
            this.szDeviceIdentify = this.loginIp + '_' + this.port;
            console.log('登录所需参数', this.loginIp, 1, this.port, this.username, this.password);

            const iRet = WebVideoCtrl.I_Login(this.loginIp, 1, this.port, this.username, this.password, {
                success: (xmlDoc) => {
                    console.log(" 登录成功!");
                    setTimeout(() => {
                        // 获取通道信息
                        this.getChannelInfo();
                        // 获取端口
                        this.getDevicePort();
                    }, 10);

                    // 异步请求,当通道和端口都获取到的时候,开始预览

                    setTimeout(() => {
                        this.setIChannelID();
                    }, 1000)
                },
                error: (status, xmlDoc) => {
                    console.log(" 登录失败!", status, xmlDoc);
                }
            });

            if (iRet === -1) {
                console.log(this.szDeviceIdentify + " 已登录过!,直接预览");
                this.setIChannelID();
            }
        },
        // 获取通道信息
        getChannelInfo () {
            this.channelsList = [];

            if (this.szDeviceIdentify === '') {
                return false;
            }

            // 数字通道
            WebVideoCtrl.I_GetDigitalChannelInfo(this.szDeviceIdentify, {
                async: false,
                success: (xmlDoc) => {
                    var oChannels = $(xmlDoc).find("InputProxyChannelStatus");
                    const that = this;
                    $.each(oChannels, function (i) {
                        const id = $(this).find("id").eq(0).text();
                        let name = $(this).find("name").eq(0).text();
                        const online = $(this).find("online").eq(0).text();
                        if (online === "false") { // 过滤禁用的数字通道
                            return true;
                        }
                        if (name === "") {
                            name = "IPCamera " + (i < 9 ? "0" + (i + 1) : (i + 1));
                        }
                        that.channelsList.push({id, name, bZero: false});
                    });
                    console.log(this.szDeviceIdentify + " 获取数字通道成功!");
                    return true;
                },
                error: (status, xmlDoc) => {
                    console.log(this.szDeviceIdentify + " 获取数字通道失败!", status, xmlDoc);
                    return false;
                }
            });
        },
        // 获取端口
        getDevicePort () {
            if (this.szDeviceIdentify === '') {
                return false;
            }
            const oPort = WebVideoCtrl.I_GetDevicePort(this.szDeviceIdentify);
            if (oPort != null) {
                this.iDevicePort = oPort.iDevicePort; // 设备 SDK 端口号,不传的话,插件会自动向设备获取
                this.iRtspPort = oPort.iRtspPort;
                console.log(JSON.stringify(oPort) + " 获取端口成功!");
                return true;
            } else {
                console.log(JSON.stringify(oPort) + " 获取端口失败!");
                return false;
            }
        },
        // 设置预览不同的通道
        setIChannelID () {
            if (this.channelsList.length === 0) {
                return false;
            }
            console.log('开始设置通道');
            // 因为界面调控只能看到通道的名称,为了方便后期维护,所以需要通过通道名称获取通道id
            let arr = [];
            this.iChannelIDIndexList.map((iChannelID, iWndIndex) => {
                console.log(iChannelID, iWndIndex, '通道编号和窗口编号');
                setTimeout(() => {
                    // 多个同时播放的时候,g_iWndIndex应该设置上,不能不用,因为在clickStartRealPlay方法中已经在播放了,先停止
                    this.g_iWndIndex = iWndIndex;
                    this.clickStartRealPlay(iChannelID, iWndIndex); // iChannelID为通道号,  iWndIndex为窗口编号
                }, 200 * iWndIndex);
            })
            // 开始设置通道
            // for (let i = 0; i < 4; i++) { //i+1为通道号,  i 为窗口
            //     setTimeout(() => {
            //         // 多个同时播放的时候,g_iWndIndex应该设置上,不能不用,因为在clickStartRealPlay方法中已经在播放了,先停止
            //         this.g_iWndIndex = i;
            //         this.clickStartRealPlay(i, i++);
            //     }, 300 * i);
            // }
        },
        // 开始预览
        clickStartRealPlay (iChannelID, iWndIndex) {
            console.log('开始预览');

            if (!this.channelsList.length) {
                console.log('通道信息获取异常!')
                return false;
            }
            if (!this.iRtspPort) {
                console.log('RTSP端口获取异常!')
                return false;
            }

            const oWndInfo = WebVideoCtrl.I_GetWindowStatus(this.g_iWndIndex);

            const startRealPlay = () => {
                console.log('预览参数iRtspPort:' + this.iRtspPort);
                console.log('预览参数-通道列表:' + JSON.stringify(this.channelsList));
                console.log('预览参数-通道号iChannelID:' + this.channelsList[0].id);

                if (this.channelsList.length <= this.iChannelIDIndex) {
                    console.log('当前通道长度小于传入的通道索引');
                    return false;
                }

                WebVideoCtrl.I_StartRealPlay(this.szDeviceIdentify, {
                    iRtspPort: this.iRtspPort,
                    iStreamType: 2, // 码流类型  1:主码流 2:子码流 3:第三码流 4:转码码流
                    iChannelID: iChannelID, // 通道 ID 播放通道号,默认通道
                    bZeroChannel: false, // 是否播放零通道,默认为 false
                    iWndIndex: iWndIndex,
                    success: () => {
                        console.log('开始预览成功');
                    },
                    error: (status, xmlDoc) => {
                        if (status === 403) {
                            console.log('设备不支持Websocket取流!');
                        } else {
                            console.log('开始预览失败!');
                        }
                        console.log('预览失败', status + " " + xmlDoc);
                    }
                });
            };

            if (oWndInfo !== null) { // 已经在播放了,先停止,多个的时候也需要处理
                console.log('已经在播放了,先停止!');
                console.log('停止窗口编号:' + this.g_iWndIndex);
                WebVideoCtrl.I_Stop({
                    iWndIndex: this.g_iWndIndex,
                    success: () => {
                        console.log('停止成功,开始播放!');
                        startRealPlay();
                    },
                    error: () => {
                    console.log('停止播放异常!');
                    }
                });
            } else {
                console.log('开始播放!');
                startRealPlay();
            }
        },
        // 退出登录
        clickLogout () {
            // 退出登录
            let szInfo = "";

            var iRet = WebVideoCtrl.I_Logout(this.szDeviceIdentify);
            if (iRet === 0) {
                szInfo = "退出成功!";
                this.getChannelInfo();
                this.getDevicePort();
            } else {
                szInfo = "退出失败!";
            }
            console.log('退出成功', this.loginIp + '_' + this.port + " " + szInfo);
        },
        // 生成uuid
        generateUUID () {
            let d = new Date().getTime();
            let uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
            let r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
            });
            return uuid;
        }
    },
    mounted() {
        this.clickLogout();
        setTimeout(() => {
            this.initVideoCtrl();
        }, 200);
    },
    beforeDestroy () {
        this.clickLogout();
    },
}
</script>

<style lang="less" scoped>
    .video_wrapper_box {
        width: 100%;
        height: 100%;

        /deep/ .parent-wnd {
            > div {
            background: none !important;
            }
        }
        /deep/ canvas {
            border: none !important;
        }
    }
</style>

效果

在这里插入图片描述

闭坑指南

  1. 根据需要的功能对demo里面的代码进行借鉴即可。
  2. 代码流程:先进行初始化,然后进行窗口分割和登录,登录成功之后需要获取通道和获取端口,然后进行预览,中间需要对应延迟,保证异步都完成获取到对应的数据。
  3. 登录的参数:ip、端口、用户名、密码都是进口设备的参数
  4. 在所有流程走通之后可能会遇到预览成功了,界面却没有显示出来。
    • 首先控制台不能打开,控制台要是打开的话,界面视频会不显示,需要在控制台关闭的状态下。
    • 还有就是如果监控的外层或者父级组件加了v-if、v-showd等都会不显示出来
    • 如果监控的外层有轮播也会导致监控不生效。
  5. 针对多个监控分窗口的问题,需要单独设置不同的窗口编号同时显示对应的视频监控。

打印的日志

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐