Qt編寫安防視頻監控系統21-攝像機管理


一、前言

攝像機管理在整個系統中是數據庫部分最核心的,只有添加了攝像機信息,才能進行加載,生成樹狀列表等,攝像機表信息的字段內容改過好幾次,有可能后期還需要修改,目前攝像機表信息主要包括攝像機編號、攝像機名稱、所屬錄像機、廠家、設備地址、媒體地址、雲台地址、主碼流地址、子碼流地址、經緯度、背景地圖、X坐標、Y坐標、用戶姓名、用戶密碼、啟用狀態、安裝位置。其中設備地址、媒體地址、雲台地址、主碼流地址、子碼流地址這五個是在通過onvif搜索設備的時候拿到,碼流地址是必須的,其他三個可以為空,這三個用來雲台控制。背景地圖表示該攝像機對應的圖片地圖模塊的圖片文件名稱,默認在可執行文同一目錄下的map文件夾,XY坐標為對應地圖上的位置,經緯度為在線地圖和離線地圖中的位置,用戶名和密碼為對應onvif登錄到該攝像機的用戶信息,用戶名和密碼信息必須正確,否則在雲台控制的時候會失敗,每次雲台控制下發的數據都帶了用戶信息,用戶信息不正確的話會執行失敗,這個用戶和攝像機的web界面的登錄用戶不一樣,一般都是在攝像機的后台onvif用戶信息的地方進行設置。

分頁組件開源地址:https://gitee.com/feiyangqingyun/QWidgetDemo https://github.com/feiyangqingyun/QWidgetDemo
文件名稱:dbpage

體驗地址:https://gitee.com/feiyangqingyun/QWidgetExe https://github.com/feiyangqingyun/QWidgetExe
文件名稱:bin_video_system.zip

二、功能特點

  1. 支持16畫面切換,全屏切換等,包括1+4+6+8+9+13+16畫面切換。
  2. 支持alt+enter全屏,esc退出全屏。
  3. 自定義信息框+錯誤框+詢問框+右下角提示框。
  4. 17套皮膚樣式隨意更換,所有樣式全部統一,包括菜單等。
  5. 雲台儀表盤鼠標移上去高亮,八個方位精准識別。
  6. 底部畫面工具欄(畫面分割切換+截圖聲音等設置)移上去高亮。
  7. 可在配置文件更改左上角logo+中文軟件名稱+英文軟件名稱。
  8. 封裝了百度地圖,三維切換,設備點位,鼠標按下獲取經緯度等。
  9. 堆棧窗體,每個窗體都是個單獨的qwidget,方便編寫自己的代碼。
  10. 頂部鼠標右鍵菜單,可動態控制時間CPU+左上角面板+左下角面板+右上角面板+右下角面板的顯示和隱藏,支持恢復默認布局。
  11. 工具欄可以放置多個小圖標和關閉圖標。
  12. 左側右側可拖動拉伸,並自動記憶寬高位置,重啟后恢復。
  13. 雙擊攝像機節點自動播放視頻,雙擊節點自動依次添加視頻,會自動跳到下一個,雙擊父節點自動添加該節點下的所有視頻。
  14. 攝像機節點拖曳到對應窗體播放視頻,同時支持拖曳本地文件直接播放。
  15. 視頻畫面窗體支持拖曳交換,瞬間響應。
  16. 雙擊節點+拖曳節點+拖曳窗體交換位置,均自動更新url.txt。
  17. 支持從url.txt中加載16通道視頻播放,自動記憶最后通道對應的視頻,軟件啟動后自動打開播放。
  18. 右下角音量條控件,失去焦點自動隱藏,音量條帶靜音圖標。
  19. 集成百度地圖,可以添加設備對應位置,自動生成地圖,支持縮放和三維地圖,提供地圖風格選擇,共12種風格。
  20. 視頻拖動到通道窗體外自動刪除視頻。
  21. 鼠標右鍵可刪除當前+所有視頻,截圖當前+所有視頻。
  22. 錄像機管理、攝像機管理,可添加刪除修改導入導出打印信息,立即應用新的設備信息生成樹狀列表,不需重啟。
  23. 在pro文件中可以自由開啟是否加載地圖。
  24. 視頻播放可選四種內核自由切換,vlc+ffmpeg+easyplayer+海康sdk,均可在pro中設置。
  25. 可設置1+4+9+16畫面輪詢,可設置輪詢間隔以及輪詢碼流類型等,直接在主界面底部工具欄右側單擊啟動輪詢按鈕即可,再次單擊停止輪詢。
  26. 默認超過10秒鍾未操作自動隱藏鼠標指針。
  27. 支持onvif搜素設備,支持任意onvif攝像機,包括但不限於海康大華宇視天地偉業華為等,支持onvif雲台控制。
  28. 高度可定制化,用戶可以很方便的在此基礎上衍生自己的功能,支持linux系統。

三、效果圖

四、核心代碼

