• 62919阅读
  • 98回复

QT开发之旅五视频监管平台(开源) [复制链接]

上一主题 下一主题
离线liudianwu
 

图酷模式  只看楼主 正序阅读 楼主  发表于: 2014-12-27
— 本帖被 realfan 执行加亮操作(2014-12-27) —
忙忙碌碌又是一年,算算自己毕业四年半,一直在现在这家公司做研发外加总经理助理,研发起初用的VB.NET,而后全面转为C#,最后又全面转为QT,都是由于项目需要,算下来自己搞QT编程也已经四年了,2010年开始接触QT并编写一些公司需要的辅助工具,其实在公司绝大部分时间在干杂七杂八的事情,例如采购、人事、招投标、现场技术支持等,一年下来大概只有不到三分之一的时间在钻研程序,其中这三分之一的时间晚上占了一大半,其实搞程序的,我感觉绝大部分都是出于本身兴趣爱好,然后持之以恒的钻研,不断成长和进步。
QT陆续写过几个商业项目以及公司内部硬件通信需要的一些辅助设置工具,其中以报警视频联动管理平台为主,从2010年的C#版本开始编写,陆续完善积累到2014年的稳定版,花了相当多的精力去完善,不断查看同行的相关软件功能,吸取优秀的功能,摒弃无用的功能,用易用简洁全完善每一个细节。
今天要分享的是给某区安全管理中心编写的视频监管平台,稍后会放出QT4-QT5各版本可完整编译运行的源码。
按照习惯,首先上一张主界面截图:
XP下运行截图:


Win7下运行截图:


Ubuntu下运行截图:


整个系统在开始架构的时候,本人都是写在草稿纸上的,包括布局,功能点,需要注意的处理等方面,现在要重新一一仔细写出来,还真不容易,这里就说个大概,然后将其中的部分功能处理用代码描述。
项目需求:某区下面有几百所学校,每个学校都有若干台NVR或者DVR,每台NVRDVR都挂接着NIPC(摄像机)(包括网络摄像机和模拟摄像机),现在需要对所有学校的监控进行查看以及回放和轮询,能够对指定学校进行视频监控,对所有学校的视重点部位视频进行查看轮询,可自定义轮询时间等。
开发过程:本着尽量追求简洁的要求,最终编写了如上图的主界面。没有采用QT自带的界面,而是重写了界面,自定义无边框拖动,自由换肤,全部采用QSS控制,本人从官网http://qt-project.org/doc/qt-4.8/stylesheet-examples.html彻底学习了下QSS的规则,整理了一套通用的换肤方案。

功能点罗列:
1:只限定一个实例处理。


视频监管平台是一个独占视频通道资源的系统,不能运行多个实例在同一台电脑上运行,所以在main函数中就限制了一个实例运行。
//创建共享内存,判断是否已经运行程序
    QSharedMemory mem("VM");
    if (!mem.create(1)) {
        myHelper::ShowMessageBoxError("程序已运行,软件将自动关闭!");
        return 1;
    }
其中VM为自定义的名称,return 1表示退出程序返回1给操作系统。

2F1键进入全屏模式,Esc键退出全屏模式。
几乎所有的视频监控系统,主界面都支持全屏显示esc退出全屏,在QT中我是这样实现的,重写了主界面的keyPressEvent事件,拦截按键消息,判断对应按键,调用全屏及普通模式的方法。

void frmMain::keyPressEvent(QKeyEvent *event)
{
    //空格键进入全屏,esc键退出全屏
    switch(event->key()) {
    case Qt::Key_F1:
        screen_full();
        break;
    case Qt::Key_Escape:
        screen_normal();
        break;
    default:
        QDialog::keyPressEvent(event);
        break;
    }
}

void frmMain::screen_full()
{    
    this->setGeometry(qApp->desktop()->geometry());
    this->layout()->setContentsMargins(0, 0, 0, 0);
    ui->widget_main->layout()->setContentsMargins(0, 0, 0, 0);
    ui->widget_title->setVisible(false);
    ui->treeMain->setVisible(false);
}

void frmMain::screen_normal()
{    
    this->setGeometry(qApp->desktop()->availableGeometry());
    this->layout()->setContentsMargins(1, 1, 1, 1);
    ui->widget_main->layout()->setContentsMargins(5, 5, 5, 5);
    ui->widget_title->setVisible(true);
    ui->treeMain->setVisible(true);
}

