## 一、前言
如果
网络环境正常设备正常,
视频监控
系统一般都是按照正常运行下去,不会出现什么
问题,但是实际情况会很不同,奇奇怪怪七七八八的问题都会出现,就比如网络出了问题都有很多情况(交换机故障、网线故障、带宽故障等),所以监控系统在运行过程中,还得做超时检测,超过规定的时间
没有收到
数据则认为掉线了,需要重连,超时检测有两个地方需要,一个是打开的时候,因为受限于网络等,默认超时时间是30s太久,在打开之前,可以做个简单的连接探测是否地址通,不通就不用继续;另一个地方就是实时采集过程中,也要能够及时识别到,防止一直在那边死循环的读取。
在上面超过检测后,一般都是更新最后的收到数据的时间,然后自动重连的机制就是在
线程中判断这个最后接收数据的时间和当前时间比较,超过了设定的超时时间,则认为掉线,关闭视频,如果还设置了自动重连属性,则先关闭再去重新打开,务必记得关闭的时候及时释放所有的资源,不然内存会一直增长。封装后的视频流控件自带了自动重连的机制,这样用户再使用的时候不用管如何重连,只需要开启自动重连属性即可,默认开,还有一种情况可能要关闭自动重连属性,比如播放本地视频
文件,有时候只需要播放一次就行,不需要播放完成以后又重新播放,如果确实需要,则关联播放完毕信号自行重新open即可。
## 二、效果图
## 三、体验地址
1. 国内站点:[
https://gitee.com/feiyangqingyun](https://gitee.com/feiyangqingyun)
2. 国际站点:[
https://github.com/feiyangqingyun](https://github.com/feiyangqingyun)
3. 个人作品:[
https://blog.csdn.net/feiyangqingyun/article/details/97565652](https://blog.csdn.net/feiyangqingyun/article/details/97565652)
4. 体验地址:[
https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g](https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g) 提取码:01jf 文件名:bin_video_demo/bin_linux_video。
## 四、相关代码
```cpp
void VideoThread::checkOpen()
{
//特意每次做个小延时每次都去判断标志位等可以大大加快关闭速度
int count = 0;
int maxCount = openSleepTime / 100;
while (!stopped) {
msleep(100);
count++;
//测试下来正常情况下基本上等待一次后 isOk=true
if (count == maxCount || isOk) {
break;
}
}
}
void VideoThread::run()
{
while (!stopped) {
if (!isOk) {
this->closeVideo();
if (videoMode == VideoMode_Hwnd) {
QMetaObject::invokeMethod(this, "openVideo");
} else {
this->openVideo();
}
this->checkOpen();
continue;
}
if (videoCore == VideoCore_Vlc) {
if (videoWidth <= 0 && !getOnlyAudio()) {
//视频文件需要尝试读取媒体信息多次保证能够读取到(一般视频流需要多次才能读取到)
this->readMediaInfo();
}
} else if (videoCore == VideoCore_HaiKang) {
if (videoType == VideoType_FileLocal) {
//本地文件需要这里实时读取播放进度
this->getPosition();
} else if (isOk && videoMode == VideoMode_Hwnd) {
//句柄模式下视频流如果打开正常了则sdk内部处理重连
lastTime = QDateTime::currentDateTime();
}
} else if (videoCore == VideoCore_EasyPlayer) {
if (videoWidth <= 0) {
this->readMediaInfo();
}
this->getPosition();
}
//启用了自动重连则通过判断最后的消息时间(超时则重新打开)
if (readTimeout > 0) {
qint64 offset = lastTime.msecsTo(QDateTime::currentDateTime());
if (offset >= readTimeout) {
isOk = false;
debug("超时重连", "");
continue;
}
}
msleep(100);
}
//关闭视频
this->closeVideo();
//文件名为空才说明真正处理完可以彻底结束线程(否则一直等因为有可能文件还没保存完成)
while (!fileName.isEmpty()) {
debug("等待完成", "");
msleep(5);
}
debug("线程结束", "");
}
```