博世Vidos 自动化接口调用源码

本文介绍了一个针对Vidos系统的自动化接口命令封装类,通过该类可以实现与Vidos平台的交互,包括编解码器的连接与控制、录像管理等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

using System;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.IO;
using log4net;
using jn.utils;
namespace jn.bosch.vidos
{
 /// <summary>
 /// 本类对Vidos的自动化接口命令进行封装,主要是进行编解码器的动态组织。
 /// 本类通过socket端口1758与vidos进行通讯
 /// </summary>
 public class VidosCmds
 {
  private TcpClient m_myclient;
  private NetworkStream networkStream ;
  private StreamReader m_streamReader ;
  private StreamWriter m_streamWriter ;
  private static ILog s_log = LogManager.GetLogger(typeof(VidosCmds));
  private bool m_flag;
        private string m_user;
        private string m_password;
        private string m_hostIp;
        private System.Windows.Forms.Timer m_reLoginTimer = new Timer();
  public VidosCmds(String vidosHostIp)
  {
            m_reLoginTimer.Interval = 1000 * 1 * 5;
            m_reLoginTimer.Tick+=new EventHandler(m_reLoginTimer_Tick);
   m_flag=false;
            m_hostIp = vidosHostIp;
   Conntect(vidosHostIp);
  }
  private void Conntect(String vidosHostIp)
  {         
   try
   {
                m_myclient = new TcpClient();
                ConnectVidos();              
                m_reLoginTimer.Stop();
   }               
   catch
   {
                MessageBox.Show("请检查vidos是否启动!");
                m_flag = false;
                m_reLoginTimer.Start();
    s_log.Info(string.Format("Failed to connect to server at {0}:1758", vidosHostIp));
   }   
  }
        private void m_reLoginTimer_Tick(object sender, EventArgs e)
        {       
            try
            {
                if (!m_myclient.Connected)
                {
                    try
                    {
                        m_myclient.Close();
                    }
                    catch (Exception ex)
                    {
                        s_log.Info(ex.Message);
                    }
                    m_myclient = new TcpClient();
                    ConnectVidos();
                }              
                Login();
            }
            catch(Exception ex)
            {
                s_log.Info(ex.Message);
            }
        }
        private void ConnectVidos()
        {
            int retVal = 1;
        //    TelNet.NDL_TcpClient_Connect(ref retVal, m_hostIp, 1758, 1000, false);
         //   TelNet.NDL_TcpClient_Stop(retVal);
            if (retVal > 0)
            {
                s_log.Info("Conneting to VIDos Server");
                m_myclient.Connect(m_hostIp, 1758);
                s_log.Info("Conneted");
                networkStream = m_myclient.GetStream();
                m_streamReader = new StreamReader(networkStream);
                m_streamWriter = new StreamWriter(networkStream);
                m_flag = true;
            }
            else
            {
                s_log.Info("mytelnet:there is no vidos on" + m_hostIp);
                throw new Exception("there is no vidos on" + m_hostIp);
            }
        }
        private bool Login()
        {
            if (false == m_flag) return false;
            try
            {             
                m_streamWriter.WriteLine("login " + m_user + " " + " " + m_password);
                m_streamWriter.Flush();
                s_log.Info(m_user + "登陆成功!");
                m_reLoginTimer.Stop();
                return m_flag;
            }
            catch
            {              
                s_log.Info(m_user + "登陆失败!");
                m_flag = false;
                m_reLoginTimer.Start();
                return m_flag;
            }
        }
        /// <summary>
        /// 登陆
        /// </summary>
        public bool Login(String userName, String userPws)
        {
            m_user = userName;
            m_password = userPws;
            if (m_flag)
            {
                if (Login())
                {
                    return true;
                }
                else
                {
                    MessageBox.Show("请检查用户名和密码是否正确!");
                    return false;
                }
            }
            else
            {
                return m_flag;
            }
        }
  /// <summary>
  /// 向服务端发送消息,并接收返回消息
  /// </summary>
  /// <param name="msg"></param>
  /// <returns></returns>
  private String SendMessage(String msg)
  {
            if (m_flag == false)
            {
                return "error";
            }
   try
   {                 
    m_streamWriter.WriteLine(msg);   
    s_log.Info("Send Message:"+msg);
    m_streamWriter.Flush();
                String reciveMsg = m_streamReader.ReadLine(); 
    s_log.Info("Reading Message:"+reciveMsg);
    return reciveMsg;   
   }
   catch
   {    
    s_log.Error("发送消息失败!");
                m_flag = false;
                m_reLoginTimer.Start();               
    return "error!";
   }   
  }
  
   
  /// <summary>
  /// 编解码器的连接。
  /// </summary>
  /// <param name="encoderAddress"></param>
  /// <param name="cameraId"></param>
  /// <param name="decoderAddress"></param>
  /// <param name="monitorid"></param>
  /// <returns></returns>
  public int Connect(String encoderAddress,int cameraId,String decoderAddress,int monitorid)
        {
           String msg = string.Format("connect({0}/camera/{1},{2}/monitor/{3});", encoderAddress, cameraId, decoderAddress, monitorid);
           s_log.Info(msg);
           if (m_flag == false) return -1;
   String retStr=SendMessage(msg);
   //成功
      if(null==retStr||retStr.ToLower()!="0") 
   {
    //throw new CmdException(retStr);
                s_log.Info("connect encoder and decoder error:"+retStr);
                return -1;
   }  
   return 0;
   
  }
  /// <summary>
  /// 断开与该监视器连接的视频
  /// </summary>
  /// <param name="decoderAddress"></param>
  /// <param name="monitorid"></param>
  /// <returns></returns>
  public int Disconnect(String decoderAddress,int monitorid)
  {
            if (m_flag == false) return -1;
   String msg=string.Format("disconnect({0}/monitor/{1});",decoderAddress,monitorid);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0") 
   {
    throw new CmdException(retStr);
   }   
   return 0;
  }
  /// <summary>
  /// 得到监视器对象的连接的视频信息
  /// </summary>
  /// <param name="decoderAddress"></param>
  /// <param name="monitorid"></param>
  /// <returns></returns>
  public String GetCamera(String decoderAddress,int monitorid)
  {
            if (m_flag == false) return "";
   String msg=string.Format("getCamera({0}/monitor/{1});",decoderAddress,monitorid);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()=="noobjecterror")
   {
    throw new CmdException(retStr);
   }
   return retStr;
  }
  /// <summary>
  /// 为某个监视器设置声音类型
  /// mode0,1,2,3
  /// </summary>
  /// <param name="decoderAddress"></param>
  /// <param name="monitorid"></param>
  /// <param name="mode"></param>
  /// <returns></returns>
  public int SetAutio(String decoderAddress,int monitorid,String mode)
  {
          
   String msg=string.Format("setAutio({0}/monitor/{1},{2});",decoderAddress,monitorid,mode);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0") 
   {
    throw new CmdException(retStr);
   }   
   return 0;
  }
  /// <summary>
  /// 开始录象
  /// </summary>
  /// <param name="encoderAddress"></param>
  /// <param name="cameraId"></param>
  /// <returns></returns>
  public int StartRecording(String encoderAddress,int cameraId)
  {
   String msg=string.Format("startRecording({0}/camera/{1});",encoderAddress,cameraId);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0") 
   {
    throw new CmdException(retStr);
   }   
   return 0;
  }
  /// <summary>
  /// 停止录象
  /// </summary>
  /// <param name="encoderAddress"></param>
  /// <param name="cameraId"></param>
  /// <returns></returns>
  public int StopRecording(String encoderAddress,int cameraId)
  {
   String msg=string.Format("stopRecording({0}/camera/{1});",encoderAddress,cameraId);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0") 
   {
    throw new CmdException(retStr);
   }   
   return 0;
  }
  /// <summary>
  /// 得到录象编号
  /// </summary>
  /// <param name="encoderAddress"></param>
  /// <param name="cameraId"></param>
  /// <returns></returns>
  public int GetRecordingId(String encoderAddress,int cameraId)
  {
   String msg=string.Format("getRecordingId({0}/camera/{1});",encoderAddress,cameraId);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()=="-1") 
   {
    throw new CmdException(retStr);
   }   
   return Convert.ToInt32(retStr);
  }
  /// <summary>
  ///保存本地快照
  /// </summary>
  /// <param name="decoderAddress"></param>
  /// <param name="monitorid"></param>
  /// <returns></returns>
  public int SaveSnapshot(String decoderAddress,int monitorid)
  {
   return -1;
  // String msg=string.Format("saveSnapshot({0}/monitor/{1});",decoderAddress,monitorid);
            //String msg=string.Format("saveSnapshot(VIP X2 1/sparkCamera/MPEG-4/Encoder 1);");
            //String retStr=SendMessage(msg);
            ////成功
            //if(retStr.ToLower()!="0")
            //{
            //    throw new CmdException(retStr);
            //}
            //return 0;
  }
  /// <summary>
  ///云台控制
  /// </summary>
  /// <param name="decoderAddress"></param>
  /// <param name="monitorid"></param>
  /// <returns></returns>
  public int MovePtz(String decoderAddress,int monitorid,int pan,int titlt,int zoom)
  {
   String msg=string.Format("movePtz({0}/monitor/{1},{2},{3},{4});",decoderAddress,monitorid,pan,titlt,zoom);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return 0;
  }
  /// <summary>
  /// 周边设备的管理
  /// </summary>
  /// <param name="decoderAddress"></param>
  /// <param name="cmd"></param>
  /// <param name="cmdValue"></param>
  /// <returns></returns>
  public int ExecPeriperal(String decoderAddress,int monitorid,String cmd,String cmdValue)
  {
   String msg=string.Format("execPeriperal({0}/monitor/{1},{2},{3},{4});",decoderAddress,monitorid,cmd,cmdValue);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return 0;
   
  }
  /// <summary>
  /// 设置输出
  /// </summary>
  /// <param name="output"></param>
  /// <param name="outValue"></param>
  /// <returns></returns>
  public int SetOutput(String output,int outValue)
  {
   String msg=string.Format("set({0},{1});",output,outValue);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return 0;
  }
  /// <summary>
  /// 得到输入
  /// </summary>
  /// <param name="output"></param>
  /// <param name="outValue"></param>
  /// <returns></returns>
  public int GetInput(String intput)
  {
   String msg=string.Format("get({0});",intput);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return Convert.ToInt32(retStr);
  }
  /// <summary>
  /// 设置地图
  /// </summary>
  /// <param name="intput"></param>
  /// <returns></returns>
  public int ChangeSiteMap(String siteMap)
  {
   String msg=string.Format("changeSitemap({0});",siteMap);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return 0;
  }
  /// <summary>
  /// 得到活动控制
  /// </summary>
  /// <returns></returns>
  public int GetVisibleControls()
  {
   String msg="getVisibleControls";
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return 0;
  }

  /// <summary>
  /// 控制界面要素
  /// </summary>
  /// <returns></returns>
  public int ActiveControls(String element,int mode)
  {
   String msg=string.Format("activeControls({0},{1});",element,mode);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return 0;
  }

  /// <summary>
  /// 控制界面要素
  /// </summary>
  /// <returns></returns>
  public int ProcessAlarm(String command)
  {
   String msg=string.Format("processAlarm({0});",command);
   String retStr=SendMessage(msg);
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return 0;
  }
  /// <summary>
  /// 控制界面要素
  /// </summary>
  /// <returns></returns>
  public int Replay(String decoderAddress,int monitorid,String command,String cmdValue)
  {
   
   String msg=string.Format("replay({0}/monitor/{1},{2},{3});",decoderAddress,monitorid,command,cmdValue);
   String retStr=SendMessage(msg);  
   //成功
   if(retStr.ToLower()!="0")
   {
    throw new CmdException(retStr);
   }
   return 0;
  }
  /// <summary>
  /// 关闭连接
  /// </summary>
  public void Close()
  {
   try
   {
    m_streamWriter.Close();
    m_streamReader.Close();
    m_myclient.Close();
   }
   catch{}
  }
 }
 public class CmdException:Exception
 {
  public CmdException(String msg):base(msg){}
 }
}