3:支持QT4QT5各个版本编译运行。
之前放出过N个工具及一个安防报警管理系统的源码,有兴趣的可以点击这里查看:http://www.qtcn.org/bbs/read-htm-tid-56372.html,很多兄弟反应不能在QT5上编译通过,甚是操蛋。本人一直喜欢用QT4.7,两个原因,一个是项目需要,程序主要在ARM上面跑,觉得部分公司提供的硬件开发板核心板都是自带的QT4.7版本的运行库,其他版本编译的程序无法在4.7运行库下运行。一个是QT4.7版本很经典,在windows上打包只需要附带几个DLL即可,打包压缩下一般才七八兆,很小,方便。到现在的QT5.4,我擦,光插件库就需要130MB,我勒个去,这还让用户的电脑怎么活啊!
本项目并木有牵扯到windows.h文件,连修改系统时间的方法都改用了通用的系统命令,所以只要稍微更改部分地方即可,我代码中用的是:
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
#include <QtWidgets>
#endif
QT5以上的版本需要引入头文件QtWidgets,设置UTF8编码在QT5中已经取消了。
    //设置编码为UTF8
    static void SetUTF8Code() {
#if (QT_VERSION <= QT_VERSION_CHECK(5,0,0))
        QTextCodec *codec = QTextCodec::codecForName("UTF-8");
        QTextCodec::setCodecForLocale(codec);
        QTextCodec::setCodecForCStrings(codec);
        QTextCodec::setCodecForTr(codec);
#endif
}

将所有的toAscii()方法全部替换成了toLatin1(),本来QT4就支持toLatin1()方法,作用几乎一样,索性就所有的替换成了toLatin1()方法。

4:精心编写的通用的excelhelper类,独创的不依赖任何office组件的导出数据到表格的处理,通用任何excel版本。
方法:
void ToExcel(QString fileName, QString sheetName,
                 QString title, QString columnNames[],
                 int columnWidths[], int columnCount, QStringList content);
具体实现可以下载源码下来看。

57套精美样式换肤,整体界面换肤。
这个花了本人N多精力去一个个调颜色,一个个控件写对应样式,所以在源码中并不包含,
在主界面的右上角做了个小箭头用来更换样式。

void frmMain::change_style()
{
    QAction *action = (QAction *)sender();
    QString style = action->text();
    if (style == "淡蓝色") {
        myApp::AppStyle = ":/image/blue.css";
    } else if (style == "蓝色") {
        myApp::AppStyle = ":/image/dev.css";
    } else if (style == "灰色") {
        myApp::AppStyle = ":/image/gray.css";
    } else if (style == "黑色") {
        myApp::AppStyle = ":/image/black.css";
    } else if (style == "灰黑色") {
        myApp::AppStyle = ":/image/brown.css";
    } else if (style == "白色") {
        myApp::AppStyle = ":/image/white.css";
    } else if (style == "银色") {
        myApp::AppStyle = ":/image/silvery.css";
    }

    myHelper::SetStyle(myApp::AppStyle);
    myApp::WriteConfig();
}

6:自带中文翻译文件。
鼠标右键菜单,默认QT是英文的,客户看了很恼火,需要自己将中文翻译文件加入资源文件编译到可执行文件中。
//设置为中文字符
    static void SetChinese() {
        QTranslator *translator = new QTranslator(qApp);
        translator->load(":/image/qt_zh_CN.qm");
        qApp->installTranslator(translator);
}