void frmConfigIpc::on_btnAdd_clicked()
{
    int count = model->rowCount();
    model->insertRow(count);

    int ipcID = model->index(count - 1, 0).data().toInt() + 1;
    QString ipcName = model->index(count - 1, 1).data().toString();
    QString nvrName = model->index(count - 1, 2).data().toString();
    QString ipcType = model->index(count - 1, 3).data().toString();
    QString onvifAddr = model->index(count - 1, 4).data().toString();
    QString mediaAddr = model->index(count - 1, 5).data().toString();
    QString ptzAddr = model->index(count - 1, 6).data().toString();
    QString rtspMain = model->index(count - 1, 7).data().toString();
    QString rtspSub = model->index(count - 1, 8).data().toString();
    QString ipcPosition = model->index(count - 1, 9).data().toString();
    QString ipcImage = model->index(count - 1, 10).data().toString();
    int ipcX = model->index(count - 1, 11).data().toInt();
    int ipcY = model->index(count - 1, 12).data().toInt();
    QString userName = model->index(count - 1, 13).data().toString();
    QString userPwd = model->index(count - 1, 14).data().toString();
    QString ipcEnable = model->index(count - 1, 15).data().toString();
    QString ipcAddr = model->index(count - 1, 16).data().toString();

    if (ipcName.startsWith("攝像機#")) {
        ipcName = QString("攝像機#%1").arg(ipcID);
    }

    ipcX += App::DeviceWidth;
    if (ipcX > App::MapWidth - 100) {
        ipcX = 5;
        ipcY += App::DeviceHeight;
    }

    if (count == 0) {
        ipcID = 1;
        ipcName = "攝像機#1";
        nvrName = "錄像機#1";

        ipcType = "other";
        //onvifAddr = "http://192.168.1.128/onvif/device_service";
        //mediaAddr = "http://192.168.1.128//onvif/media_service";
        //ptzAddr = "http://192.168.1.128//onvif/ptz_service";
        rtspMain = "rtsp://192.168.1.128:554/0";
        rtspSub = "rtsp://192.168.1.128:554/1";
        ipcPosition = "121.534942,31.307706";
        ipcImage = "無";
        ipcX = 5;
        ipcY = 5;
        userName = "admin";
        userPwd = "admin";
        ipcEnable = "啟用";
        ipcAddr = "錄像機的安裝位置";
    }

    //設置新增加的行默認值
    model->setData(model->index(count, 0), ipcID);
    model->setData(model->index(count, 1), ipcName);
    model->setData(model->index(count, 2), nvrName);
    model->setData(model->index(count, 3), ipcType);
    model->setData(model->index(count, 4), onvifAddr);
    model->setData(model->index(count, 5), mediaAddr);
    model->setData(model->index(count, 6), ptzAddr);
    model->setData(model->index(count, 7), rtspMain);
    model->setData(model->index(count, 8), rtspSub);
    model->setData(model->index(count, 9), ipcPosition);
    model->setData(model->index(count, 10), ipcImage);
    model->setData(model->index(count, 11), ipcX);
    model->setData(model->index(count, 12), ipcY);
    model->setData(model->index(count, 13), userName);
    model->setData(model->index(count, 14), userPwd);
    model->setData(model->index(count, 15), ipcEnable);
    model->setData(model->index(count, 16), ipcAddr);
    ui->tableView->setCurrentIndex(model->index(count, 0));
}

void frmConfigIpc::on_btnSave_clicked()
{
    model->database().transaction();
    if (model->submitAll()) {
        model->database().commit();
        DBHelper::loadIpcInfo();
        DeviceHelper::initDeviceTree();
        DeviceHelper::initVideoIcon();
        DeviceHelper::initDeviceMap();
        DeviceHelper::initDeviceButton();
        AppEvent::Instance()->slot_saveIpcInfo();
    } else {
        model->database().rollback();
        QUIHelper::showMessageBoxError("保存信息失敗,信息不能為空,請重新填寫!");
    }
}

void frmConfigIpc::on_btnDelete_clicked()
{
    if (ui->tableView->currentIndex().row() < 0) {
        QUIHelper::showMessageBoxError("請選擇要刪除的攝像機!");
        return;
    }

    if (QUIHelper::showMessageBoxQuestion("確定要刪除該攝像機嗎? 刪除后不能恢復!") == QMessageBox::Yes) {
        int row = ui->tableView->currentIndex().row();
        model->removeRow(row);
        model->submitAll();
        ui->tableView->setCurrentIndex(model->index(model->rowCount() - 1, 0));
        DBHelper::loadIpcInfo();
        DeviceHelper::initDeviceTree();
        DeviceHelper::initVideoIcon();
        AppEvent::Instance()->slot_saveIpcInfo();
    }
}

void frmConfigIpc::on_btnReturn_clicked()
{
    model->revertAll();
}

void frmConfigIpc::on_btnClear_clicked()
{
    if (model->rowCount() <= 0) {
        return;
    }

    if (QUIHelper::showMessageBoxQuestion("確定要清空所有攝像機信息嗎?") == QMessageBox::Yes) {
        DBHelper::clearIpcInfo();
        model->select();
        DBHelper::loadIpcInfo();
        DeviceHelper::initDeviceTree();
        DeviceHelper::initVideoIcon();
        AppEvent::Instance()->slot_saveIpcInfo();
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM