Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to realize General Channel Management with Qt Audio and Video Development

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article focuses on "how to use Qt audio and video development to achieve general channel management", interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let the editor take you to learn "how to use Qt audio and video development to achieve general channel management"!

I. Preface

After the general video control is done, it is much more convenient to add a new kernel in the later stage, and there is no need to copy and paste many files. The next step is to need a unified class to manage 16 channels or 32 channels in the video surveillance system, or even 64 channels. Of course, general channel management is also compatible with various monitoring kernels. In the past, channel management classes were written one for each kernel, which was also very tedious. A lot of repetitive code, so after sorting out the general video surveillance control, it is natural to modify this general channel management class.

The requirement of general channel management comes from the actual development process, such as disconnection reconnection mechanism. Although each video surveillance control has its own disconnection reconnection function, extreme situations are easy to occur. For example, after the network is down, the device will be online again, and all of them will be online in an instant (if the set timeout is the same). This will put a lot of pressure on CPU, and it will soar in an instant. Therefore, a class is needed to manage all the camera devices, and he is responsible for queuing disconnected and reconnecting, loading and opening devices, unified screenshot mechanism, and unified video storage mechanism.

Basic functions of channel management:

Sets the address collection (either a configuration file read or a database read), a name collection, and a control collection.

All channels or specify the opening and closing of channels.

A screenshot of the specified channel.

Set the number of video channels and timeout.

Set the interval between opening the video and reconnecting the video.

Specify the video storage interval and storage folder.

II. Functional features

Supports multi-screen switching, full-screen switching, etc., including 1 "4" 6 "8" 9 "13" 16 "25" 36 "64 screen switching.

Support alt+enter full screen, esc exit full screen.

Custom message box + error box + inquiry box + prompt box in the lower right corner (including multiple formats).

17 sets of skin styles are changed at will, all styles are unified, including menus and so on.

The head dashboard mouse moves up to highlight, and eight directions are accurately identified.

The bottom screen toolbar (screen division switch + screenshot sound, etc.) is moved up to highlight.

You can change the logo+ Chinese software name + English software name in the upper left corner of the configuration file.

Encapsulated Baidu map, view switching, motion trajectory, equipment location, mouse press to obtain longitude and latitude and so on.

Support picture map, the device button can drag freely on the picture map to automatically save location information.

On Baidu Maps and Picture Maps, double-click the video to preview the camera real-time video.

Stack forms, each form is a separate qwidget, making it easy to write your own code.

Top right mouse button menu, can dynamically control the time CPU+ upper left corner panel + lower left corner panel + upper right corner panel + lower right corner panel show and hide, support to restore the default layout.

Toolbars can place multiple small icons and close icons.

The left side and the right side can be dragged and stretched, and the width and height position can be automatically remembered and restored after restart.

Double-click the camera node to automatically play the video, double-click the node to automatically add videos in turn, automatically jump to the next one, and double-click the parent node to automatically add all the videos under that node.

The camera node is dragged to the corresponding form to play the video, and the local file can be dragged to play directly.

The video screen form supports dragging and swapping and instant response.

Double-click the node + drag the node + drag the form to change the position, and the url.txt is automatically updated.

Support loading channel video playback from url.txt, automatically memorizing the video corresponding to the last channel, and automatically opening and playing after the software starts.

Lower right corner volume bar control, lose focus automatically hide, volume bar with mute icon.

Integrate Baidu online map and offline map, you can add the corresponding location of the device, automatically generate the map, support zooming and adding coverings and so on.

Drag the video out of the channel form to automatically delete the video.

The right mouse button can delete the current + all videos and take screenshots of current + all videos.

Video recorder management, camera management, you can add, delete, modify, import and export print information, and immediately apply new equipment information to generate a tree list without restarting.

In the pro file, you are free to open or load the map.

Video playback can be switched freely by two kernels, vlc+ffmpeg, both of which can be set in pro.

You can set 1 "4" 9 "16 screen polling, you can set the polling interval and the polling stream type, etc. Click the start polling button on the right side of the toolbar at the bottom of the main interface, and click stop polling again.

By default, the mouse pointer is automatically hidden without operation for more than 10 seconds.

Support onvif search equipment, support any onvif camera, including but not limited to Haikang Dahuayu Shitian Weiye Huawei and so on.

Support onvif pan control, can move the head camera up and down, including reset and focal length adjustment, etc.

It also supports sqlite, mysql, postsql and other databases.

Can save video, can be selected for storage or single file storage, optional storage interval.

The video stream communication mode tcp+udp can be set, and the video decoding can be set as speed priority, quality priority, balance and so on.