7:基本常用的数据库处理,添加删除修改操作,表格显示。
本人一直喜欢采用拼接sql字符串来执行SQL语句。觉得这样运行效率很高,而且这种方法通用任何编程语言。
void frmIPC::on_btnAdd_clicked()
{
    QString IPCID = ui->cboxIPCID->currentText();
    QString IPCName = ui->txtIPCName->text();
    QString NVRID = ui->cboxNVRID->currentText();
    QString NVRName = ui->cboxNVRName->currentText();
    QString IPCType = ui->cboxIPCType->currentText();
    QString IPCRtspAddrMain = ui->txtIPCRtspAddrMain->text();
    QString IPCRtspAddrSub = ui->txtIPCRtspAddrSub->text();
    QString IPCUserName = ui->txtIPCUserName->text();
    QString IPCUserPwd = ui->txtIPCUserPwd->text();
    QString IPCUse = ui->cboxIPCUse->currentText();

    if (IPCName == "") {
        myHelper::ShowMessageBoxError("名称不能为空,请重新填写!");
        ui->txtIPCName->setFocus();
        return;
    }

    if (NVRName == "") {
        myHelper::ShowMessageBoxError("NVR名称不能为空,请先添加好NVR!");
        return;
    }

    if (IPCRtspAddrMain == "") {
        myHelper::ShowMessageBoxError("主码流地址不能为空,请重新填写!");
        ui->txtIPCRtspAddrMain->setFocus();
        return;
    }

    if (IPCRtspAddrSub == "") {
        myHelper::ShowMessageBoxError("子码流地址不能为空,请重新填写!");
        ui->txtIPCRtspAddrSub->setFocus();
        return;
    }

    //检测编号是否唯一
    if (IsExistIPCID(NVRID, IPCID)) {
        myHelper::ShowMessageBoxError("编号已经存在,请重新选择!");
        return;
    }

    QSqlQuery query;
    QString sql = "insert into [IPCInfo](";
    sql += "[IPCID],[IPCName],[NVRID],[NVRName],";
    sql += "[IPCType],[IPCRtspAddrMain],[IPCRtspAddrSub],";
    sql += "[IPCUserName],[IPCUserPwd],[IPCUse])";
    sql += "values('";
    sql += IPCID + "','";
    sql += IPCName + "','";
    sql += NVRID + "','";
    sql += NVRName + "','";
    sql += IPCType + "','";
    sql += IPCRtspAddrMain + "','";
    sql += IPCRtspAddrSub + "','";
    sql += IPCUserName + "','";
    sql += IPCUserPwd + "','";
    sql += IPCUse + "')";
    query.exec(sql);

    LoadIPCInfo();

    ui->cboxIPCID->setCurrentIndex(ui->cboxIPCID->currentIndex() + 1);
    ui->txtIPCName->setText(QString("摄像机%1").arg(ui->cboxIPCID->currentText()));
}

void frmIPC::on_btnDelete_clicked()
{
    if (ui->tableMain->currentIndex().row() < 0) {
        myHelper::ShowMessageBoxError("请选择要删除的摄像机!");
        return;
    }

    QString tempIPCID = queryModule->record(
                            ui->tableMain->currentIndex().row())
                        .value(0).toString();

    if (myHelper::ShowMessageBoxQuesion("确定要删除摄像机吗?") == 1) {
        QSqlQuery query;
        QString sql = "delete from [IPCInfo] where [IPCID]='" + tempIPCID + "'";
        query.exec(sql);
        myHelper::Sleep(100);

        //同步删除轮询表中的摄像机信息
        sql = "delete from [PollInfo] where [IPCID]='" + tempIPCID + "'";
        query.exec(sql);
        myHelper::Sleep(100);

        LoadIPCInfo();
    }
}

