邢台网站改版开发,长沙教育网站开发,织梦体育网站模板,朝阳建设局网站文章目录 前言相关网址综合安防管理平台网址获取Appkey和Secret/密码和密钥测试个人魔改工具类 海康视频接入获取摄像头Id下载海康Web插件原生Html导入网页设置 JS封装封装代码使用设置成功#xff01; 前言
最近有个需求是将海康的摄像头视频画面传到我们平台上#xff0c;… 文章目录 前言相关网址综合安防管理平台网址获取Appkey和Secret/密码和密钥测试个人魔改工具类 海康视频接入获取摄像头Id下载海康Web插件原生Html导入网页设置 JS封装封装代码使用设置成功 前言
最近有个需求是将海康的摄像头视频画面传到我们平台上作为一个全干工程师网页后端都要我来做。
相关网址 海康开发平台 资源中心 综合安防管理平台
我这里用的是综合安防管理平台
网址 综合安防管理平台 API OpenApi 下载 获取Appkey和Secret/密码和密钥
具体步骤可以看这个 python调用海康视频汇聚平台API获得所有摄像头设备编号、实时播放rtsp地址、回放rtsp地址 保证有默认合作方 拿到Key和Secret
测试
随便找个Api测试 测试成功有返回信息就可以了
个人魔改工具类
还是不喜欢全局静态的写法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Security;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;namespace HaiKang
{public class HaiKangService{/// summary/// 平台ip/// /summaryprivate string _ip;/// summary/// 平台端口/// /summaryprivate int _port 443;/// summary/// 平台APPKey/// /summaryprivate string _appkey;/// summary/// 平台APPSecret/// /summaryprivate string _secret;/// summary/// 是否使用HTTPS协议/// /summaryprivate bool _isHttps true;/// summary/// 设置信息参数/// /summary/// param nameappkey合作方APPKey/param/// param namesecret合作方APPSecret/param/// param nameip平台IP/param/// param nameport平台端口默认HTTPS的443端口/param/// param nameisHttps是否启用HTTPS协议默认HTTPS/param/// return/returnpublic HaiKangService(){_appkey 你的key;_secret 你的密码;_ip 你的服务器的ip地址;_port 1443;//一般是1443端口_isHttps true;}/// summary/// HTTP GET请求/// /summary/// param nameuriHTTP接口Url不带协议和端口如/artemis/api/resource/v1/cameras/indexCode?cameraIndexCodea10cafaa777c49a5af92c165c95970e0/param/// param nametimeout请求超时时间单位秒/param/// returns/returnspublic (byte[]? bytes, WebResponse? response) HttpGet(string uri, int timeout){Dictionarystring, string header new Dictionarystring, string();// 初始化请求组装请求头设置远程证书自动验证通过initRequest(header, uri, , false);// build web request objectStringBuilder sb new StringBuilder();sb.Append(_isHttps ? https:// : http://).Append(_ip).Append(:).Append(_port.ToString()).Append(uri);HttpWebRequest req (HttpWebRequest)HttpWebRequest.Create(sb.ToString());req.KeepAlive false;req.ProtocolVersion HttpVersion.Version11;req.AllowAutoRedirect false; // 不允许自动重定向req.Method GET;req.Timeout timeout * 1000; // 传入是秒需要转换成毫秒req.Accept header[Accept];req.ContentType header[Content-Type];foreach (string headerKey in header.Keys){if (headerKey.Contains(x-ca-)){req.Headers.Add(headerKey : header[headerKey]);}}HttpWebResponse rsp null;try{rsp (HttpWebResponse)req.GetResponse();if (HttpStatusCode.OK rsp.StatusCode){Stream rspStream rsp.GetResponseStream(); // 响应内容字节流StreamReader sr new StreamReader(rspStream);string strStream sr.ReadToEnd();long streamLength strStream.Length;byte[] response System.Text.Encoding.UTF8.GetBytes(strStream);rsp.Close();return ( response,rsp);}else if (HttpStatusCode.Found rsp.StatusCode || HttpStatusCode.Moved rsp.StatusCode) // 302/301 redirect{string reqUrl rsp.Headers[Location].ToString(); // 获取重定向URLWebRequest wreq WebRequest.Create(reqUrl); // 重定向请求对象WebResponse wrsp wreq.GetResponse(); // 重定向响应long streamLength wrsp.ContentLength; // 重定向响应内容长度Stream rspStream wrsp.GetResponseStream(); // 响应内容字节流byte[] response new byte[streamLength];rspStream.Read(response, 0, (int)streamLength); // 读取响应内容至byte数组rspStream.Close();rsp.Close();return (response, wrsp);}rsp.Close();}catch (WebException e){if (rsp ! null){rsp.Close();}}return (null,null);}/// summary/// HTTP Post请求/// /summary/// param nameuriHTTP接口Url不带协议和端口如/artemis/api/resource/v1/org/advance/orgList/param/// param namebody请求参数/param/// param nametimeout请求超时时间单位秒/param/// return请求结果/returnpublic (byte[]? bytes, string res_str) HttpPost(string uri, string body, int timeout){Dictionarystring, string header new Dictionarystring, string();// 初始化请求组装请求头设置远程证书自动验证通过initRequest(header, uri, body, true);// build web request objectStringBuilder sb new StringBuilder();sb.Append(_isHttps ? https:// : http://).Append(_ip).Append(:).Append(_port.ToString()).Append(uri);// 创建POST请求HttpWebRequest req (HttpWebRequest)HttpWebRequest.Create(sb.ToString());req.KeepAlive false;req.ProtocolVersion HttpVersion.Version11;req.AllowAutoRedirect false; // 不允许自动重定向req.Method POST;req.Timeout timeout * 1000; // 传入是秒需要转换成毫秒req.Accept header[Accept];req.ContentType header[Content-Type];foreach (string headerKey in header.Keys){if (headerKey.Contains(x-ca-)){req.Headers.Add(headerKey : header[headerKey]);}}if (!string.IsNullOrWhiteSpace(body)){byte[] postBytes Encoding.UTF8.GetBytes(body);req.ContentLength postBytes.Length;Stream reqStream null;try{reqStream req.GetRequestStream();reqStream.Write(postBytes, 0, postBytes.Length);reqStream.Close();}catch (WebException e){if (reqStream ! null){reqStream.Close();}return (null,null);}}HttpWebResponse rsp null;try{rsp (HttpWebResponse)req.GetResponse();if (HttpStatusCode.OK rsp.StatusCode){Stream rspStream rsp.GetResponseStream();StreamReader sr new StreamReader(rspStream);string strStream sr.ReadToEnd();long streamLength strStream.Length;byte[] response System.Text.Encoding.UTF8.GetBytes(strStream);rsp.Close();return (response,ResponseToStr(response));}else if (HttpStatusCode.Found rsp.StatusCode || HttpStatusCode.Moved rsp.StatusCode) // 302/301 redirect{try{string reqUrl rsp.Headers[Location].ToString(); // 如需要重定向URL请自行修改接口返回此参数WebRequest wreq WebRequest.Create(reqUrl);rsp (HttpWebResponse)wreq.GetResponse();Stream rspStream rsp.GetResponseStream();long streamLength rsp.ContentLength;int offset 0;byte[] response new byte[streamLength];while (streamLength 0){int n rspStream.Read(response, offset, (int)streamLength);if (0 n){break;}offset n;streamLength - n;}return ( response, ResponseToStr(response));}catch (Exception e){return (null,null);}}rsp.Close();}catch (WebException e){if (rsp ! null){rsp.Close();}}return (null,null);}private void initRequest(Dictionarystring, string header, string url, string body, bool isPost){// Accept string accept application/json;// */*;header.Add(Accept, accept);// ContentType string contentType application/json;header.Add(Content-Type, contentType);if (isPost){// content-md5be careful it must be lower case.string contentMd5 computeContentMd5(body);header.Add(content-md5, contentMd5);}// x-ca-timestampstring timestamp ( ( DateTime.Now.Ticks - TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1, 0, 0, 0, 0)).Ticks ) / 1000 ).ToString();header.Add(x-ca-timestamp, timestamp);// x-ca-noncestring nonce System.Guid.NewGuid().ToString();header.Add(x-ca-nonce, nonce);// x-ca-keyheader.Add(x-ca-key, _appkey);// build string to signstring strToSign buildSignString(isPost ? POST : GET, url, header);string signedStr computeForHMACSHA256(strToSign, _secret);// x-ca-signatureheader.Add(x-ca-signature, signedStr);if (_isHttps){// set remote certificate Validation auto passServicePointManager.ServerCertificateValidationCallback new System.Net.Security.RemoteCertificateValidationCallback(remoteCertificateValidate);ServicePointManager.SecurityProtocol SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;}}/// summary/// 计算content-md5/// /summary/// param namebody/param/// returnsbase64后的content-md5/returnsprivate string computeContentMd5(string body){MD5 md5 new MD5CryptoServiceProvider();byte[] result md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(body));return Convert.ToBase64String(result);}/// summary/// 远程证书验证/// /summary/// param namesender/param/// param namecert/param/// param namechain/param/// param nameerror/param/// returns验证是否通过始终通过/returnsprivate bool remoteCertificateValidate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error){return true;}/// summary/// 计算HMACSHA265/// /summary/// param namestr待计算字符串/param/// param namesecret平台APPSecet/param/// returnsHMAXH265计算结果字符串/returnsprivate string computeForHMACSHA256(string str, string secret){var encoder new System.Text.UTF8Encoding();byte[] secretBytes encoder.GetBytes(secret);byte[] strBytes encoder.GetBytes(str);var opertor new HMACSHA256(secretBytes);byte[] hashbytes opertor.ComputeHash(strBytes);return Convert.ToBase64String(hashbytes);}/// summary/// 计算签名字符串/// /summary/// param namemethodHTTP请求方法如“POST”/param/// param nameurl接口Url如/artemis/api/resource/v1/org/advance/orgList/param/// param nameheader请求头/param/// returns签名字符串/returnsprivate string buildSignString(string method, string url, Dictionarystring, string header){StringBuilder sb new StringBuilder();sb.Append(method.ToUpper()).Append(\n);if (null ! header){if (null ! header[Accept]){sb.Append((string)header[Accept]);sb.Append(\n);}if (header.Keys.Contains(Content-MD5) null ! header[Content-MD5]){sb.Append((string)header[Content-MD5]);sb.Append(\n);}if (null ! header[Content-Type]){sb.Append((string)header[Content-Type]);sb.Append(\n);}if (header.Keys.Contains(Date) null ! header[Date]){sb.Append((string)header[Date]);sb.Append(\n);}}// build and add header to signstring signHeader buildSignHeader(header);sb.Append(signHeader);sb.Append(url);return sb.ToString();}/// summary/// 返回字符流/// /summary/// param nameresponse/param/// returns/returnsprivate string ResponseToStr(byte[] bytes){var res ;res System.Text.Encoding.UTF8.GetString(bytes);return res;}/// summary/// 计算签名头/// /summary/// param nameheader请求头/param/// returns签名头/returnsprivate string buildSignHeader(Dictionarystring, string header){Dictionarystring, string sortedDicHeader new Dictionarystring, string();sortedDicHeader header;var dic from objDic in sortedDicHeader orderby objDic.Key ascending select objDic;StringBuilder sbSignHeader new StringBuilder();StringBuilder sb new StringBuilder();foreach (KeyValuePairstring, string kvp in dic){if (kvp.Key.Replace( , ).Contains(x-ca-)){sb.Append(kvp.Key :);if (!string.IsNullOrWhiteSpace(kvp.Value)){sb.Append(kvp.Value);}sb.Append(\n);if (sbSignHeader.Length 0){sbSignHeader.Append(,);}sbSignHeader.Append(kvp.Key);}}header.Add(x-ca-signature-headers, sbSignHeader.ToString());return sb.ToString();}}
}
海康视频接入
海康视频接入有两种方式第一种是有web插件第二种是无web插件。无web插件弄起来特别的麻烦所以我们主要讲第一种。
获取摄像头Id
选择分页获取监控点资源 选择个数多一点 下载海康Web插件 海康开发平台下载地址 视频Web 插件 V1.5.2直链下载地址 下载完成之后我们可以看到Demo选择合适的自己试一下 原生Html导入
我这里已经封装好了我直接拿出来了
网页设置
我将很多无关都隐藏了
!DOCTYPE html
html langen
headmeta charsetUTF-8script src~/Scripts/jquery-1.12.4.min.js/scriptscript src~/Scripts/jsencrypt.min.js/scriptscript src~/Scripts/web-control_1.2.5.min.js/script......../head
body.....div idplayWnd classplayWnd/div
/body
/html
CSS .playWnd {margin: 30px 0 0 150px;width: 1000px; /*播放容器的宽和高设定*/height: 600px;border: 1px solid red;
}JS封装
注意我这个是绑定id的必须要div的id为playWnd
封装代码
//海康div示例
//div id playWnd classplayWnd style left: 109px; top: 133px; /div /*** 海康摄像头帮助类*/
let oWebControl new WebControl();
class Hik_Class {/*** * param {Ip地址} ip* param {端口} port* param {密钥} appkey* param {密码} secret* param {摄像头Id} cameraIndexCode*/constructor(ip, port, appkey, secret, cameraIndexCode) {this.ip ip;this.port port;this.appkey appkey;this.secret secret;this.cameraIndexCode cameraIndexCode}Init() {var that thisoWebControl new WebControl({szPluginContainer: playWnd, // 指定容器idiServicePortStart: 15900, // 指定起止端口号建议使用该值iServicePortEnd: 15900,szClassId: 23BF3B0A-2C56-4D97-9C03-0CB103AA8F11, // 用于IE10使用ActiveX的clsidcbConnectSuccess: function () { // 创建WebControl实例成功 oWebControl.JS_StartService(window, { // WebControl实例创建成功后需要启动服务dllPath: ./VideoPluginConnect.dll // 值./VideoPluginConnect.dll写死 }).then(function () { // 启动插件服务成功oWebControl.JS_SetWindowControlCallback({ // 设置消息回调cbIntegrationCallBack: cbIntegrationCallBack});oWebControl.oDocOffset.top 95;//设置你的x,y偏移因为海康插件无法识别多页面的浏览器位置oWebControl.oDocOffset.left 280;oWebControl.JS_CreateWnd(playWnd, 1000, 600, { bEmbed: true }).then(function () { //JS_CreateWnd创建视频播放窗口宽高可设定that.init(); // 创建播放实例成功后初始化});}, function () { // 启动插件服务失败});},cbConnectError: function () { // 创建WebControl实例失败oWebControl null;$(#playWnd).html(插件未启动正在尝试启动请稍候...);WebControl.JS_WakeUp(VideoWebPlugin://); // 程序未启动时执行error函数采用wakeup来启动程序initCount;if (initCount 3) {setTimeout(function () {initPlugin();}, 3000)} else {$(#playWnd).html(插件启动失败请检查插件是否安装);}},cbConnectClose: function (bNormalClose) {// 异常断开bNormalClose false// JS_Disconnect正常断开bNormalClose true console.log(cbConnectClose);oWebControl null;$(#playWnd).html(插件未启动正在尝试启动请稍候...);WebControl.JS_WakeUp(VideoWebPlugin://);initCount;if (initCount 3) {setTimeout(function () {initPlugin();}, 3000)} else {$(#playWnd).html(插件启动失败请检查插件是否安装);}}});}init() {var that thisgetPubKey(function () {// 请自行修改以下变量值 var appkey that.appkey; //综合安防管理平台提供的appkey必填var secret setEncrypt(that.secret); //综合安防管理平台提供的secret必填var ip that.ip; //综合安防管理平台IP地址必填var playMode 0; //初始播放模式0-预览1-回放var port that.port; //综合安防管理平台端口若启用HTTPS协议默认443var snapDir D:\\SnapDir; //抓图存储路径var videoDir D:\\VideoDir; //紧急录像或录像剪辑存储路径var layout 1x1; //playMode指定模式的布局var enableHTTPS 1; //是否启用HTTPS协议与综合安防管理平台交互这里总是填1var encryptedFields secret; //加密字段默认加密领域为secretvar showToolbar 0; //是否显示工具栏0-不显示非0-显示var showSmart 0; //是否显示智能信息如配置移动侦测后画面上的线框0-不显示非0-显示var buttonIDs 0,16,256,257,258,259,260,512,513,514,515,516,517,768,769; //自定义工具条按钮// 请自行修改以上变量值 oWebControl.JS_RequestInterface({funcName: init,argument: JSON.stringify({appkey: appkey, //API网关提供的appkeysecret: secret, //API网关提供的secretip: ip, //API网关IP地址playMode: playMode, //播放模式决定显示预览还是回放界面port: port, //端口layout: layout, //布局enableHTTPS: enableHTTPS, //是否启用HTTPS协议encryptedFields: encryptedFields, //加密字段showToolbar: showToolbar, //是否显示工具栏showSmart: showSmart, //是否显示智能信息buttonIDs: buttonIDs //自定义工具条按钮})}).then(function (oData) {oWebControl.JS_Resize(1000, 600); // 初始化后resize一次规避firefox下首次显示窗口后插件窗口未与DIV窗口重合问题});});}Connect() {console.log(开始连接海康摄像头)var cameraIndexCode this.cameraIndexCode; //获取输入的监控点编号值必填var streamMode 0; //主子码流标识0-主码流1-子码流var transMode 1; //传输协议0-UDP1-TCPvar gpuMode 0; //是否启用GPU硬解0-不启用1-启用var wndId -1; //播放窗口序号在2x2以上布局下可指定播放窗口cameraIndexCode cameraIndexCode.replace(/(^\s*)/g, );cameraIndexCode cameraIndexCode.replace(/(\s*$)/g, );oWebControl.JS_RequestInterface({funcName: startPreview,argument: JSON.stringify({cameraIndexCode: cameraIndexCode, //监控点编号streamMode: streamMode, //主子码流标识transMode: transMode, //传输协议gpuMode: gpuMode, //是否开启GPU硬解wndId: wndId //可指定播放窗口})})}Close() {if (oWebControl ! null) {oWebControl.JS_HideWnd(); // 先让窗口隐藏规避可能的插件窗口滞后于浏览器消失问题 oWebControl.JS_Disconnect().then(function () { // 断开与插件服务连接成功},function () { // 断开与插件服务连接失败});}}
}//声明公用变量
var initCount 0;
var pubKey ;// 设置窗口控制回调
function setCallbacks() {oWebControl.JS_SetWindowControlCallback({cbIntegrationCallBack: cbIntegrationCallBack});
}// 推送消息
function cbIntegrationCallBack(oData) {showCBInfo(JSON.stringify(oData.responseMsg));
}//获取公钥
function getPubKey(callback) {oWebControl.JS_RequestInterface({funcName: getRSAPubKey,argument: JSON.stringify({keyLength: 1024})}).then(function (oData) {console.log(oData);if (oData.responseMsg.data) {pubKey oData.responseMsg.data;callback()}})
}//RSA加密
function setEncrypt(value) {var encrypt new JSEncrypt();encrypt.setPublicKey(pubKey);return encrypt.encrypt(value);
}// 监听resize事件使插件窗口尺寸跟随DIV窗口变化
$(window).resize(function () {if (oWebControl ! null) {oWebControl.JS_Resize(1000, 600);setWndCover();}
});// 监听滚动条scroll事件使插件窗口跟随浏览器滚动而移动
$(window).scroll(function () {if (oWebControl ! null) {oWebControl.JS_Resize(1000, 600);setWndCover();}
});// 设置窗口裁剪当因滚动条滚动导致窗口需要被遮住的情况下需要JS_CuttingPartWindow部分窗口
function setWndCover() {var iWidth $(window).width();var iHeight $(window).height();var oDivRect $(#playWnd).get(0).getBoundingClientRect();var iCoverLeft (oDivRect.left 0) ? Math.abs(oDivRect.left) : 0;var iCoverTop (oDivRect.top 0) ? Math.abs(oDivRect.top) : 0;var iCoverRight (oDivRect.right - iWidth 0) ? Math.round(oDivRect.right - iWidth) : 0;var iCoverBottom (oDivRect.bottom - iHeight 0) ? Math.round(oDivRect.bottom - iHeight) : 0;iCoverLeft (iCoverLeft 1000) ? 1000 : iCoverLeft;iCoverTop (iCoverTop 600) ? 600 : iCoverTop;iCoverRight (iCoverRight 1000) ? 1000 : iCoverRight;iCoverBottom (iCoverBottom 600) ? 600 : iCoverBottom;oWebControl.JS_RepairPartWindow(0, 0, 1001, 600); // 多1个像素点防止还原后边界缺失一个像素条if (iCoverLeft ! 0) {oWebControl.JS_CuttingPartWindow(0, 0, iCoverLeft, 600);}if (iCoverTop ! 0) {oWebControl.JS_CuttingPartWindow(0, 0, 1001, iCoverTop); // 多剪掉一个像素条防止出现剪掉一部分窗口后出现一个像素条}if (iCoverRight ! 0) {oWebControl.JS_CuttingPartWindow(1000 - iCoverRight, 0, iCoverRight, 600);}if (iCoverBottom ! 0) {oWebControl.JS_CuttingPartWindow(0, 600 - iCoverBottom, 1000, iCoverBottom);}
}//视频预览功能
$(#startPreview).click(function () {});//停止全部预览
$(#stopAllPreview).click(function () {oWebControl.JS_RequestInterface({funcName: stopAllPreview});
});// 标签关闭
$(window).unload(function () {if (oWebControl ! null) {oWebControl.JS_HideWnd(); // 先让窗口隐藏规避可能的插件窗口滞后于浏览器消失问题 oWebControl.JS_Disconnect().then(function () { // 断开与插件服务连接成功},function () { // 断开与插件服务连接失败});}
});
使用
//声明
let hik_Class new Hik_Class(你的外网ip地址,你的端口,
你的AppKey,
你的Secret,
你的摄像头Id)//使用hik_Class.Init()//创建窗体
hik_Class.Connect()//连接摄像头并输入视频流
hik_Class.Close()//关闭窗体
设置成功