Can set hard decoding type, support qsv, dxva2, d3d11va and so on.

Opengl is used by default to draw video, ultra-low CPU resource consumption, support for yuyv and nv12 two formats to draw, very powerful.

Highly customizable, users can easily derive their own functions on this basis, supporting linux and mac systems.

Third, effect picture

IV. Core code # include "commonvideomanage.h" # ifdef videovlc#include "vlchelper.h" # elif videoffmpeg#include "ffmpeghelper.h" # elif haikang#include "haikanghelper.h" # endif#define TIMEMS qPrintable (QTime::currentTime (). ToString ("HH:mm:ss zzz")) # define TIME qPrintable (QTime::currentTime (). ToString ("HH:mm:ss")) # define QDATE qPrintable (QDate::currentDate (). ToString ("yyyy") -MM-dd ") # define QTIME qPrintable (QTime::currentTime (). ToString (" HH-mm-ss ")) # define DATETIME qPrintable (QDateTime::currentDateTime (). ToString (" yyyy-MM-dd HH:mm:ss ")) # define STRDATETIME qPrintable (QDateTime::currentDateTime (). ToString (" yyyy-MM-dd-HH-mm-ss ")) # define STRDATETIMEMS qPrintable (QDateTime::currentDateTime (). ToString (" yyyy-MM-dd-HH ") -mm-ss-zzz ") QScopedPointer CommonVideoManage::self CommonVideoManage * CommonVideoManage::Instance () {if (self.isNull ()) {static QMutex mutex; QMutexLocker locker (& mutex); if (self.isNull ()) {self.reset (new CommonVideoManage);}} return self.data ();} CommonVideoManage::CommonVideoManage (QObject * parent): QObject (parent) {timeout = 10; openInterval = 1000; checkInterval = 5; videoCount = 16; saveVideo = false SaveVideoInterval = 0; savePath = qApp- > applicationDirPath (); / / Open video timer timerOpen = new QTimer (this); connect (timerOpen, SIGNAL (timeout ()), this, SLOT (openVideo (); timerOpen- > setInterval (openInterval); / / reconnect video timer timerCheck = new QTimer (this); connect (timerCheck, SIGNAL (timeout ()), this, SLOT (checkVideo (); timerCheck- > setInterval (checkInterval * 1000) / / create a new directory newDir ("snap");} CommonVideoManage::~CommonVideoManage () {this- > stop ();} QString CommonVideoManage::getVersion2 () {# if (defined videovlc) | | (defined videoffmpeg) | (defined haikang) return getVersion (); # else return "1.0" # endif} void CommonVideoManage::newDir (const QString & dirName) {/ / if the path contains slash characters, it is an absolute path / / linux system path character with / windows system path character with: / QString strDir = dirName If (! strDir.startsWith ("/") & &! strDir.contains (": /") {strDir = QString ("% 1Accord% 2") .arg (qApp- > applicationDirPath ()) .arg (strDir);} QDir dir (strDir); if (! dir.exists ()) {dir.mkpath (strDir);}} void CommonVideoManage::openVideo () {if (index)

