/// <summary> /// 断开监控管理连接 /// </summary> /// <returns></returns> public SmcErr Disconnect() { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); SmcErr err = new CgwError(); if (OperationContext.Current != null) { //string strSessionId = OperationContext.Current.SessionId; string strSessionId = currentSessionID; if (!string.IsNullOrEmpty(strSessionId)) { err = SessionManage.Instance().RemoveSessionBySessionId(strSessionId); logEx.Info("Client DisConnect MonitorManageService Successful,Current.Cgw IP is : {0}", CgwConst.ClientIp); } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_CURRENTSESSION_NULL); logEx.Warn("Current SessionId is null ! "); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_CURRENTSESSION_NULL); logEx.Warn("Current SessionId is null ! "); } return(err); }
/// <summary> /// 断开融合网关 /// </summary> /// <returns></returns> public SmcErr DisConnect() { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); SmcErr err = new CgwError(); if (OperationContext.Current != null) { string strSessionId = OperationContext.Current.SessionId; if (!string.IsNullOrEmpty(strSessionId)) { err = SessionManage.Instance().RemoveSessionBySessionId(strSessionId); logEx.Trace("DisConnect Successful,Current.SessionId is : ", strSessionId); } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_CURRENTSESSION_NULL); logEx.Warn("Current SessionId is null ! "); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_CURRENTSESSION_NULL); logEx.Warn("Current SessionId is null ! "); } return(err); }
/// <summary> /// sip保活 /// </summary> /// <param name="localSignalGateway">网关对接T28181监控平台时,网关视为监控平台外域,该编码是标识网关的域编码,即是监控平台配置界面添加网关时的外域编码。</param> public void StartKeepalive(string serverID, string localID) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: T28181VideoMonitor.StartConnectRegisterSip()."); EM_SIP_RESULT iRet = EM_SIP_RESULT.RET_FAILURE; //初始话定时器 this.keepLiveTimer.AutoReset = true; this.keepLiveTimer.Elapsed += new System.Timers.ElapsedEventHandler((x, y) => { //sip保活,deviceID为用户名 string strBody = @"<?xml version='1.0'?><Notify><CmdType>Keepalive</CmdType><SN>" + KeepaliveSN + "</SN><DeviceID>" + localID + "</DeviceID><Status>OK</Status></Notify>"; KeepaliveSN++; iRet = SipSDKInterface.SIP_SDK_MESSAGE(serverID, strBody); if (iRet != EM_SIP_RESULT.RET_SUCCESS) { logEx.Warn("SipStackAdapter.Keepalive Failed"); //保活失败,重新注册. zWX231378 .2015/6/24 SIP_SDK_REGISTER(); } else { logEx.Trace("SipStackAdapter.Keepalive Success"); } }); //保活时间为10秒 this.keepLiveTimer.Interval = CgwConst.Thread_Sleep_Time * 10; keepLiveTimer.Start(); }
/// <summary> /// 连接融合网关 /// </summary> /// <param name="cgwPwd">连接字符串</param> /// <returns></returns> public SmcErr Connect(string cgwPwd) { SmcErr err = new CgwError(); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); if (isLoadSuccess == false) { err.SetErrorNo(CgwError.ERR_CGW_IS_LOADING); return(err); } //if (false == string.IsNullOrEmpty(cgwPwd)) //{ ////进行SHA256加密 //string newPassword = CommonFunction.SHA256Encrypt(strPwd); //保存当前会话 //if (newPassword == cgwPwd) //{ //获取SessionManage中Session个数 if (SessionManage.Instance().GetSessionsCount() == 0) { Guid sessionGuid = Guid.NewGuid(); //保存至CGW的session管理中 CgwSession CgwSession = new CgwSession(sessionGuid, OperationContext.Current.SessionId); isChangeLic = false; MessageProperties properties = OperationContext.Current.IncomingMessageProperties; //获取传进的消息属性 RemoteEndpointMessageProperty endpoint = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; //获取消息发送的远程终结点IP和端口 if (endpoint != null) { CgwConst.SmcIp = endpoint.Address; // 获取发送消息的客户端的 IP 地址。 logEx.Info("SMC Connect CgwService Successful,Current.SMC IP is : {0}", CgwConst.SmcIp); } else { logEx.Info("SMC Connect CgwService Successful,Current.SMC IP is null."); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_SESSION_COUNT_MAX); logEx.Warn("Session Count is Top Of Max number !"); } //} //else //{ // err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_PASSWORD_INCORRECT); // logEx.Error("Connect Password is Incorrect !"); //} //} //else //{ // err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_PASSWORD_NULL); // logEx.Error("Connect Password is null !"); //} return(err); }
/// <summary> /// 停止预览 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <returns>成功返回0,失败返回错误码</returns> public SmcErr StopReceiveVideo(string cameraNo) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: T28181VideoMonitor.StopReceiveVideo({0}).", cameraNo); SmcErr err = new CgwError(); //需要停止的预览句柄 uint needToStopChannel = 0; if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoChannelDic.ContainsKey(cameraNo)) { needToStopChannel = this.cameraVideoChannelDic[cameraNo]; this.videoChannelDataSenderDic.Remove(needToStopChannel); this.cameraVideoChannelDic.Remove(cameraNo); //关闭rtp回调 rtpAdapter.ESDK_RTP_CloseChannel(needToStopChannel); } else { logEx.Warn("Stop Receive camera video data failed. Don't need to end the preview.Camera No:{0}.", cameraNo); //如果预览句柄不存在,不需要处理,直接返回 return(err); } } catch (Exception ex) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.Execption message:{0}", ex.Message); return(err); } finally { this.handelOperateLock.ExitWriteLock(); } } //调用sdk的停止方法,放在handelOperateLock外面,防止长时间占用锁 if (needToStopChannel != 0) { int result = sipStack.StopRecvStream(needToStopChannel); //如果不为0,表示预览失败 if (result != CgwConst.IVS_SDK_SUCCESS_TAG) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed. error code:{0}", result); return(err); } logEx.Info("Stop Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, needToStopChannel); } return(err); }
/// <summary> /// 停止预览 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <returns>成功返回0,失败返回错误码</returns> public SmcErr StopReceiveVideo(string cameraNo) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: IvsVideoMonitor.StopReceiveVideo({0}).", cameraNo); SmcErr err = new CgwError(); //需要停止的预览句柄 int needToStopHandel = CgwConst.START_RECEIVE_VIDEO_DATA_FAILED; if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoHandeDic.ContainsKey(cameraNo)) { needToStopHandel = this.cameraVideoHandeDic[cameraNo]; this.videoHandleCameraDic.Remove(needToStopHandel); this.cameraVideoHandeDic.Remove(cameraNo); } else { logEx.Warn("Stop Receive camera video data failed. Don't need to end the preview.Camera No:{0}.", cameraNo); //如果预览句柄不存在,不需要处理,直接返回 return(err); } } catch (Exception ex) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.Execption message:{0}", ex.Message); return(err); } finally { this.handelOperateLock.ExitWriteLock(); } } //调用sdk的停止方法,放在handelOperateLock外面,防止长时间占用锁 if (needToStopHandel != CgwConst.START_RECEIVE_VIDEO_DATA_FAILED) { int result = this.ivsSdkClient.StopRealPlay(needToStopHandel); //如果不为0,表示预览失败 if (result != CgwConst.IVS_SDK_SUCCESS_TAG) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.Ivs sdk error code:{0}", result); return(err); } logEx.Info("Stop Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, needToStopHandel); } return(err); }
/// <summary> /// 根据消息体解析设备 /// </summary> /// <param name="strBody">查询返回的消息</param> private static void GetDeviceItem(string strBody) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: SipStackAdapter.GetDeviceItem()."); //解析返回的XML数据返回数据对象 XmlNode node = XmlUtil.ProcessResponseMsg(strBody, "DeviceList"); List <DeviceItem> list = XmlUtil.DeserializeToList <DeviceItem>(node); if (list == null) { return; } try { foreach (DeviceItem item in list) { if (!deviceList.Contains(item, new DeviceItemCompare())) { deviceList.Add(item); } else { logEx.Warn("SipStackAdapter.GetDeviceItem DeviceItem.DeviceID = {0} duplicate", item.DeviceID); return; } } //获取数据完成 if (deviceNum == deviceList.Count) { if (ReceivedAllDevice != null) { logEx.Trace("SipStackAdapter.GetDeviceItem Start ReceivedAllDevice"); // 接收完所有设备,通知上层处理单元 ReceivedAllDevice(null, null); //回收系统内存 GC.Collect(); GC.WaitForFullGCComplete(CgwConst.Thread_Sleep_Time); } } } catch (System.Exception ex) { logEx.Error("SipStackAdapter Get all cameras failed.Execption message:{0}", ex.Message); } }
/// <summary> /// 连接融合网关 /// </summary> /// <param name="password">连接字符串</param> /// <returns></returns> public SmcErr Connect(out string sessionID) { SmcErr err = new CgwError(); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); sessionID = ""; if (isLoadSuccess == false) { err.SetErrorNo(CgwError.ERR_CGW_IS_LOADING); return(err); } //获取SessionManage中Session个数 if (SessionManage.Instance().GetSessionsCount() == 0) { Guid sessionGuid = Guid.NewGuid(); sessionID = OperationContext.Current.SessionId; currentSessionID = sessionID; //保存至CGW的session管理中 CgwSession CgwSession = new CgwSession(sessionGuid, OperationContext.Current.SessionId); MessageProperties properties = OperationContext.Current.IncomingMessageProperties; //获取传进的消息属性 RemoteEndpointMessageProperty endpoint = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; //获取消息发送的远程终结点IP和端口 if (endpoint != null) { CgwConst.ClientIp = endpoint.Address; // 获取发送消息的客户端的 IP 地址。 logEx.Info("Client Connect MonitorManageService Successful,Current.Client IP is : {0}", CgwConst.ClientIp); } else { logEx.Info("Client Connect MonitorManageService Successful,Current.Client IP is null."); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_SESSION_COUNT_MAX); logEx.Warn("Session Count is Top Of Max number !"); } return(err); }
/// <summary> /// 连接融合网关 /// </summary> /// <param name="password">连接字符串</param> /// <returns></returns> public SmcErr Connect(string password) { SmcErr err = new CgwError(); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); if (false == string.IsNullOrEmpty(password)) { //获取后台密码字符串 string s = CommonFunction.GetAppSetting("PassWord"); //进行SHA256加密 string newPassword = CommonFunction.SHA256Encrypt(s); //保存当前会话 if (newPassword == password) { //获取SessionManage中Session个数 if (SessionManage.Instance().GetSessionsCount() == 0) { Guid sessionGuid = Guid.NewGuid(); //保存至CGW的session管理中 CGWSession CgwSession = new CGWSession(sessionGuid, OperationContext.Current.SessionId); logEx.Trace("Connect Successful,Current.SessionId is : ", OperationContext.Current.SessionId); } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_SESSION_COUNT_MAX); logEx.Warn("Session Count is Top Of Max number !"); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_PASSWORD_INCORRECT); logEx.Error("Connect Password is Incorrect !"); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_PASSWORD_NULL); logEx.Error("Connect Password is null !"); } return(err); }
/// <summary> /// 停止预览 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <returns>成功返回0,失败返回错误码</returns> public SmcErr StopReceiveVideo(string cameraNo) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: TiandyVideoMonitor.StopReceiveVideo({0}).", cameraNo); SmcErr err = new CgwError(); //需要停止的预览句柄 int needToStopHandel = CgwConst.START_RECEIVE_VIDEO_DATA_FAILED; if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoHandeDic.ContainsKey(cameraNo)) { needToStopHandel = this.cameraVideoHandeDic[cameraNo]; this.videoHandleCameraDic.Remove(needToStopHandel); this.cameraVideoHandeDic.Remove(cameraNo); } else { //不存在,表示已经删除,不返回错误 //err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Warn("Stop Receive camera video data failed. Don't need to end the preview.Camera No:{0}.", cameraNo); } } finally { this.handelOperateLock.ExitWriteLock(); } } //调用sdk的停止方法,放在handelOperateLock外面,防止长时间占用锁 if (needToStopHandel != CgwConst.START_RECEIVE_VIDEO_DATA_FAILED) { this.sdkClient.StopReceiveVideo(needToStopHandel); } logEx.Info("Stop Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, needToStopHandel); return(err); }
/// <summary> /// 获取摄像头列表及分组信息定时器 /// 1、获取系统中所有的域 /// 2、循环所有的域,查询域下面的分组,递归处理,获取节点关系 /// 3、查询设备列表 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GetAllCamerasTimer(object sender, System.Timers.ElapsedEventArgs e) { //查询设备未完成,需要阻塞直到查询结束 System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: T28181VideoMonitor.GetAllCamerasTimer()."); try { //获取设备列表 sipStack.GetDeviceList(username, deviceID); //开始计时 stopwatch.Start(); //查询结束或者超时时结束等待 while (!getDeviceEndFlg && stopwatch.ElapsedMilliseconds < iQueryDeviceTimeOut) { Thread.Sleep(CgwConst.Thread_Sleep_Time); } if (stopwatch.ElapsedMilliseconds >= iQueryDeviceTimeOut) { logEx.Warn("GetAllCamerasTimer Timeout"); } } catch (System.Exception ex) { logEx.Error("GetAllCamerasTimer failed.Exception message:{0}", ex.Message); } finally { //停止计时、获取设备完成标志复位 stopwatch.Stop(); getDeviceEndFlg = false; logEx.Info("cameraList.{0}", cameraList.Count); logEx.Info("groupList.{0}", groupList.Count); logEx.Info("nodeRelationList.{0}", nodeRelationList.Count); logEx.Trace("Leave: T28181VideoMonitor.GetAllCamerasTimer()."); } }
/// <summary> /// 保活监控平台服务 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void MonitorManageServiceKeepLiveTimer_Elapsed(object sender, ElapsedEventArgs e) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); SmcErr err = new SmcErr(); try { if (isNeedKeepAliver) { //Connect Monitor if (!serviceControl.MonitorServiceRun()) { isNeedConnect = true; //2015/2/13 Monitor服务不在线,将KeepAliver置为false,避免线程不断保活,待测试 isNeedKeepAliver = false; err.SetErrorNo(CgwError.ERR_MONITOR_MANAGE_SERVICE_RESTARTING); } else { err = CgwMonitorManageAdapter.Instance().KeepAliver(); } if (err.IsSuccess()) { logEx.Trace("MonitorManageServiceKeepLive Successful !"); } else { isNeedConnect = true; isNeedKeepAliver = false; logEx.Warn("MonitorManageServiceKeepLive Failed !"); } } } catch (System.Exception ex) { isNeedConnect = true; isNeedKeepAliver = false; logEx.Error("MonitorManageServiceKeepLive.Exception is {0}", ex.ToString()); } }
/// <summary> /// 失效通道 /// </summary> /// <param name="channelLabel"></param> public void DisableChannel(string channelLabel) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); try { bool successed = this.channelDicLocker.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME); // 申请互斥 if (successed) { try { if (this.monitorChannelDic.ContainsKey(channelLabel)) { this.monitorChannelDic[channelLabel].Disable(); } else { logEx.Warn("DisableChannel can't find channel label={0}.", channelLabel); } } finally { // 释放互斥量 this.channelDicLocker.ExitReadLock(); } } else { // 日志 logEx.Error("DisableChannel: Enert Write Lock Failed.WaitingReadCount:{0};WaitingWriteCount:{1}.", this.channelDicLocker.WaitingReadCount, this.channelDicLocker.WaitingWriteCount); } } catch (Exception ex) { // 日志 logEx.Error(ex, "DisableChannel: Enert Write Lock Exception."); } }
/// <summary> /// 写日志回调函数 /// </summary> /// <param name="level"></param> /// <param name="log"></param> /// <param name="len"></param> /// <returns></returns> private uint WriteLog(NLogLevel level, string log, int len) { NLog.Logger sotLog = NLog.LogManager.GetLogger("SoftTerminal"); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(sotLog); try { switch (level) { case NLogLevel.Error: logEx.Error(log); break; case NLogLevel.Warn: logEx.Warn(log); break; case NLogLevel.Info: logEx.Info(log); break; case NLogLevel.Trace: logEx.Trace(log); break; default: break; } } catch (System.Exception ex) { logEx.Error(ex, "WriteLog Exception level:{0}, log:{1}.", level, log); } return(1); }
/// <summary> /// 根据消息体解析设备 /// </summary> /// <param name="strBody">查询返回的消息</param> private static void GetDeviceItem(string strBody) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: SipStackAdapter.GetDeviceItem()."); //解析返回的XML数据返回数据对象 XmlNode node = XmlUtil.ProcessResponseMsg(strBody, "DeviceList"); List<DeviceItem> list = XmlUtil.DeserializeToList<DeviceItem>(node); if (list == null) { return; } try { foreach (DeviceItem item in list) { if (!deviceList.Contains(item, new DeviceItemCompare())) { deviceList.Add(item); } else { logEx.Warn("SipStackAdapter.GetDeviceItem DeviceItem.DeviceID = {0} duplicate", item.DeviceID); return; } } //获取数据完成 if (deviceNum == deviceList.Count) { if (ReceivedAllDevice != null) { logEx.Trace("SipStackAdapter.GetDeviceItem Start ReceivedAllDevice"); // 接收完所有设备,通知上层处理单元 ReceivedAllDevice(null, null); //回收系统内存 GC.Collect(); GC.WaitForFullGCComplete(CgwConst.Thread_Sleep_Time); } } } catch (System.Exception ex) { logEx.Error("SipStackAdapter Get all cameras failed.Execption message:{0}", ex.Message); } }
/// <summary> /// 连接融合网关 /// </summary> /// <param name="password">连接字符串</param> /// <returns></returns> public SmcErr Connect(out string sessionID) { SmcErr err = new CgwError(); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); sessionID = ""; if (isLoadSuccess == false) { err.SetErrorNo(CgwError.ERR_CGW_IS_LOADING); return err; } //获取SessionManage中Session个数 if (SessionManage.Instance().GetSessionsCount() == 0) { Guid sessionGuid = Guid.NewGuid(); sessionID = OperationContext.Current.SessionId; currentSessionID = sessionID; //保存至CGW的session管理中 CgwSession CgwSession = new CgwSession(sessionGuid, OperationContext.Current.SessionId); MessageProperties properties = OperationContext.Current.IncomingMessageProperties; //获取传进的消息属性 RemoteEndpointMessageProperty endpoint = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; //获取消息发送的远程终结点IP和端口 if (endpoint != null) { CgwConst.ClientIp = endpoint.Address; // 获取发送消息的客户端的 IP 地址。 logEx.Info("Client Connect MonitorManageService Successful,Current.Client IP is : {0}", CgwConst.ClientIp); } else { logEx.Info("Client Connect MonitorManageService Successful,Current.Client IP is null."); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_SESSION_COUNT_MAX); logEx.Warn("Session Count is Top Of Max number !"); } return err; }
/// <summary> /// 停止预览 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <returns>成功返回0,失败返回错误码</returns> public SmcErr StopReceiveVideo(string cameraNo) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: T28181VideoMonitor.StopReceiveVideo({0}).", cameraNo); SmcErr err = new CgwError(); //需要停止的预览句柄 uint needToStopChannel = 0; if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoChannelDic.ContainsKey(cameraNo)) { needToStopChannel = this.cameraVideoChannelDic[cameraNo]; this.videoChannelDataSenderDic.Remove(needToStopChannel); this.cameraVideoChannelDic.Remove(cameraNo); //用户参数,4字节整数 IntPtr pUser = Marshal.AllocHGlobal(4); NetSourcedInterface.IVS_NETSOURCE_SetDataCallBack(needToStopChannel, null, pUser); //释放NETSOURCE通道资源 IVS_NETSOURCE_RESULT iNet = NetSourcedInterface.IVS_NETSOURCE_CloseNetStream(needToStopChannel); if (iNet != IVS_NETSOURCE_RESULT.SUCCESS) { logEx.Error("IVS_NETSOURCE_CloseNetStream failed channel={0}", needToStopChannel); err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); } //关闭rtp回调 rtpAdapter.ESDK_RTP_CloseChannel(needToStopChannel); } else { logEx.Warn("Stop Receive camera video data failed. Don't need to end the preview.Camera No:{0}.", cameraNo); //如果预览句柄不存在,不需要处理,直接返回 return err; } } catch (Exception ex) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.Execption message:{0}", ex.Message); return err; } finally { this.handelOperateLock.ExitWriteLock(); } } //调用sdk的停止方法,放在handelOperateLock外面,防止长时间占用锁 if (needToStopChannel != 0) { EM_SIP_RESULT iRet = sipStack.StopRecvStream(needToStopChannel); //如果不为0,表示预览失败 if (iRet != EM_SIP_RESULT.RET_SUCCESS) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed. error code:{0}", iRet); return err; } logEx.Info("Stop Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, needToStopChannel); } return err; }
/// <summary> /// 连接融合网关 /// </summary> /// <param name="password">连接字符串</param> /// <returns></returns> public SmcErr Connect(string password) { SmcErr err = new CgwError(); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); if (false == string.IsNullOrEmpty(password)) { //获取后台密码字符串 string s = CommonFunction.GetAppSetting("PassWord"); //进行SHA256加密 string newPassword = CommonFunction.SHA256Encrypt(s); //保存当前会话 if (newPassword == password) { //获取SessionManage中Session个数 if (SessionManage.Instance().GetSessionsCount() == 0) { Guid sessionGuid = Guid.NewGuid(); //保存至CGW的session管理中 CGWSession CgwSession = new CGWSession(sessionGuid, OperationContext.Current.SessionId); logEx.Trace("Connect Successful,Current.SessionId is : ", OperationContext.Current.SessionId); } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_SESSION_COUNT_MAX); logEx.Warn("Session Count is Top Of Max number !"); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_PASSWORD_INCORRECT); logEx.Error("Connect Password is Incorrect !"); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_PASSWORD_NULL); logEx.Error("Connect Password is null !"); } return err; }
/// <summary> /// 码流回调函数, /// 1、根据预览句柄handle从videoHandleCameraDic中获取摄像头编号, /// 2、根据摄像头编号,获取mic状态 /// 3、判断码流是否是音频,如果是音频,根据mic状态判断是否需要转发 /// </summary> /// <param name="handle">播放句柄</param> /// <param name="pRawFrameInfo">实况参数</param> /// <param name="pBuf">码流</param> /// <param name="uiBufSize">大小</param> /// <param name="cameraNo">摄像头编号</param> private void IvsRealPlayCallBackRaw(int handle, IvsRawFrameInfo pRawFrameInfo, byte[] pBuf, UInt32 uiBufSize, string pUserData) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); //logEx.Trace("Enter:IvsRealPlayCallBackRaw(),{0}", pUserData); MediaDataSender mediaDataSender = null; try { if (this.handelOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (!this.videoHandleCameraDic.ContainsKey(handle)) { logEx.Error("The video data handle is not found.Handle:{0}", handle); return; } mediaDataSender = this.videoHandleCameraDic[handle]; } finally { this.handelOperateLock.ExitReadLock(); } } if (mediaDataSender == null) { return; } StreamType streamType = StreamType.VIDEO_H264; //判断码流类型,因为码流回调访问频频非常高,不单独抽成一个方法,减少方法访问开销 //对于支持的码流类型,用break退出switch,对于不支持的码流类型直接舍弃,用return返回 switch (pRawFrameInfo.StreamType) { //对于音频只接收G711A和G711U,其他舍弃 case (int)IvsStreamType.PAY_LOAD_TYPE_PCMU: streamType = StreamType.AUDIO_G711U; break; case (int)IvsStreamType.PAY_LOAD_TYPE_PCMA: streamType = StreamType.AUDIO_G711A; break; //只接收H264的视频码流 case (int)IvsStreamType.PAY_LOAD_TYPE_H264: //H264的标准视频流,作为视频流处理 streamType = StreamType.VIDEO_H264; break; default: //不支持的类型,直接舍弃,返回 //logEx.Warn("This stream type is not support. Chuck the data.StreamType:{0};Camera no:{1}", // Enum.GetName(typeof(IvsStreamType), pRawFrameInfo.StreamType), // cameraNo); return; } if (streamType == StreamType.AUDIO_G711A || streamType == StreamType.AUDIO_G711U) { //如果是音频流,需要判断mic的状态,开启时才发送音频流 if (this.micOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraMicStatusDic.ContainsKey(mediaDataSender.CameraNo)) { //如果mic为非开启状态,则不发送音频码流, if (!this.cameraMicStatusDic[mediaDataSender.CameraNo]) { //logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } else { //默认为关闭状态,因此如果cameraMicStatusDic不包含该摄像头,则认为处于关闭状态,舍弃音频码流 //logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } finally { this.micOperateLock.ExitReadLock(); } } } MediaData mediaData = new MediaData(); mediaData.Data = pBuf; //IVS 目前为裸码流 mediaData.DataType = MediaDataType.FRAME_DATA; mediaData.StreamType = streamType; mediaData.Size = uiBufSize; //将Ivs帧类型转换成各融合网关统一的帧类型 string name = Enum.GetName(typeof(IvsH264NaluType), pRawFrameInfo.FrameType); //帧类型判断,偶现IVS返回的帧类型,在融合网关中未记录,返回值为null if (string.IsNullOrEmpty(name)) { logEx.Warn("IvsRealPlayCallBackRaw FrameType Is Not Defined ,FrameType:{0}", pRawFrameInfo.FrameType); mediaData.FrameType = FrameDataType.H264_NALU_TYPE_UNDEFINED; } else { if (Enum.IsDefined(typeof(FrameDataType), name)) { FrameDataType frameDataType = (FrameDataType)Enum.Parse(typeof(FrameDataType), name); mediaData.FrameType = frameDataType; } else { mediaData.FrameType = FrameDataType.H264_NALU_TYPE_UNDEFINED; } } //向回调函数转发码流 //this.videoDataCallBack(cameraNo, mediaData, this.sender); //logEx.Debug("FrameDataCallBackFun.mediaData.DataType={0},FrameType = {1},StreamType = {2},Size = {3}", Enum.GetName(typeof(MediaDataType), mediaData.DataType), // Enum.GetName(typeof(FrameDataType), mediaData.FrameType), Enum.GetName(typeof(StreamType), mediaData.StreamType), mediaData.Size); mediaDataSender.SendData(mediaData, this.sender); } catch (Exception e) { logEx.Error("Send the media data failed.Execption message:{0}", e.ToString()); } }
/// <summary> /// 连接融合网关 /// </summary> /// <param name="cgwPwd">连接字符串</param> /// <returns></returns> public SmcErr Connect(string cgwPwd) { SmcErr err = new CgwError(); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); if (isLoadSuccess == false) { err.SetErrorNo(CgwError.ERR_CGW_IS_LOADING); return err; } //if (false == string.IsNullOrEmpty(cgwPwd)) //{ ////进行SHA256加密 //string newPassword = CommonFunction.SHA256Encrypt(strPwd); //保存当前会话 //if (newPassword == cgwPwd) //{ //获取SessionManage中Session个数 if (SessionManage.Instance().GetSessionsCount() == 0) { Guid sessionGuid = Guid.NewGuid(); //保存至CGW的session管理中 CgwSession CgwSession = new CgwSession(sessionGuid, OperationContext.Current.SessionId); isChangeLic = false; MessageProperties properties = OperationContext.Current.IncomingMessageProperties; //获取传进的消息属性 RemoteEndpointMessageProperty endpoint = properties[RemoteEndpointMessageProperty.Name] as RemoteEndpointMessageProperty; //获取消息发送的远程终结点IP和端口 if (endpoint != null) { CgwConst.SmcIp = endpoint.Address; // 获取发送消息的客户端的 IP 地址。 logEx.Info("SMC Connect CgwService Successful,Current.SMC IP is : {0}", CgwConst.SmcIp); } else { logEx.Info("SMC Connect CgwService Successful,Current.SMC IP is null."); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_SESSION_COUNT_MAX); logEx.Warn("Session Count is Top Of Max number !"); } //} //else //{ // err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_PASSWORD_INCORRECT); // logEx.Error("Connect Password is Incorrect !"); //} //} //else //{ // err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_PASSWORD_NULL); // logEx.Error("Connect Password is null !"); //} return err; }
/// <summary> /// rtp码流回调处理 /// </summary> /// <param name="pBuf">帧数据字节数组</param> /// <param name="pFrameData">帧数据类型</param> /// <param name="uiChannel">通道</param> /// <param name="uiBufSize">帧数据字节数组长度</param> private void FrameDataCallBackFun(IntPtr pBuf, uint uiBufSize, ref ST_FRAME_DATA pFrameData, uint uiChannel) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); ST_FRAME_DATA frameData = pFrameData; MediaDataSender mediaDataSender = null; if (this.handelOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.videoChannelDataSenderDic.ContainsKey(uiChannel)) { mediaDataSender = this.videoChannelDataSenderDic[uiChannel]; } } finally { this.handelOperateLock.ExitReadLock(); } } if (mediaDataSender == null) { logEx.Warn("FrameDataCallBackFun mediaDataSender = NULL"); return; } StreamType streamType = StreamType.VIDEO_H264; //对于支持的码流类型,用break退出switch,对于不支持的码流类型直接舍弃,用return返回 switch (frameData.iStreamType) { //对于音频只接收G711A和G711U,其他舍弃 case (int)IvsStreamType.PAY_LOAD_TYPE_PCMU: streamType = StreamType.AUDIO_G711U; break; case (int)IvsStreamType.PAY_LOAD_TYPE_PCMA: streamType = StreamType.AUDIO_G711A; break; //只接收H264的视频码流 case (int)IvsStreamType.PAY_LOAD_TYPE_H264: //H264的标准视频流,作为视频流处理 streamType = StreamType.VIDEO_H264; break; default: //不支持的类型,直接舍弃,返回 return; } if (streamType == StreamType.AUDIO_G711A || streamType == StreamType.AUDIO_G711U) { //如果是音频流,需要判断mic的状态,开启时才发送音频流 if (this.micOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraMicStatusDic.ContainsKey(mediaDataSender.CameraNo)) { //如果mic为非开启状态,则不发送音频码流, if (!this.cameraMicStatusDic[mediaDataSender.CameraNo]) { logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } else { //默认为关闭状态,因此如果cameraMicStatusDic不包含该摄像头,则认为处于关闭状态,舍弃音频码流 logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } finally { this.micOperateLock.ExitReadLock(); } } } try { MediaData mediaData = new MediaData(); //获取非托管的数据 byte[] datagram = new byte[uiBufSize]; if (!(streamType == StreamType.AUDIO_G711A || streamType == StreamType.AUDIO_G711U)) { Marshal.Copy(pBuf, datagram, 0, (int)uiBufSize); //视频帧数据头部增加四个四节的开始表实0x000001 byte[] newDatagram = new byte[uiBufSize + 4]; datagram.CopyTo(newDatagram, 4); newDatagram[3] = 1; mediaData.Data = newDatagram; mediaData.Size = (uint)(uiBufSize + 4); } else { mediaData.Data = datagram; mediaData.Size = (uiBufSize); } //裸码流 mediaData.DataType = MediaDataType.FRAME_DATA; mediaData.StreamType = streamType; //将帧类型转换成各融合网关统一的帧类型 string name = Enum.GetName(typeof(IvsH264NaluType), frameData.iFrameDataType); if (Enum.IsDefined(typeof(FrameDataType), name)) { FrameDataType frameDataType = (FrameDataType)Enum.Parse(typeof(FrameDataType), name); mediaData.FrameType = frameDataType; } else { mediaData.FrameType = FrameDataType.H264_NALU_TYPE_UNDEFINED; } //向回调函数转发码流 mediaDataSender.SendData(mediaData, this.sender); } catch (System.Exception ex) { logEx.Error("FrameDataCallBackFun failed.Execption message:{0}", ex.Message); } }
/// <summary> /// 停止预览 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <returns>成功返回0,失败返回错误码</returns> public SmcErr StopReceiveVideo(string cameraNo) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: T28181VideoMonitor.StopReceiveVideo({0}).", cameraNo); SmcErr err = new CgwError(); //需要停止的预览句柄 uint needToStopChannel = 0; if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoChannelDic.ContainsKey(cameraNo)) { needToStopChannel = this.cameraVideoChannelDic[cameraNo]; this.videoChannelDataSenderDic.Remove(needToStopChannel); this.cameraVideoChannelDic.Remove(cameraNo); //关闭rtp回调 rtpAdapter.ESDK_RTP_CloseChannel(needToStopChannel); } else { logEx.Warn("Stop Receive camera video data failed. Don't need to end the preview.Camera No:{0}.", cameraNo); //如果预览句柄不存在,不需要处理,直接返回 return err; } } catch (Exception ex) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.Execption message:{0}", ex.Message); return err; } finally { this.handelOperateLock.ExitWriteLock(); } } //调用sdk的停止方法,放在handelOperateLock外面,防止长时间占用锁 if (needToStopChannel != 0) { int result = sipStack.StopRecvStream(needToStopChannel); //如果不为0,表示预览失败 if (result != CgwConst.IVS_SDK_SUCCESS_TAG) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed. error code:{0}", result); return err; } logEx.Info("Stop Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, needToStopChannel); } return err; }
/// <summary> /// 获取摄像头列表及分组信息定时器 /// 1、获取系统中所有的域 /// 2、循环所有的域,查询域下面的分组,递归处理,获取节点关系 /// 3、查询设备列表 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void GetAllCamerasTimer(object sender, System.Timers.ElapsedEventArgs e) { //查询设备未完成,需要阻塞直到查询结束 System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: T28181VideoMonitor.GetAllCamerasTimer()."); try { //获取设备列表 sipStack.GetDeviceList(username, deviceID); //开始计时 stopwatch.Start(); //查询结束或者超时时结束等待 while (!getDeviceEndFlg && stopwatch.ElapsedMilliseconds < iQueryDeviceTimeOut ) { Thread.Sleep(CgwConst.Thread_Sleep_Time); } if (stopwatch.ElapsedMilliseconds >= iQueryDeviceTimeOut) { logEx.Warn("GetAllCamerasTimer Timeout"); } } catch (System.Exception ex) { logEx.Error("GetAllCamerasTimer failed.Exception message:{0}", ex.Message); } finally { //停止计时、获取设备完成标志复位 stopwatch.Stop(); getDeviceEndFlg = false; logEx.Info("cameraList.{0}", cameraList.Count); logEx.Info("groupList.{0}", groupList.Count); logEx.Info("nodeRelationList.{0}", nodeRelationList.Count); logEx.Trace("Leave: T28181VideoMonitor.GetAllCamerasTimer()."); } }
/// <summary> /// 停止云台控制,摄像头控制 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <param name="ptzCommand">命令类型</param> /// <returns></returns> public SmcErr StopControlPtz(string cameraNo, PtzCommandType ptzCommand) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: TiandyVideoMonitor.StopControlPtz({0}).", cameraNo); SmcErr err = new CgwError(); int handel = CgwConst.START_RECEIVE_VIDEO_DATA_FAILED; if (this.handelOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoHandeDic.ContainsKey(cameraNo)) { handel = this.cameraVideoHandeDic[cameraNo]; } else { logEx.Warn("The camera was not Preview.Don't need to end the control.Camera No:{0}.", cameraNo); } } finally { this.handelOperateLock.ExitReadLock(); } } if (handel != CgwConst.START_RECEIVE_VIDEO_DATA_FAILED) { Client_PTZ_Command client_ptz_command = new Client_PTZ_Command(); client_ptz_command.start = false; //将ptz命令转换成天地伟业的命令 string name = Enum.GetName(typeof(PtzCommandType), ptzCommand); if (Enum.IsDefined(typeof(TiandyPtzCommandType), name)) { TiandyPtzCommandType tiandyPtzCommandType = (TiandyPtzCommandType)Enum.Parse(typeof(TiandyPtzCommandType), name); client_ptz_command.cmd = (int)tiandyPtzCommandType; } else { err.SetErrorNo(CgwError.STOP_CONTROL_PTZ_FAILED); logEx.Error("The tiandy monitor is not support the command.ptzCommand:{0}.", ptzCommand); return(err); } bool result = this.sdkClient.ControlPtz(handel, client_ptz_command); if (result) { logEx.Info("Stop control camera ptz success.Camera No:{0}.", cameraNo); } else { err.SetErrorNo(CgwError.STOP_CONTROL_PTZ_FAILED); logEx.Error("Stop control camera ptz failed.Camera No:{0}.", cameraNo); } } else { err.SetErrorNo(CgwError.STOP_CONTROL_PTZ_FAILED); logEx.Error("Handel is not found. Stop control camera ptz failed. Camera No:{0}.", cameraNo); return(err); } return(err); }
/// <summary> /// 断开融合网关 /// </summary> /// <returns></returns> public SmcErr DisConnect() { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); SmcErr err = new CgwError(); if (OperationContext.Current != null) { string strSessionId = OperationContext.Current.SessionId; if (!string.IsNullOrEmpty(strSessionId)) { err = SessionManage.Instance().RemoveSessionBySessionId(strSessionId); logEx.Trace("DisConnect Successful,Current.SessionId is : ", strSessionId); } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_CURRENTSESSION_NULL); logEx.Warn("Current SessionId is null ! "); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_CURRENTSESSION_NULL); logEx.Warn("Current SessionId is null ! "); } return err; }
/// <summary> /// 停止云台控制,摄像头控制 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <param name="ptzCommand">命令类型</param> /// <returns></returns> public SmcErr StopControlPtz(string cameraNo, PtzCommandType ptzCommand) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: TiandyVideoMonitor.StopControlPtz({0}).", cameraNo); SmcErr err = new CgwError(); int handel = CgwConst.START_RECEIVE_VIDEO_DATA_FAILED; if (this.handelOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoHandeDic.ContainsKey(cameraNo)) { handel = this.cameraVideoHandeDic[cameraNo]; } else { logEx.Warn("The camera was not Preview.Don't need to end the control.Camera No:{0}.", cameraNo); } } finally { this.handelOperateLock.ExitReadLock(); } } if (handel != CgwConst.START_RECEIVE_VIDEO_DATA_FAILED) { Client_PTZ_Command client_ptz_command = new Client_PTZ_Command(); client_ptz_command.start = false; //将ptz命令转换成天地伟业的命令 string name = Enum.GetName(typeof(PtzCommandType), ptzCommand); if (Enum.IsDefined(typeof(TiandyPtzCommandType), name)) { TiandyPtzCommandType tiandyPtzCommandType = (TiandyPtzCommandType)Enum.Parse(typeof(TiandyPtzCommandType), name); client_ptz_command.cmd = (int)tiandyPtzCommandType; } else { err.SetErrorNo(CgwError.STOP_CONTROL_PTZ_FAILED); logEx.Error("The tiandy monitor is not support the command.ptzCommand:{0}.", ptzCommand); return err; } bool result = this.sdkClient.ControlPtz(handel, client_ptz_command); if (result) { logEx.Info("Stop control camera ptz success.Camera No:{0}.", cameraNo); } else { err.SetErrorNo(CgwError.STOP_CONTROL_PTZ_FAILED); logEx.Error("Stop control camera ptz failed.Camera No:{0}.", cameraNo); } } else { err.SetErrorNo(CgwError.STOP_CONTROL_PTZ_FAILED); logEx.Error("Handel is not found. Stop control camera ptz failed. Camera No:{0}.", cameraNo); return err; } return err; }
/// <summary> /// 写日志回调函数 /// </summary> /// <param name="level"></param> /// <param name="log"></param> /// <param name="len"></param> /// <returns></returns> private uint WriteLog(NLogLevel level, string log, int len) { NLog.Logger sotLog = NLog.LogManager.GetLogger("SoftTerminal"); NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(sotLog); try { switch (level) { case NLogLevel.Error: logEx.Error(log); break; case NLogLevel.Warn: logEx.Warn(log); break; case NLogLevel.Info: logEx.Info(log); break; case NLogLevel.Trace: logEx.Trace(log); break; default: break; } } catch (System.Exception ex) { logEx.Error(ex, "WriteLog Exception level:{0}, log:{1}.", level, log); } return 1; }
/// <summary> /// 初始化监控平台 /// </summary> /// <returns></returns> public SmcErr Load() { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Info("Enter: VideoMonitorManage.Load()"); SmcErr err = new CgwError(); XmlElement monitorsRootElement = ConfigSettings.MonitorSettings; if (monitorsRootElement == null) { err.SetErrorNo(CgwError.MONITOR_CONFIG_FILE_INVALID); logEx.Error("Monitor config file is invalid.Can not found monitorSettings node."); return err; } foreach (XmlNode monitorNode in monitorsRootElement) { XmlElement monitorElement = monitorNode as XmlElement; if (monitorElement == null) { continue; } else if (CgwConst.MONITOR_TAG.Equals(monitorElement.Name)) { //判断监控平台是否启用 string isEnable = monitorElement.GetAttribute(CgwConst.ENABLE_TAG).Trim(); if (!CgwConst.TRUE_TAG.Equals(isEnable.ToLower())) { logEx.Warn("This monitor is disable."); continue; } string monitorId; string className; err = GetMonitorConfig(monitorElement, out monitorId, out className); if (!err.IsSuccess()) { return err; } IVideoMonitor videoMonitor; //加载监控平台 err = CreateMonitor(monitorId, className, out videoMonitor); if (!err.IsSuccess()) { logEx.Error("Create monitor failed.monitorId:{0}, className:{1}, Error code:{2}", monitorId, className, err.ErrNo); return err; } err = videoMonitor.Load(monitorElement); if (err.IsSuccess()) { if (this.monitorsOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { monitorsDictionary.Add(monitorId, videoMonitor); } catch (Exception e) { logEx.Error("Load monitor failed.Execption message:{0}", e.Message); return err; } finally { this.monitorsOperateLock.ExitWriteLock(); } } } else { logEx.Error("Load monitor failed.MonitorId:{0},Error code:{1}", monitorId, err.ErrNo); return err; } } } logEx.Info("Load all monitors success."); return err; }
/// <summary> /// 停止预览 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <returns>成功返回0,失败返回错误码</returns> public SmcError.SmcErr StopReceiveVideo(string cameraNo) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: eLTEVideoMonitor.StopReceiveVideo({0}).", cameraNo); SmcErr err = new CgwError(); //需要停止的预览句柄 uint needToStopChannel = CgwConst.T28181_ERROR_HANDLE; if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoChannelDic.ContainsKey(cameraNo)) { needToStopChannel = this.cameraVideoChannelDic[cameraNo]; this.videoChannelDataSenderDic.Remove(needToStopChannel); this.cameraVideoChannelDic.Remove(cameraNo); //释放用户数据内存 foreach (KeyValuePair<UInt32, IntPtr> kvp in channelInPtrDic) { if (kvp.Key == needToStopChannel) { Marshal.FreeHGlobal(kvp.Value); channelInPtrDic.Remove(kvp.Key); break; } } //用户参数,4字节整数 IntPtr pUser = Marshal.AllocHGlobal(4); NetSourcedInterface.IVS_NETSOURCE_SetDataCallBack(needToStopChannel, null, pUser); //释放NETSOURCE通道资源 IVS_NETSOURCE_RESULT iNet = NetSourcedInterface.IVS_NETSOURCE_CloseNetStream(needToStopChannel); if (iNet != IVS_NETSOURCE_RESULT.SUCCESS) { logEx.Error("IVS_NETSOURCE_CloseNetStream failed channel={0}", needToStopChannel); err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); } iNet = NetSourcedInterface.IVS_NETSOURCE_FreeChannel(needToStopChannel); if (iNet != IVS_NETSOURCE_RESULT.SUCCESS) { logEx.Error("IVS_NETSOURCE_FreeChannel failed channel={0}", needToStopChannel); err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); } //关闭rtp回调 rtpAdapter.ESDK_RTP_CloseChannel(needToStopChannel); } else { logEx.Warn("Stop Receive camera video data failed. Don't need to end the preview.Camera No:{0}.", cameraNo); //如果预览句柄不存在,不需要处理,直接返回 return err; } } catch (Exception ex) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.Execption message:{0}", ex.Message); return err; } finally { this.handelOperateLock.ExitWriteLock(); } } //调用sdk的停止方法,放在handelOperateLock外面,防止长时间占用锁 if (needToStopChannel != CgwConst.T28181_ERROR_HANDLE) { ELTE_RESULT result = (ELTE_RESULT)this.lteSdkClient.StopP2PVideo(Convert.ToInt32(cameraNo)); //如果不为0,表示预览失败 if (result != ELTE_RESULT.RET_SUCCESS) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.eLTE sdk error code:{0}", result); return err; } logEx.Info("Stop Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, needToStopChannel); } return err; }
/// <summary> /// 停止预览 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <returns>成功返回0,失败返回错误码</returns> public SmcErr StopReceiveVideo(string cameraNo) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: IvsVideoMonitor.StopReceiveVideo({0}).", cameraNo); SmcErr err = new CgwError(); //需要停止的预览句柄 int needToStopHandel = CgwConst.START_RECEIVE_VIDEO_DATA_FAILED; if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoHandeDic.ContainsKey(cameraNo)) { needToStopHandel = this.cameraVideoHandeDic[cameraNo]; this.videoHandleCameraDic.Remove(needToStopHandel); this.cameraVideoHandeDic.Remove(cameraNo); } else { logEx.Warn("Stop Receive camera video data failed. Don't need to end the preview.Camera No:{0}.", cameraNo); //如果预览句柄不存在,不需要处理,直接返回 return err; } } catch (Exception ex) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.Execption message:{0}", ex.Message); return err; } finally { this.handelOperateLock.ExitWriteLock(); } } //调用sdk的停止方法,放在handelOperateLock外面,防止长时间占用锁 if (needToStopHandel != CgwConst.START_RECEIVE_VIDEO_DATA_FAILED) { int result = this.ivsSdkClient.StopRealPlay(needToStopHandel); //如果不为0,表示预览失败 if (result != CgwConst.IVS_SDK_SUCCESS_TAG) { err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Error("Stop Receive camera video data failed.Ivs sdk error code:{0}", result); return err; } logEx.Info("Stop Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, needToStopHandel); } return err; }
/// <summary> /// 获取本机ip /// </summary> /// <returns></returns> static private string GetLocalIP(string serverIP, int serverPort, int localPort) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: eLTEVideoMonitor.GetLocalIP()."); try { IPAddress serverAddress = IPAddress.Parse(serverIP); //IPAddress[] arrIPAddresses = Dns.GetHostAddresses(Dns.GetHostName()); IPAddress[] arrIPAddresses = Dns.GetHostAddresses(System.Environment.MachineName); foreach (IPAddress ip in arrIPAddresses) { if (serverAddress.AddressFamily.Equals(AddressFamily.InterNetwork) && ip.AddressFamily.Equals(serverAddress.AddressFamily)) { #region IPv4 IPEndPoint serverEndpoint = new IPEndPoint(serverAddress, serverPort); Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint clientEndpoint = new IPEndPoint(ip, localPort); socketClient.Bind(clientEndpoint); try { socketClient.Connect(serverEndpoint); if (socketClient.Connected) { logEx.Trace("eLTEVideoMonitor.try GetLocalIP ={0}.", ip.ToString()); return ip.ToString(); } else { logEx.Info("socketClient is not Connected."); } } catch (SocketException e) { logEx.Warn("eLTEVideoMonitor.GetLocalIP failed,e.ErrorCode:{0}", e.ErrorCode); if (e.ErrorCode == 10061 || e.ErrorCode == 10048) //Even No connection could be made because the target machine actively refused it ,but IP is valid. { logEx.Trace("eLTEVideoMonitor.catch GetLocalIP ={0}.", ip.ToString()); return ip.ToString(); } } finally { socketClient.Close(); logEx.Info("eLTEVideoMonitor.GetLocalIP finally,Close the socketClient success"); } #endregion } //如果serverIP为IPv6 else if (serverAddress.AddressFamily.Equals(AddressFamily.InterNetworkV6) && ip.AddressFamily.Equals(serverAddress.AddressFamily)) { #region IPV6 IPEndPoint serverEndpoint = new IPEndPoint(serverAddress, serverPort); Socket socketClient = new Socket(AddressFamily.InterNetworkV6, SocketType.Stream, ProtocolType.Tcp); IPEndPoint clientEndpoint = new IPEndPoint(ip, localPort); socketClient.Bind(clientEndpoint); try { socketClient.Connect(serverEndpoint); if (socketClient.Connected) { logEx.Trace("SipStackAdapter.try GetLocalIP ={0}.", ip.ToString()); return ip.ToString(); } } catch (SocketException e) { //logEx.Warn("SipStackAdapter.GetLocalIP failed,e.ErrorCode:{0}", e.ErrorCode); if (e.ErrorCode == 10061 || e.ErrorCode == 10048) //Even No connection could be made because the target machine actively refused it ,but IP is valid. { logEx.Trace("SipStackAdapter.catch GetLocalIP ={0}.", ip.ToString()); return ip.ToString(); } logEx.Error("SipStackAdapter.GetLocalIP failed.catch Execption message:{0}", e.Message); } finally { socketClient.Close(); logEx.Info("SipStackAdapter.GetLocalIP finally,Close the socketClient success"); } #endregion } } return null; } catch (System.Exception ex) { logEx.Error("eLTEVideoMonitor.GetLocalIP failed.serverIP={0},serverPort={1},localPort={2},Execption message:{0}", serverIP, serverPort, localPort, ex.Message); return null; } }
/// <summary> /// 初始化监控平台 /// </summary> /// <returns></returns> public SmcErr Load() { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Info("Enter: VideoMonitorManage.Load()"); SmcErr err = new CgwError(); XmlElement monitorsRootElement = ConfigSettings.MonitorSettings; if (monitorsRootElement == null) { err.SetErrorNo(CgwError.MONITOR_CONFIG_FILE_INVALID); logEx.Error("Monitor config file is invalid.Can not found monitorSettings node."); return(err); } foreach (XmlNode monitorNode in monitorsRootElement) { XmlElement monitorElement = monitorNode as XmlElement; if (monitorElement == null) { continue; } else if (CgwConst.MONITOR_TAG.Equals(monitorElement.Name)) { //判断监控平台是否启用 string isEnable = monitorElement.GetAttribute(CgwConst.ENABLE_TAG).Trim(); if (!CgwConst.TRUE_TAG.Equals(isEnable.ToLower())) { logEx.Warn("This monitor is disable."); continue; } string monitorId; string className; err = GetMonitorConfig(monitorElement, out monitorId, out className); if (!err.IsSuccess()) { return(err); } IVideoMonitor videoMonitor; //加载监控平台 err = CreateMonitor(monitorId, className, out videoMonitor); if (!err.IsSuccess()) { logEx.Error("Create monitor failed.monitorId:{0}, className:{1}, Error code:{2}", monitorId, className, err.ErrNo); return(err); } err = videoMonitor.Load(monitorElement); if (err.IsSuccess()) { if (this.monitorsOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { monitorsDictionary.Add(monitorId, videoMonitor); } catch (Exception e) { logEx.Error("Load monitor failed.Execption message:{0}", e.Message); return(err); } finally { this.monitorsOperateLock.ExitWriteLock(); } } } else { logEx.Error("Load monitor failed.MonitorId:{0},Error code:{1}", monitorId, err.ErrNo); return(err); } } } logEx.Info("Load all monitors success."); return(err); }
/// <summary> /// rtp码流回调处理 /// </summary> /// <param name="pBuf">帧数据字节数组</param> /// <param name="pFrameData">帧数据类型</param> /// <param name="uiChannel">通道</param> /// <param name="uiBufSize">帧数据字节数组长度</param> private void FrameDataCallBackFun(IntPtr pBuf, uint uiBufSize, ref ST_FRAME_DATA pFrameData, uint uiChannel) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); ST_FRAME_DATA frameData = pFrameData; MediaDataSender mediaDataSender = null; if (this.handelOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.videoChannelDataSenderDic.ContainsKey(uiChannel)) { mediaDataSender = this.videoChannelDataSenderDic[uiChannel]; } } finally { this.handelOperateLock.ExitReadLock(); } } if (mediaDataSender == null) { logEx.Warn("FrameDataCallBackFun mediaDataSender = NULL"); return; } StreamType streamType = StreamType.VIDEO_H264; //对于支持的码流类型,用break退出switch,对于不支持的码流类型直接舍弃,用return返回 switch (frameData.iStreamType) { //对于音频只接收G711A和G711U,其他舍弃 case (int)IvsStreamType.PAY_LOAD_TYPE_PCMU: streamType = StreamType.AUDIO_G711U; break; case (int)IvsStreamType.PAY_LOAD_TYPE_PCMA: streamType = StreamType.AUDIO_G711A; break; //只接收H264的视频码流 case (int)IvsStreamType.PAY_LOAD_TYPE_H264: //H264的标准视频流,作为视频流处理 streamType = StreamType.VIDEO_H264; break; default: //不支持的类型,直接舍弃,返回 logEx.Warn("FrameDataCallBackFun.iStreamType is not valid"); return; } if (streamType == StreamType.AUDIO_G711A || streamType == StreamType.AUDIO_G711U) { //如果是音频流,需要判断mic的状态,开启时才发送音频流 if (this.micOperateLock.TryEnterReadLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraMicStatusDic.ContainsKey(mediaDataSender.CameraNo)) { //如果mic为非开启状态,则不发送音频码流, if (!this.cameraMicStatusDic[mediaDataSender.CameraNo]) { // logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } else { //默认为关闭状态,因此如果cameraMicStatusDic不包含该摄像头,则认为处于关闭状态,舍弃音频码流 // logEx.Warn("This data is audio,but the mic is off.Chuck the data.Camera no:{0}", mediaDataSender.CameraNo); return; } } finally { this.micOperateLock.ExitReadLock(); } } } try { MediaData mediaData = new MediaData(); //获取非托管的数据 byte[] datagram = new byte[uiBufSize]; Marshal.Copy(pBuf, datagram, 0, (int)uiBufSize); //视频数据增加头信息 if (!(streamType == StreamType.AUDIO_G711A || streamType == StreamType.AUDIO_G711U)) { //头部增加四个四节的开始表实0x000001 byte[] newDatagram = new byte[uiBufSize + 4]; datagram.CopyTo(newDatagram, 4); newDatagram[3] = 1; mediaData.Data = newDatagram; mediaData.Size = (uint)(uiBufSize + 4); } else { mediaData.Data = datagram; mediaData.Size = (uint)(uiBufSize); } //裸码流 mediaData.DataType = MediaDataType.FRAME_DATA; mediaData.StreamType = streamType; //将帧类型转换成各融合网关统一的帧类型 string name = Enum.GetName(typeof(IvsH264NaluType), frameData.iFrameDataType); if (Enum.IsDefined(typeof(FrameDataType), name)) { FrameDataType frameDataType = (FrameDataType)Enum.Parse(typeof(FrameDataType), name); mediaData.FrameType = frameDataType; } else { mediaData.FrameType = FrameDataType.H264_NALU_TYPE_UNDEFINED; logEx.Warn("eLTE FrameDataCallBackFun FrameType is Not Defined, FrameType:{0}", frameData.iFrameDataType); } //logEx.Debug("FrameDataCallBackFun.mediaData.DataType={0},FrameType = {1},StreamType = {2},Size = {3}", Enum.GetName(typeof(MediaDataType), mediaData.DataType), // Enum.GetName(typeof(FrameDataType), mediaData.FrameType), Enum.GetName(typeof(StreamType), mediaData.StreamType), mediaData.Size); //向回调函数转发码流 mediaDataSender.SendData(mediaData, this.sender); } catch (System.Exception ex) { logEx.Error("FrameDataCallBackFun failed.Execption message:{0}", ex.Message); } }
/// <summary> /// 发起视频回传成功后,在状态变化事件中处理视频接收、P2Pvideocall_IND_STATUS_ANSWERED时开始接收视频数据 /// </summary> /// <param name="structResStaIndi"></param> private void P2pStatusDelegateFun(ref strP2pvideocallStatusIndicator structP2pvideocallStaIndi) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Info("Enter: P2pStatusDelegateFun.strP2pvideocallStatusIndicator.Status = {0},Callee = {1}", Enum.GetName(typeof(P2pvideocall_Status_t), structP2pvideocallStaIndi.Status), structP2pvideocallStaIndi.Callee); //P2Pvideocall_IND_STATUS_ANSWERED,表示视频回传请求被成功处理处理 //视频网关需要提取其中的RTP port和对端IP,并负责与摄像头建立RTP连接和读取RTP中的H.264的视频流,然后再调用上层的视频管理系统或视频监控系统中的API //视频从摄像头回传,通过视频网关传入到上层的视频管理系统或视频监控系统 if (structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_ANSWERED) { //摄像机编码 int cameraNo = structP2pvideocallStaIndi.Callee; //源端发送码流IP; string pRemoteSendStreamIp = ip; //源端发送视频码流RTP端口号 uint uiRemoteSendStreamVideoPort = (uint)structP2pvideocallStaIndi.RemoteVideoPort; //源端发送音频端口号 uint uiRemoteSendStreamAudioPort = (uint)structP2pvideocallStaIndi.RemoteAudioPort; //本地视频、音频端口 uint uiLocalAudioPort = (uint)structP2pvideocallStaIndi.CalAudioPort; uint uiLocalVideoPort = (uint)structP2pvideocallStaIndi.LocalVideoPort; //发起视频回传,建立成功 logEx.Trace("P2pStatusDelegateFun.Camera = {0},pRemoteSendStreamIp ={1},uiRemoteSendStreamVideoPort = {2},uiRemoteSendStreamAudioPort ={3},uiLocalAudioPort ={4} ,uiLocalVideoPort ={5} P2Pvideocall_IND_STATUS_ANSWERED OK!", cameraNo, pRemoteSendStreamIp, uiRemoteSendStreamVideoPort, uiRemoteSendStreamAudioPort, uiLocalAudioPort, uiLocalVideoPort); if (uiRemoteSendStreamVideoPort == 0) { logEx.Warn("P2pvideocallStatus uiRemoteSendStreamVideoPort is NULL"); return; } //打开通道,开始接收实况RTP数据流 UInt32 channel = StartRecvStream(cameraNo.ToString(), pRemoteSendStreamIp, uiRemoteSendStreamVideoPort, uiRemoteSendStreamAudioPort == 0 ? uiRemoteSendStreamVideoPort : uiRemoteSendStreamAudioPort, uiLocalVideoPort, uiLocalAudioPort == 0 ? uiLocalVideoPort : uiLocalAudioPort); //如果为0,表示预览失败 if (channel == CgwConst.T28181_ERROR_HANDLE) { logEx.Error("Start Receive camera video data failed.Camera No:{0}.", cameraNo); return; } else { logEx.Info("Start Receive camera video data success.Camera No:{0}", cameraNo); } if (this.videoAutOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (videoAutoEvents.ContainsKey(cameraNo.ToString())) { videoAutoEvents[cameraNo.ToString()].VideoSuccess = true; videoAutoEvents[cameraNo.ToString()].eLTEVideoEvent.Set(); logEx.Trace("P2pStatusDelegateFun AutoResetEvent State Set,StartVideo Success"); } } finally { this.videoAutOperateLock.ExitWriteLock(); } } //设置rtp解析回调函数 rtpAdapter.ESDK_RTP_OpenESChannel(frameDataCallBack, channel); if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { this.cameraVideoChannelDic.Add(cameraNo.ToString(), channel); MediaDataSender mediaDataSender = new MediaDataSender(cameraNo.ToString(), this.dataCallBack); this.videoChannelDataSenderDic.Add(channel, mediaDataSender); } finally { this.handelOperateLock.ExitWriteLock(); } } } else if (P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_HANGUPED == structP2pvideocallStaIndi.Status || P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_RELEASED == structP2pvideocallStaIndi.Status || P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_CANCELLED == structP2pvideocallStaIndi.Status) { //2015/3/6 设置信号量不阻塞 if (videoAutOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { int cameraNo = structP2pvideocallStaIndi.Callee; if (videoAutoEvents.ContainsKey(cameraNo.ToString())) { videoAutoEvents[cameraNo.ToString()].VideoSuccess = true; videoAutoEvents[cameraNo.ToString()].eLTEVideoEvent.Set(); logEx.Trace("P2pStatusDelegateFun AutoResetEvent State Set,StartVideo End"); } } finally { this.videoAutOperateLock.ExitWriteLock(); } } //收到呼叫被结束事件、需要停止RTP传输并关闭RTP连接 StopReceiveVideo(structP2pvideocallStaIndi.Callee.ToString()); } //2015/2/5 设备播放失败的错误码状态 else if (structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_REMOTE_NOTCONNECTED || structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_REMOTE_NOTSUPPORTED || structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_REMOTE_NOANSWER || structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_REMOTE_NOTFOUND || structP2pvideocallStaIndi.Status == P2pvideocall_Status_t.P2Pvideocall_IND_STATUS_RELEASED_BUSY ) { if (this.videoAutOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { //摄像机编码 int cameraNo = structP2pvideocallStaIndi.Callee; if (videoAutoEvents.ContainsKey(cameraNo.ToString())) { videoAutoEvents[cameraNo.ToString()].VideoSuccess = false; videoAutoEvents[cameraNo.ToString()].eLTEVideoEvent.Set(); logEx.Trace("P2pStatusDelegateFun AutoResetEvent State Set,StartVideo Remote Failed"); } } finally { this.videoAutOperateLock.ExitWriteLock(); } } } }
/// <summary> /// 断开监控管理连接 /// </summary> /// <returns></returns> public SmcErr Disconnect() { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); SmcErr err = new CgwError(); if (OperationContext.Current != null) { //string strSessionId = OperationContext.Current.SessionId; string strSessionId = currentSessionID; if (!string.IsNullOrEmpty(strSessionId)) { err = SessionManage.Instance().RemoveSessionBySessionId(strSessionId); logEx.Info("Client DisConnect MonitorManageService Successful,Current.Cgw IP is : {0}", CgwConst.ClientIp); } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_CURRENTSESSION_NULL); logEx.Warn("Current SessionId is null ! "); } } else { err.SetErrorNo(CgwError.ERR_CGW_BUSINESS_CURRENTSESSION_NULL); logEx.Warn("Current SessionId is null ! "); } return err; }
/// <summary> /// 停止预览 /// </summary> /// <param name="cameraNo">摄像头编号</param> /// <returns>成功返回0,失败返回错误码</returns> public SmcErr StopReceiveVideo(string cameraNo) { NLogEx.LoggerEx logEx = new NLogEx.LoggerEx(log); logEx.Trace("Enter: TiandyVideoMonitor.StopReceiveVideo({0}).", cameraNo); SmcErr err = new CgwError(); //需要停止的预览句柄 int needToStopHandel = CgwConst.START_RECEIVE_VIDEO_DATA_FAILED; if (this.handelOperateLock.TryEnterWriteLock(CgwConst.ENTER_LOCK_WAIT_TIME)) { try { if (this.cameraVideoHandeDic.ContainsKey(cameraNo)) { needToStopHandel = this.cameraVideoHandeDic[cameraNo]; this.videoHandleCameraDic.Remove(needToStopHandel); this.cameraVideoHandeDic.Remove(cameraNo); } else { //不存在,表示已经删除,不返回错误 //err.SetErrorNo(CgwError.STOP_RECEIVE_VIDEO_FAILED); logEx.Warn("Stop Receive camera video data failed. Don't need to end the preview.Camera No:{0}.", cameraNo); } } finally { this.handelOperateLock.ExitWriteLock(); } } //调用sdk的停止方法,放在handelOperateLock外面,防止长时间占用锁 if (needToStopHandel != CgwConst.START_RECEIVE_VIDEO_DATA_FAILED) { this.sdkClient.StopReceiveVideo(needToStopHandel); } logEx.Info("Stop Receive camera video data success.Camera No:{0},Handle:{1}.", cameraNo, needToStopHandel); return err; }