void frmIPC::on_btnUpdate_clicked()
{
    if (ui->tableMain->currentIndex().row() < 0) {
        myHelper::ShowMessageBoxError("请选择要修改的摄像机!");
        return;
    }

    QString tempIPCID = queryModule->record(
                            ui->tableMain->currentIndex().row())
                        .value(0).toString();

    QString IPCID = ui->cboxIPCID->currentText();
    QString IPCName = ui->txtIPCName->text();
    QString NVRID = ui->cboxNVRID->currentText();
    QString NVRName = ui->cboxNVRName->currentText();
    QString IPCType = ui->cboxIPCType->currentText();
    QString IPCRtspAddrMain = ui->txtIPCRtspAddrMain->text();
    QString IPCRtspAddrSub = ui->txtIPCRtspAddrSub->text();
    QString IPCUserName = ui->txtIPCUserName->text();
    QString IPCUserPwd = ui->txtIPCUserPwd->text();
    QString IPCUse = ui->cboxIPCUse->currentText();

    if (IPCID != tempIPCID) {
        //检测编号是否和已经存在的除自己之外的编号相同
        if (IsExistIPCID(NVRID, IPCID)) {
            myHelper::ShowMessageBoxError("编号已经存在,请重新选择!");
            return;
        }
    }

    QSqlQuery query;
    QString sql = "update [IPCInfo] set";
    sql += " [IPCID]='" + IPCID;
    sql += "',[IPCName]='" + IPCName;
    sql += "',[NVRID]='" + NVRID;
    sql += "',[NVRName]='" + NVRName;
    sql += "',[IPCType]='" + IPCType;
    sql += "',[IPCRtspAddrMain]='" + IPCRtspAddrMain;
    sql += "',[IPCRtspAddrSub]='" + IPCRtspAddrSub;
    sql += "',[IPCUserName]='" + IPCUserName;
    sql += "',[IPCUserPwd]='" + IPCUserPwd;
    sql += "',[IPCUse]='" + IPCUse;
    sql += "' where [IPCID]='" + tempIPCID + "'";
    query.exec(sql);
    myHelper::Sleep(100);

    //同步修改轮询表的信息
    sql = "update [PollInfo] set";
    sql += " [IPCID]='" + IPCID;
    sql += "',[IPCName]='" + IPCName;
    sql += "',[NVRID]='" + NVRID;
    sql += "',[NVRName]='" + NVRName;
    sql += "',[IPCRtspAddrMain]='" + IPCRtspAddrMain;
    sql += "',[IPCRtspAddrSub]='" + IPCRtspAddrSub;
    sql += "' where [IPCID]='" + tempIPCID + "'";
    query.exec(sql);
    myHelper::Sleep(100);

    LoadIPCInfo();
}

8QTreeViewQTableView数据加载和双击处理。
如下图:


void frmPollConfig::LoadNVRIPC()
{
    ui->treeMain->clear();

    QSqlQuery queryNVR;
    QString sqlNVR = "select [NVRID],[NVRName],[NVRIP] from [NVRInfo] where [NVRUse]='启用'";
    queryNVR.exec(sqlNVR);

    while (queryNVR.next()) {
        QString tempNVRID = queryNVR.value(0).toString();
        QString tempNVRName = queryNVR.value(1).toString();
        QString tempNVRIP = queryNVR.value(2).toString();

        QTreeWidgetItem *itemNVR = new QTreeWidgetItem
        (ui->treeMain, QStringList(tempNVRName + "[" + tempNVRIP + "]"));
        itemNVR->setIcon(0, QIcon(":/image/nvr.png"));

        //查询没有添加在轮询表中的摄像机信息
        QSqlQuery queryIPC;
        QString sqlIPC = "select [IPCID],[IPCName],[IPCRtspAddrMain] from [IPCInfo]";
        sqlIPC += " where [NVRID]='" + tempNVRID;
        sqlIPC += "' and [IPCUse]='启用'";
        sqlIPC += " order by [IPCID] asc";
        queryIPC.exec(sqlIPC);

        while (queryIPC.next()) {
            QString tempIPCID = queryIPC.value(0).toString();

            //如果该摄像机已经存在轮询表,则跳过
            if (IsExistIPCID(tempIPCID)) {
                continue;
            }

            QString tempIPCName = queryIPC.value(1).toString();
            QString rtspAddr = queryIPC.value(2).toString();

            QStringList temp = rtspAddr.split("/");
            QString ip = temp[2].split(":")[0];

            temp = QStringList(QString(tempIPCName + "[" + ip + "](" + tempIPCID + ")"));
            QTreeWidgetItem *itemIPC = new QTreeWidgetItem(itemNVR, temp);
            itemIPC->setIcon(0, QIcon(":/image/ipc_normal.png"));
            itemNVR->addChild(itemIPC);
        }
    }
    ui->treeMain->expandAll();
}

916通道画面展示区域处理,自由切换1画面4画面9画面16画面。
这个功能看似简单,确花费我一个星期的时间完善。
void frmMain::show_video_4()
{
    removelayout();
    video_max = false;
    int index = 0;

    QAction *action = (QAction *)sender();
    QString name = action->text();
    if (name == "通道1-通道4") {
        index = 0;
        myApp::VideoType = "1_4";
    } else if (name == "通道5-通道8") {
        index = 4;
        myApp::VideoType = "5_8";
    } else if (name == "通道9-通道12") {
        index = 8;
        myApp::VideoType = "9_12";
    } else if (name == "通道13-通道16") {
        index = 12;
        myApp::VideoType = "13_16";
    }

    change_video_4(index);
    myApp::WriteConfig();
}