< videoCount) { //取出一个进行打开,跳过为空的立即下一个 QString url = videoUrls.at(index); if (!url.isEmpty()) { this->

Open (index); index++;} else {index++; this- > openVideo ();}} else {/ / disable timer timerOpen- > stop ();}} void CommonVideoManage::checkVideo () {/ / if the timer is still working, do not continue if (timerOpen- > isActive ()) {return } QDateTime now = QDateTime::currentDateTime (); for (int I = 0; I

< videoCount; i++) { //只有url不为空的才需要处理重连 if (videoUrls.at(i).isEmpty()) { continue; } //如果10秒内已经处理过重连则跳过当前这个,防止多个掉线一直处理第一个掉线的 if (lastTimes.at(i).secsTo(now) < 10) { continue; } //计算超时时间 QDateTime lastTime = videoWidgets.at(i)->

GetLastTime (); int sec = lastTime.secsTo (now); if (sec > = timeout) {/ / reconnect the device videoWidgets.at (I)-> restart (); / / remember the last reconnection time lastTimes [I] = now; / / break for each reconnection }} void CommonVideoManage::snapImage (const QImage & image) {CommonVideoWidget * w = (CommonVideoWidget *) sender (); QString fileName = w-> property ("fileName"). ToString (); if (! image.isNull ()) {image.save (fileName, "jpg");} void CommonVideoManage::setTimeout (int timeout) {if (timeout > = 5 & & timeout)

< 60) { this->

Timeout = timeout;}} void CommonVideoManage::setOpenInterval (int openInterval) {if (openInterval > = 0 & & openInterval openInterval = openInterval; timerOpen- > setInterval (openInterval);}} void CommonVideoManage::setCheckInterval (int checkInterval) {if (checkInterval > = 5 & & checkInterval checkInterval = checkInterval; timerCheck- > setInterval (checkInterval * 1000);} void CommonVideoManage::setVideoCount (int videoCount) {this- > videoCount = videoCount;} void CommonVideoManage::setSaveVideo (bool saveVideo) {this- > saveVideo = saveVideo } void CommonVideoManage::setSaveVideoInterval (int saveVideoInterval) {this- > saveVideoInterval = saveVideoInterval;} void CommonVideoManage::setSavePath (const QString & savePath) {this- > savePath = savePath;} void CommonVideoManage::setUrls (const QList & videoUrls) {this- > videoUrls = videoUrls;} void CommonVideoManage::setNames (const QList & videoNames) {this- > videoNames = videoNames;} void CommonVideoManage::setWidgets (QList videoWidgets) {this- > videoWidgets = videoWidgets;} void CommonVideoManage::start () {if (videoWidgets.count ()! = videoCount) {return } lastTimes.clear (); for (int I = 0; I

< videoCount; i++) { lastTimes.append(QDateTime::currentDateTime()); QString url = videoUrls.at(i); if (!url.isEmpty()) { CommonVideoWidget *w = videoWidgets.at(i);#ifdef videoffmpeg disconnect(w, SIGNAL(snapImage(QImage)), this, SLOT(snapImage(QImage))); connect(w, SIGNAL(snapImage(QImage)), this, SLOT(snapImage(QImage)));#endif //设置文件url地址 w->

SetUrl (url); / / if it is a USB camera, set width and height if separately (w-> getIsUsbCamera ()) {w-> setVideoWidth (480); w-> setVideoHeight (480);} / / set OSD information, visible + font size + text + color + format + position if (I

< videoNames.count()) { w->

SetOSD1Visible (true); w-> setOSD1FontSize (18); w-> setOSD1Text (videoNames.at (I)); w-> setOSD1Color (Qt::yellow); w-> setOSD1Format (CommonVideoWidget::OSDFormat_Text); w-> setOSD1Position (CommonVideoWidget::OSDPosition_Right_Top) / / you can also set the second route OSD#if 0w-> setOSD2Visible (true); w-> setOSD2FontSize (18); w-> setOSD2Color (Qt::yellow); w-> setOSD2Format (CommonVideoWidget::OSDFormat_DateTime); w-> setOSD2Position (CommonVideoWidget::OSDPosition_Left_Bottom) # endif} / / sets whether to store files w-> setSaveFile (saveVideo); w-> setSavePath (savePath); w-> setSaveInterval (saveVideoInterval); if (saveVideo & & saveVideoInterval = = 0) {QString path = QString ("% 1 saveVideoInterval% 2") .arg (savePath) .arg (QDATE); newDir (path) QString fileName = QString ("% 1/Ch%2_%3.mp4") .arg (path) .arg (I + 1) .arg (STRDATETIME); w-> setFileName (fileName);} / / Open interval = 0 milliseconds, open if immediately (openInterval = = 0) {this- > arg (I) } / / start timer one by one queue to open if (openInterval > 0) {index = 0; timerOpen- > start ();} / start timer queue processing reconnect QTimer::singleShot (5000, timerCheck, SLOT (start ());} void CommonVideoManage::stop () {if (videoWidgets.count ()! = videoCount) {return) } if (timerOpen- > isActive ()) {timerOpen- > stop ();} if (timerCheck- > isActive ()) {timerCheck- > stop ();} for (int I = 0; I

< videoCount; i++) { this->

Close (I);}} void CommonVideoManage::open (int index) {if (! videoUrls.at (index). IsEmpty ()) {videoWidgets.at (index)-> open ();}} void CommonVideoManage::close (int index) {if (! videoUrls.at (index). IsEmpty ()) {videoWidgets.at (index)-> close () }} void CommonVideoManage::snap (int index, const QString & fileName) {if (videoUrls.at (index). IsEmpty ()) {return;} # ifdef videoffmpeg CommonVideoWidget * w = videoWidgets.at (index); w-> setProperty ("fileName", fileName); QImage img = w-> getImage (); if (! img.isNull ()) {img.save (fileName, "jpg");} # else videoWidgets.at (index)-> snap (fileName) # endif} at this point, I believe you have a deeper understanding of "how to use Qt audio and video development to achieve general channel management". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report