甲方要求再页面可以实时观看监控,后端还不写接口,让用海康的开发包....,终于开发完成,给大家分享一下
注意事项:
1.使用web3.2开发包需要确认录像机,或者摄像头是否支持websocket取流
2.测试开发环境无法测试,需要配置本地Nginx环境,打包才能测试!!! 下载海康web3.2开发包里面有Nginx包,配置方法稍等也会贴图的,莫慌
话不多说直接上代码
1.需要引入的文件
2.nginx配置,这是web3.2开发包里携带的Nginx包,配置文件在conf里的nginx
找到server,server_name,配置IP,在你本地测试的话,需要配置为你本机IP
在location/ root,放上你的dist路径
返回Nginx包,点击start开启Nginx代理即可
3.用到的方法
3.1 登录,初始化
先初始化,再登录
let datas = reactive({
g_iWndIndex: 1,
iLoadedCount: 0,
g_aIframe: "",
iProtocol: 1,
szIP: "", // 录像机,摄像头IP
szPort: "80",
szUsername: "",
szPassword: "",
szIpPort: "",
channels: [],
});
// 登录
let loginDev = () => {
datas.szIpPort = datas.szIP + "_" + datas.szPort;
WebVideoCtrl.I_Login(
datas.szIP,
1,
datas.szPort,
datas.szUsername,
datas.szPassword,
{
success: function (xmlDoc) {
console.log(" 登录成功!");
console.log(xmlDoc);
getChannelInfo(); // 获取模拟通道
GetDigitalChannelInfo(); // 获取数字通道 (此方法用的最多,一般设备通道都为数字通道)
GetZeroChannelInfo(); // 获取零通道
// setTimeout(() => {
// startRealPlay();
// }, 350);
// changeWndNum();
},
error: function (status, xmlDoc) {
//失败的回调函数
console.log(" 登录失败!");
},
}
);
};
let videoInitPlugin = () => {
console.log("正在初始化");
// 检查插件是否已经安装过
var iRet = window.WebVideoCtrl.I_CheckPluginInstall();
if (-1 == iRet) {
alert("您还未安装过插件,双击开发包目录里的WebComponentsKit.exe安装!");
return;
}
console.log("初始化成功");
// var oPlugin = {
// iWidth: videos.value.offsetWidth, // plugin width
// iHeight: videos.value.offsetHeight, // plugin height
// };
// 初始化插件参数及插入插件oPlugin.iWidth
window.WebVideoCtrl.I_InitPlugin(1200, 800, {
bWndFull: true, //是否支持单窗口双击全屏,默认支持 true:支持 false:不支持
iWndowType: 2, //窗口分割数
iPackageType: 2,
bNoPlugin: true,
// iWndowType: iWndowType.value, //窗口分割数
cbInitPluginComplete: function () {
window.WebVideoCtrl.I_InsertOBJECTPlugin("divPlugin");
// 检查插件是否最新
if (-1 == window.WebVideoCtrl.I_CheckPluginVersion()) {
alert(
"检测到新的插件版本,双击开发包目录里的WebComponentsKit.exe升级!"
);
return;
}
},
szColorProperty: "#cecece",
cbSelWnd: function (xmlDoc) {
// 点击的哪个窗口返回值
channelNum.value = XMLtoString(xmlDoc)
.replace(/<[^<>]+>/g, "-")
.split("-")[2];
},
});
};
3.2获取模拟通道
// 获取模拟通道
let getChannelInfo = () => {
// let self = this;
if (!datas.szIpPort) {
return;
}
WebVideoCtrl.I_GetAnalogChannelInfo(datas.szIpPort, {
async: false,
success: function (xmlDoc) {
console.log(xmlDoc);
let oChannels = $(xmlDoc).find("VideoInputChannel");
console.log("获取模拟通道成功", oChannels);
$.each(oChannels, function (i) {
let id = $(this).find("id").eq(0).text(),
name = $(this).find("name").eq(0).text();
if (!name) {
name = "Camera " + (i < 9 ? "0" + (i + 1) : i + 1);
}
// datas.channels.push({
// id: id,
// name: name,
// bZero: false,
// });
});
},
error: function (status, xmlDoc) {
console.log("获取模拟通道失败", status, xmlDoc);
},
});
};
3.3 获取数字通道
// 获取数字通道
let GetDigitalChannelInfo = () => {
// let self = this;
console.log("获取数字通道", datas.szIpPort);
if (!datas.szIpPort) {
return;
}
WebVideoCtrl.I_GetDigitalChannelInfo(datas.szIpPort, {
async: false,
success: function (xmlDoc) {
var oChannels = $(xmlDoc).find("InputProxyChannelStatus");
// console.log(convertToJSON(oChannels));
let obj = XMLtoString(xmlDoc)
.replace(/<[^<>]+>/g, "-")
.split("-");
let list = [];
for (let i = 0; i < obj.length; i++) {
if (obj[i]) {
list.push(obj[i]);
}
}
XMLList.value = [];
let spArrList = spArr(list, 10);
iChannelIDList.value = [];
spArrList.forEach((itrms) => {
console.log(itrms);
if (itrms[itrms.length - 2] == "true") {
iChannelIDList.value.push(itrms[0]);
XMLList.value.push({
id: itrms[0],
name: itrms[itrms.length - 1],
aisle: true,
});
iChannelID.value = itrms[0];
} else {
XMLList.value.push({
id: itrms[0],
name: itrms[itrms.length - 1] + " " + "此通道暂无画面",
aisle: false,
});
}
});
console.log(XMLList.value);
// console.log(convertToJSON(oChannels));
console.log("获取数字通道成功");
$.each(oChannels, function (i) {
var id = $(this).find("id").eq(0).text(),
name = $(this).find("name").eq(0).text(),
ipAddress = $(this).find("ipAddress").eq(0).text(),
online = $(this).find("online").eq(0).text();
if ("false" == online) {
// 过滤禁用的数字通道
return true;
}
if ("" == name) {
name = "IPCamera " + (i < 9 ? "0" + (i + 1) : i + 1);
}
// console.log($(this).find("id").eq());
});
// startRealPlay();
},
error: function (status, xmlDoc) {
console.log("获取数字通道失败", status, xmlDoc);
},
});
};
3.4获取零通道
// 获取零通道
let GetZeroChannelInfo = () => {
// let self = this;
if (!datas.szIpPort) {
return;
}
WebVideoCtrl.I_GetZeroChannelInfo(datas.szIpPort, {
async: false,
success: function (xmlDoc) {
var oChannels = $(xmlDoc).find("ZeroVideoChannel");
console.log("获取零通道成功");
console.log(xmlDoc, "ling");
$.each(oChannels, function (i) {
var id = $(this).find("id").eq(0).text(),
name = $(this).find("name").eq(0).text();
if ("" == name) {
name = "Zero Channel " + (i < 9 ? "0" + (i + 1) : i + 1);
}
if ("true" == $(this).find("enabled").eq(0).text()) {
// filter the forbidden zero-channel
// oSel.append(
// "<option value='" + id + "' bZero='true'>" + name + "</option>"
// );
}
});
},
error: function (status, xmlDoc) {},
});
};
注意,登录成功后海康接口返回的通道数据是xml格式的,下面是解析通道的方法
function XMLtoString(elem) {
var serialized;
var serializer;
try {
// XMLSerializer exists in current Mozilla browsers
serializer = new XMLSerializer();
serialized = serializer.serializeToString(elem);
} catch (e) {
// Internet Explorer has a different approach to serializing XML
serialized = elem.xml;
}
return serialized;
}
function spArr(arr, num = 1) {
//arr是你要分割的数组,num是以几个为一组
let newArr = []; //首先创建一个新的空数组。用来存放分割好的数组
for (let i = 0; i < arr.length; ) {
//注意:这里与for循环不太一样的是,没有i++
newArr.push(arr.slice(i, (i += num)));
}
return newArr;
}
我找的解析海康返回的数据xml格式方法,是把通道信息提取出来,直接是数组,自己再处理成对象,大家可以自己也试试
最后是预览代码
WebVideoCtrl.I_StartRealPlay(datas.szIpPort, {
iWndIndex: channelNum.value, // 播放窗口
iStreamType: iStreamType.value, // 码流类型 1-主码流,2-子码流,默认使用主码流预览
iChannelID: iChannelID.value, // 播放通道号
bZeroChannel: false,
success: function () {
console.log("开始预览成功!");
},
error: function (status, xmlDoc) {
var szInfo = "";
console.log(status);
console.log(xmlDoc);
if (403 === status) {
console.log("设备不支持Websocket取流!");
} else {
console.log("开始预览失败");
}
},
});
这就是我使用海康web3.2开发包的方法,第一次接触解析视频流的家人们莫慌,慢慢来就是了,最后谁懂后端甩一个录像机IP在前端接入视频流的!!第一次写可能有点乱