void frmMain::change_video_4(int index)
{
    for (int i = (index + 0); i < (index + 2); i++) {
        VideoLay[0]->addWidget(VideoLab);
        VideoLab->setVisible(true);
    }

    for (int i = (index + 2); i < (index + 4); i++) {
        VideoLay[1]->addWidget(VideoLab);
        VideoLab->setVisible(true);
    }
}
37条评分好评度+7贡献值+8金钱+72威望+10
whychristina 好评度 +1 - 2023-02-08
whychristina 贡献值 +1 - 2023-02-08
whychristina 威望 +1 - 2023-02-08
whychristina 金钱 +10 - 2023-02-08
jasonbj 金钱 +1 开源精神值得支持 2022-02-25
curiosity 贡献值 +1 LZ太强了,支持LZ的开源精神! 2017-06-23
curiosity 威望 +1 LZ太强了,支持LZ的开源精神! 2017-06-23
curiosity 金钱 +1 LZ太强了,支持LZ的开源精神! 2017-06-23
nikoladi 金钱 +3 - 2016-10-14
jonzeng 好评度 +1 - 2016-07-27
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线shokokawaii

只看该作者 98楼 发表于: 2023-10-21
好贴,可惜排版有点难受
QFluentWidgets 是基于 Qt 的 Fluent Designer 组件库,内置超过 160 个开箱即用的 Fluent Designer 组件,支持亮暗主题无缝切换和自定义主题色。搭配所见即所得的 Fluent Designer 软件,只需拖拖拽拽,不用编写一行 QSS,就能快速搭建现代化界面。有意者可联系邮箱或者 QQ~
官网:https://qfluentwidgets.com/zh/ (需要科学上网)
邮箱:shokokawaii@foxmail.com
QQ:1953658489
离线jazzmax

只看该作者 97楼 发表于: 2023-01-04
初学者路过,向大佬学习。
离线tanyue.esec

只看该作者 96楼 发表于: 2022-07-21
刚入坑安防领域,没有源码也能借鉴借鉴思路。

离线qfengdao

只看该作者 95楼 发表于: 2022-07-20
可惜链接失效了啊
离线jeffya888

只看该作者 94楼 发表于: 2021-06-26
厲害
离线zrq3563107

只看该作者 93楼 发表于: 2021-02-03
源代码连接失效了,能重新发一下吗,谢谢
离线cxs4808

只看该作者 92楼 发表于: 2021-02-02
楼主你这个源码可以发我一份吗??382983326@qq.com
离线david_2010

只看该作者 91楼 发表于: 2020-02-20
求下载啊,lz
离线jackiesp

只看该作者 90楼 发表于: 2020-02-19
楼主,还能下载吗?
本帖提到的人: @liudianwu
离线zhtman

只看该作者 89楼 发表于: 2020-02-08
支持楼主到底
离线habao126

只看该作者 88楼 发表于: 2020-02-07
下载不了了,好像下载下来学习下
离线zxwmail

只看该作者 87楼 发表于: 2020-01-04
    
离线liudianwu

只看该作者 86楼 发表于: 2020-01-04
回 lb_oo8 的帖子
lb_oo8:大神,源码还开放么,百度云链接失效了 (2020-01-04 11:42) 

可能没有了,好多年前的了,百度云他收费了,之前分享的自动失效了。
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线lb_oo8

只看该作者 85楼 发表于: 2020-01-04
大神,源码还开放么,百度云链接失效了
离线workshop

只看该作者 84楼 发表于: 2019-12-27
求一份源码
离线hostid

只看该作者 83楼 发表于: 2019-12-02
您好,这块的源码现在不再开放了吗
离线thinkcai

只看该作者 82楼 发表于: 2019-10-16
这个资源已经不能下载了?
离线fjydpf

只看该作者 81楼 发表于: 2019-04-24
不错,谢谢分享
离线子墨深沉

只看该作者 80楼 发表于: 2019-04-24
我讲数据库文件放到bin目录下,为什么还是显示数据库不存在呢
离线z1992hd

只看该作者 79楼 发表于: 2017-10-12
厉害厉害
离线xp3539989

只看该作者 78楼 发表于: 2017-08-14
llllllllllllllllllllllllllllllllllllllllllllllllll[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l[s:79]l
离线lsyzsl

只看该作者 77楼 发表于: 2017-07-21
大神,收徒弟不?
离线sanjuegou1

只看该作者 76楼 发表于: 2017-07-18
不支持太说不过去了!
离线hanheyfon

只看该作者 75楼 发表于: 2017-06-23
      
离线liudianwu

只看该作者 74楼 发表于: 2016-12-24
回 bs1003506507 的帖子
bs1003506507:视频[表情]  (2016-12-24 18:39) 

你好,可以的,加Q聊517216493
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线bs1003506507

只看该作者 73楼 发表于: 2016-12-24
视频
离线bs1003506507

只看该作者 72楼 发表于: 2016-12-24
LZ精神!我想说的是,我用的是Qt5.5,新手来着,目前对食品处理这块感兴趣,所以愿意花钱买核心部分,只是看时间过了这么久,不知道我拿到源码后能不能提供一下技术支持啊?
离线return

只看该作者 71楼 发表于: 2016-11-21
膜拜,请收下我的膝盖
离线hunterzf

只看该作者 70楼 发表于: 2016-09-23
谢谢楼主分享,真不错
离线dnqxdg

只看该作者 69楼 发表于: 2016-09-05
腾讯企点大数据免费群发营销模式(支持临时会话
很多客户朋友都知道,腾讯企点自身的付费群发还在维护状态,那怎么样利用企点辅助营销软件来对咱们的数据做大数据群发呢?今天给大家讲如何利用咱们的企点辅助软件对腾讯的企点做免费的大数据群发。

据我们目前的测试研究,做了很多的内部测试,目前腾讯在临时回话,就是保证精准的客户数据,也就是开通了临时回话的客户,可以做无限量的消息推送,无限量的陌生人群发,对群成员回话也是不限量的。陌生人会不限量回话的消息模式。

准备工具:腾讯企点,企点辅助软件

第一步,打开企点辅助软件,根据界面的提示,提取一定量的群成员或者在精准用户里面采集一定量的精准用户数据。如图示:

第二步,用精准用户里面的临时回话检测功能,检测并筛选具有临时回话的客户数据,并且关联到营销界面,注备做无限的消息群发。

第三步,编辑你要群发的广告消息,并且按照要求群发。

如果上述还不清楚,请咨询:

qq:2885401572   2885401573

电话:18810886909   13263345668

官方网站:www.hhwxkj.cn

离线菜蜗牛

只看该作者 68楼 发表于: 2016-09-03
请问楼主怎么实现运行图中这16个通路的平铺效果?
本帖提到的人: @liudianwu
离线fastestsnail

只看该作者 67楼 发表于: 2016-08-31
楼主真牛人
离线t1029901995

只看该作者 66楼 发表于: 2016-07-14
离线cwyyy

只看该作者 65楼 发表于: 2016-07-01
楼主,还可以赞助你辛苦费么
离线hbwh_will

只看该作者 64楼 发表于: 2016-06-03
        3q! 值得参考。
离线t1029901995

只看该作者 63楼 发表于: 2016-06-01
大神又奉献了
离线liudianwu

只看该作者 62楼 发表于: 2016-05-29
回 lxj434368832 的帖子
lxj434368832:关键的调用vlc的代码呢 (2016-05-29 14:18) 

可执行文件下载:http://pan.baidu.com/s/1hqxhtbA
源码下载:http://pan.baidu.com/s/1mgFWeDU
编译运行后如果提示缺少数据库。将源码下的file文件夹下的配置文件config.txt及VM.db数据库文件复制到bin目录下即可。

说明:公开的源码去除了视频处理部分及样式部分,其余功能全部保留,并可完整编译运行。
欢迎关注微信公众号:Qt实战 (各种开源作品、经验整理、项目实战技巧,专注Qt/C++软件开发,视频监控、物联网、工业控制、嵌入式软件、国产化系统应用软件开发)QQ:517216493  WX:feiyangqingyun  QQ群:751439350
离线lxj434368832

只看该作者 61楼 发表于: 2016-05-29
关键的调用vlc的代码呢
离线stlcours

只看该作者 60楼 发表于: 2016-05-10
膜拜~我除了维护旧版本需要一些精力,时间全部花在开发上了,为啥我和楼主还是差距那么大呢~
快速回复
限100 字节
 
上一个 下一个