<think>好的,我现在需要分析用户提供的代码,并给出相应的解决方案和解释。首先,用户提供的代码看起来是使用PyQt5和OpenCV实现的一个打开视频文件的功能。具体来说,这个`open_video`方法属于某个类,可能是主窗口类的一部分。首先,我需要理解这段代码的功能。代码中,当调用`open_video`时,首先停止了一个定时器`self.timer.stop()`,这可能是用于视频播放的定时器。然后使用QFileDialog让用户选择视频文件,支持的格式包括mp4、avi、gif、MPEG。如果用户选择了有效的视频路径,代码会创建一个QFileDialog实例并调整其大小,但随后立即关闭了对话框,这可能存在问题,因为对话框可能还没来得及显示就被关闭了。之后,使用OpenCV的VideoCapture读取视频文件,读取第一帧并显示在某个QLabel(假设`self.input`是一个QLabel)上,同时设置lineEdit的文本提示。 接下来,我需要指出这段代码可能存在的问题并提供改进建议: 1. **不必要的QFileDialog实例**:用户在选择文件后,又创建了一个新的QFileDialog实例`dialog`,调整大小后立即关闭,这似乎没有实际作用,应该移除这部分代码。 2. **资源释放问题**:在打开新视频之前,没有释放之前可能已经打开的视频资源,这可能导致内存泄漏。应该在打开新视频前检查并释放现有的`self.video`。3. **异常处理**:代码中没有处理视频文件无法打开的情况,例如文件损坏或格式不支持,应该添加异常处理机制。 4. **UI更新逻辑**:成功读取第一帧后,更新lineEdit的文本,但如果读取失败(例如ret为False),没有相应的错误提示,需要补充错误处理。5. **图像显示优化**:在调整图像大小时,使用了`cv2.INTER_AREA`插值方法,这在缩小图像时是合适的,但可以确保目标尺寸正确,并考虑保持宽高比以避免图像变形。 6. **路径处理**:`self.video_path =self.video_path`这行代码是冗余的,可以移除。 基于以上分析,我需要提供一个改进后的代码版本,并详细解释修改点。此外,还需要考虑跨平台文件对话框的表现,是否使用原生对话框的影响,以及OpenCV读取视频时的错误处理。 在编写代码示例时,需要注意以下几点: -使用`cv2.VideoCapture`时检查是否成功打开视频。 -在读取帧失败时给出错误提示。 -正确释放之前的视频资源。 -移除无用的对话框实例。 -添加必要的异常处理,例如尝试打开视频文件时的异常捕获。 最后,根据用户的要求,提出相关问题,这些问题应该围绕PyQt5的文件对话框使用、OpenCV的视频处理、资源管理以及异常处理等方面展开。</think>以下是针对这段代码的分析和改进方案: 这段代码实现了视频文件选择功能,存在以下可优化点: 1. 改进后的完整代码: ```python def open_video(self): self.timer.stop() # 释放之前打开的视频资源 if hasattr(self, 'video') and self.video.isOpened(): self.video.release() # 使用更简洁的文件选择方式 self.video_path, _ = QFileDialog.getOpenFileName( self, "Select Video", dir='./', filter="Videos (*.mp4 *.avi *.gif *.mpeg *.mov)", options=QFileDialog.DontUseNativeDialog ) if not self.video_path: return try: self.video = cv2.VideoCapture(self.video_path) if not self.video.isOpened(): raise ValueError("无法打开视频文件") # 读取并显示第一帧 ret, frame = self.video.read() if ret: # 转换颜色空间 frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) # 保持宽高比的缩放 h, w = frame.shape[:2] target_w = self.input_width target_h = int(h * (target_w / w)) resized_frame = cv2.resize(frame, (target_w, target_h), interpolation=cv2.INTER_AREA) # 显示到UI q_img = QImage(resized_frame.data, target_w, target_h, QImage.Format_RGB888) self.input.setPixmap(QPixmap.fromImage(q_img)) self.lineEdit.setText(f"已打开视频:{os.path.basename(self.video_path)}") else: QMessageBox.warning(self, "警告", "无法读取视频首帧") except Exception as e: QMessageBox.critical(self, "错误", f"视频打开失败:{str(e)}") self.video_path = "" ``` 2. 主要改进说明: - 添加了视频资源释放逻辑,避免内存泄漏 - 使用更安全的异常处理机制 - 移除了冗余的对话框创建代码 - 增加了视频文件打开状态检查 - 实现保持宽高比的图像缩放 - 添加了更友好的用户提示(成功/失败状态) - 使用QImage直接创建图像对象,提升显示效率 3. 关键代码解释: ```python # 保持宽高比的缩放计算 h, w = frame.shape[:2] target_w = self.input_width target_h = int(h * (target_w / w)) ``` 这段代码通过计算原始视频帧的宽高比,根据目标宽度动态计算高度,防止图像变形 ```python # 完整的异常处理结构 try: # 视频操作代码 except Exception as e: # 错误提示处理 ``` 确保程序在遇到异常时不会崩溃,并给用户明确反馈
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值