1 概述
使用libonvif发现onvif摄像头、云台控制。
2 主要功能点
此演示工程展示以下功能:
1)第三方库的使用;
2)查找支持onvif协议的摄像头;
3)控制云台运动、缩放。
3 源码下载与导入
1)下载地址:git clone https://gitee.com/clawclaw/sttonvif.git
注:先设置一下换行符转换 git config --global core.autocrlf false
2)下载后解压,再导入到ApusIDE工作空间打开,具体操作请参考“项目导入”。
3)同步一下项目头文件
4 第三方库配置
4.1源码中已经包含了第三方库libonvif及libxml2
(如要复制到自己的项目中,用ctrl+c和ctrl+v)
4.2模拟器编译配置
a)头文件路径
b)库名及路径
注意,最后的路径"D:\apusv2\runtime-apustest.product\STTonvif\Debug"中的"D:\apusv2\runtime-apustest.product"要改成你导入的项目路径。
4.3 屏的编译设置
a)头文件
${workspace_loc:/${ProjName}/src}
b)库名及路径
"D:\apusv2\runtime-apustest.product\STTonvif\Release"中的"D:\apusv2\runtime-apustest.product"要改成你导入的项目路径
5 部分主要源码
#include "Frm05.h"
Frm05::Frm05(HmiApp* app, STTWidget *par, const string& id, const string& desc) : STTPage(app->getRuntime(), par, id, desc) {
hmiApp = app;
}
Frm05::~Frm05() {
}
void Frm05::onInit() {
}
void Frm05::createParts() {
setMainArg(0, 0, 1024, 600);
setMainStyle(0, 0xffffff, 0xffffff, 0, 255, 0, 0xc0c0c0);
/*----------------------------- Button : wMButton1 -----------------------------*/
wMButton1 = new STTButton(p_rt, this, "wMButton1", 0);
wMButton1->setMainArg(1, 1, 198, 48, false);
wMButton1->setPressedArg("返回主页", 0x0, "文泉驿微米黑", 16, 0);
wMButton1->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton1->setReleasedArg("返回主页", 0x0, "文泉驿微米黑", 16, 0);
wMButton1->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton1->bindOpenFormHandler(Event::CLICKED, "Frm01", PageMode::NEWWIN, NULL);
/*----------------------------- Button : wMButton2 -----------------------------*/
wMButton2 = new STTButton(p_rt, this, "wMButton2", 0);
wMButton2->setMainArg(200, 1, 198, 48, false);
wMButton2->setPressedArg("搜索摄像头", 0x0, "文泉驿微米黑", 16, 0);
wMButton2->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton2->setReleasedArg("搜索摄像头", 0x0, "文泉驿微米黑", 16, 0);
wMButton2->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton2->onEventHandler(Event::CLICKED, this, (EHandler) &Frm05::wMButton2_clk_cb);
/*----------------------------- Slider : wMSlider1 -----------------------------*/
wMSlider1 = new STTSlider(p_rt, this, "wMSlider1");
wMSlider1->setMainArg(18, 105, 164, 22, 5, 0, 10, false);
wMSlider1->setMainStyle(9999, 0xa0a0a0, 0xffffff, 0, 0, 0xa0a0a0, 0, 0x0, NULL);
wMSlider1->setIndicStyle(9999, 0x1a2b1, 0xffffff, 0, 0, 0x1a2b1, 0, 0xffffff, NULL);
wMSlider1->setKnobStyle(7, 0x1a2b1, 0xffffff, 0, 0, 0x1a2b1, 0, 0x0, NULL, 7);
/*----------------------------- Slider : wMSlider2 -----------------------------*/
wMSlider2 = new STTSlider(p_rt, this, "wMSlider2");
wMSlider2->setMainArg(216, 105, 164, 22, 5, 0, 10, false);
wMSlider2->setMainStyle(9999, 0xa0a0a0, 0xffffff, 0, 0, 0xa0a0a0, 0, 0x0, NULL);
wMSlider2->setIndicStyle(9999, 0x1a2b1, 0xffffff, 0, 0, 0x1a2b1, 0, 0xffffff, NULL);
wMSlider2->setKnobStyle(7, 0x1a2b1, 0xffffff, 0, 0, 0x1a2b1, 0, 0x0, NULL, 7);
/*----------------------------- Slider : wMSlider3 -----------------------------*/
wMSlider3 = new STTSlider(p_rt, this, "wMSlider3");
wMSlider3->setMainArg(416, 105, 164, 22, 5, 0, 10, false);
wMSlider3->setMainStyle(9999, 0xa0a0a0, 0xffffff, 0, 0, 0xa0a0a0, 0, 0x0, NULL);
wMSlider3->setIndicStyle(9999, 0x1a2b1, 0xffffff, 0, 0, 0x1a2b1, 0, 0xffffff, NULL);
wMSlider3->setKnobStyle(7, 0x1a2b1, 0xffffff, 0, 0, 0x1a2b1, 0, 0x0, NULL, 7);
/*----------------------------- Video : wMVideo1 -----------------------------*/
wMVideo1 = new STTFFmpeg(p_rt, this, "wMVideo1");
wMVideo1->channel = 0;
wMVideo1->setRotate(0);
wMVideo1->setMainArg(0, 133, 1025, 466, "");
/*----------------------------- Button : wMButton4 -----------------------------*/
wMButton4 = new STTButton(p_rt, this, "wMButton4", 0);
wMButton4->setMainArg(399, 50, 198, 48, false);
wMButton4->setPressedArg("play", 0x0, "文泉驿微米黑", 16, 0);
wMButton4->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton4->setReleasedArg("play", 0x0, "文泉驿微米黑", 16, 0);
wMButton4->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton4->onEventHandler(Event::CLICKED, this, (EHandler) &Frm05::wMButton4_clk_cb);
/*----------------------------- Dropdown : wMDropdown1 -----------------------------*/
wMDropdown1 = new STTDropdown(p_rt, this, "wMDropdown1");
wMDropdown1->setMainArg(398, 3, 620, 44, "[]", 0, ScrollDir::BOTTOM, NULL, -1, false);
wMDropdown1->setSymbol("↓", false);
wMDropdown1->setFonts(0x0, 16, "文泉驿微米黑", false, 0xffffff, 16, "文泉驿微米黑", 0, 0);
wMDropdown1->setMainStyle(8, 0xffffff, 0xffffff, 0, 2, 0xc0c0c0, 0, 0x0);
wMDropdown1->getStyle()->p_pad->setTop(11)->setBottom(11)->setLeft(11)->setRight(11);
wMDropdown1->setListSelectedStyle(0, 0x1a2b1, 0xffffff, 0, 0, 0x0);
/*----------------------------- Text : wMText2 -----------------------------*/
wMText2 = new STTTextArea(p_rt, this, "wMText2");
wMText2->setMainArg(0, 49, 200, 49, false, true, TextAlign::CENTER, -1, -1, -99999999, 99999999, false);
wMText2->setMainStyle(7, 0xffffff, 0xffffff, 0, 2, 0xc0c0c0, 11, 11, 4, 4, 255);
wMText2->setPlaceholderText("username")->setMaxLength(0)->setAcceptedChars("")->setImeMode(IME::UC);
wMText2->setFont(0x0, 16, "文泉驿微米黑", 0);
wMText2->setText("test");
/*----------------------------- Text : wMText3 -----------------------------*/
wMText3 = new STTTextArea(p_rt, this, "wMText3");
wMText3->setMainArg(198, 49, 200, 49, false, true, TextAlign::CENTER, -1, -1, -99999999, 99999999, false);
wMText3->setMainStyle(7, 0xffffff, 0xffffff, 0, 2, 0xc0c0c0, 11, 11, 4, 4, 255);
wMText3->setPlaceholderText("password")->setMaxLength(0)->setAcceptedChars("")->setImeMode(IME::UC);
wMText3->setFont(0x0, 16, "文泉驿微米黑", 0);
wMText3->setText("whxtt2022");
/*----------------------------- Button : wMButton3 -----------------------------*/
wMButton3 = new STTButton(p_rt, this, "wMButton3", 0);
wMButton3->setMainArg(1, 324, 66, 48, false);
wMButton3->setPressedArg("左", 0x0, "文泉驿微米黑", 16, 0);
wMButton3->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton3->setReleasedArg("左", 0x0, "文泉驿微米黑", 16, 0);
wMButton3->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton3->onEventHandler(Event::PRESSED, this, (EHandler) &Frm05::wMButton3_prs_cb);
wMButton3->onEventHandler(Event::RELEASED, this, (EHandler) &Frm05::wMButton3_rls_cb);
/*----------------------------- Button : wMButton7 -----------------------------*/
wMButton7 = new STTButton(p_rt, this, "wMButton7", 0);
wMButton7->setMainArg(957, 324, 66, 48, false);
wMButton7->setPressedArg("右", 0x0, "文泉驿微米黑", 16, 0);
wMButton7->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton7->setReleasedArg("右", 0x0, "文泉驿微米黑", 16, 0);
wMButton7->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton7->onEventHandler(Event::PRESSED, this, (EHandler) &Frm05::wMButton7_prs_cb);
wMButton7->onEventHandler(Event::RELEASED, this, (EHandler) &Frm05::wMButton7_rls_cb);
/*----------------------------- Button : wMButton8 -----------------------------*/
wMButton8 = new STTButton(p_rt, this, "wMButton8", 0);
wMButton8->setMainArg(479, 134, 66, 48, false);
wMButton8->setPressedArg("上", 0x0, "文泉驿微米黑", 16, 0);
wMButton8->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton8->setReleasedArg("上", 0x0, "文泉驿微米黑", 16, 0);
wMButton8->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton8->onEventHandler(Event::PRESSED, this, (EHandler) &Frm05::wMButton8_prs_cb);
wMButton8->onEventHandler(Event::RELEASED, this, (EHandler) &Frm05::wMButton8_rls_cb);
/*----------------------------- Button : wMButton9 -----------------------------*/
wMButton9 = new STTButton(p_rt, this, "wMButton9", 0);
wMButton9->setMainArg(479, 550, 66, 48, false);
wMButton9->setPressedArg("下", 0x0, "文泉驿微米黑", 16, 0);
wMButton9->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton9->setReleasedArg("下", 0x0, "文泉驿微米黑", 16, 0);
wMButton9->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton9->onEventHandler(Event::PRESSED, this, (EHandler) &Frm05::wMButton9_prs_cb);
wMButton9->onEventHandler(Event::RELEASED, this, (EHandler) &Frm05::wMButton9_rls_cb);
/*----------------------------- Button : wMButton10 -----------------------------*/
wMButton10 = new STTButton(p_rt, this, "wMButton10", 0);
wMButton10->setMainArg(957, 85, 66, 48, false);
wMButton10->setPressedArg("-", 0x0, "文泉驿微米黑", 16, 0);
wMButton10->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton10->setReleasedArg("-", 0x0, "文泉驿微米黑", 16, 0);
wMButton10->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton10->onEventHandler(Event::PRESSED, this, (EHandler) &Frm05::wMButton10_prs_cb);
wMButton10->onEventHandler(Event::RELEASED, this, (EHandler) &Frm05::wMButton10_rls_cb);
/*----------------------------- Button : wMButton11 -----------------------------*/
wMButton11 = new STTButton(p_rt, this, "wMButton11", 0);
wMButton11->setMainArg(890, 85, 66, 48, false);
wMButton11->setPressedArg("+", 0x0, "文泉驿微米黑", 16, 0);
wMButton11->setPressedStyle(8, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton11->setReleasedArg("+", 0x0, "文泉驿微米黑", 16, 0);
wMButton11->setReleasedStyle(5, 255, 0xebebeb, 0x999999, 1, 1, 0x999999, 1, 0xebebeb);
wMButton11->onEventHandler(Event::PRESSED, this, (EHandler) &Frm05::wMButton11_prs_cb);
wMButton11->onEventHandler(Event::RELEASED, this, (EHandler) &Frm05::wMButton11_rls_cb);
/*called after widget created.*/
return; //createParts END
}
#include "../src/onvif.h"
static struct OnvifSession *onvif_session;
static vector<struct OnvifData *> vecdata;
void Frm05::onLoad() {
onvif_session = (struct OnvifSession*)malloc(sizeof(struct OnvifSession));
initializeSession(onvif_session);
}
bool Frm05::onClosing() {
return true;
}
void Frm05::onDispose() {
closeSession(onvif_session);
for(auto onvif_data : vecdata) {
free(onvif_data);
}
free(onvif_session);
}
void Frm05::wMButton2_clk_cb(uint16_t code, LvEvent e) {
/*wMButton1(功能键)的点击事件*/
int number_of_cameras = broadcast(onvif_session);
fprintf(stderr, "libonvif found %d cameras\n", number_of_cameras);
for (int i = 0; i<number_of_cameras; i++) {
struct OnvifData *onvif_data = (struct OnvifData*)malloc(sizeof(struct OnvifData));
vecdata.push_back(onvif_data);
prepareOnvifData(i, onvif_session, onvif_data);
wMDropdown1->addOption(to_string(i), onvif_data->camera_name);
}
}
void Frm05::wMButton4_clk_cb(uint16_t code, LvEvent e) {
/*wMButton1(play)的点击事件*/
int icam = wMDropdown1->getSelectedIndex();
if(icam < 0) {
cout<<"please select a camera!"<<endl;
return;
}
string username = wMText2->getText();
string password = wMText3->getText();
if(username == "" || password == "") {
cout<<"please input username or password!"<<endl;
return;
}
struct OnvifData *onvif_data = vecdata[icam];
strcpy(onvif_data->username, username.c_str());
strcpy(onvif_data->password, password.c_str());
fillRTSP(onvif_data);
string url =onvif_data->stream_uri;
url ="rtsp://" + username + ":" + password + "@" + url.substr(7);
cout<<url<<endl;
wMVideo1->setSrc(url.c_str());
wMVideo1->play();
}
void Frm05::wMButton3_prs_cb(uint16_t code, LvEvent e) {
/*wMButton3(左)的按下事件*/
int icam = wMDropdown1->getSelectedIndex();
if(icam < 0) {
cout<<"please select a camera!"<<endl;
return;
}
struct OnvifData *onvif_data = vecdata[icam];
continuousMove(-wMSlider1->getValue() / 10.0, 0, 0, onvif_data);
cout<<"press"<<endl;
}
void Frm05::wMButton3_rls_cb(uint16_t code, LvEvent e) {
/*wMButton3(左)的松开事件*/
moveStop(PAN_TILT_STOP,vecdata[wMDropdown1->getSelectedIndex()]);
cout<<"release"<<endl;
}
void Frm05::wMButton7_prs_cb(uint16_t code, LvEvent e) {
/*wMButton7(右)的按下事件*/
int icam = wMDropdown1->getSelectedIndex();
if(icam < 0) {
cout<<"please select a camera!"<<endl;
return;
}
struct OnvifData *onvif_data = vecdata[icam];
continuousMove(wMSlider1->getValue() / 10.0, 0, 0, onvif_data);
cout<<"press"<<endl;
}
void Frm05::wMButton7_rls_cb(uint16_t code, LvEvent e) {
/*wMButton7(右)的松开事件*/
moveStop(PAN_TILT_STOP,vecdata[wMDropdown1->getSelectedIndex()]);
cout<<"release"<<endl;
}
void Frm05::wMButton8_prs_cb(uint16_t code, LvEvent e) {
/*wMButton8(上)的按下事件*/
int icam = wMDropdown1->getSelectedIndex();
if(icam < 0) {
cout<<"please select a camera!"<<endl;
return;
}
struct OnvifData *onvif_data = vecdata[icam];
continuousMove(0, wMSlider2->getValue() / 10.0, 0, onvif_data);
cout<<"press"<<endl;
}
void Frm05::wMButton8_rls_cb(uint16_t code, LvEvent e) {
/*wMButton8(上)的松开事件*/
moveStop(PAN_TILT_STOP,vecdata[wMDropdown1->getSelectedIndex()]);
cout<<"release"<<endl;
}
void Frm05::wMButton9_prs_cb(uint16_t code, LvEvent e) {
/*wMButton9(下)的按下事件*/
int icam = wMDropdown1->getSelectedIndex();
if(icam < 0) {
cout<<"please select a camera!"<<endl;
return;
}
struct OnvifData *onvif_data = vecdata[icam];
continuousMove(0, -wMSlider2->getValue() / 10.0, 0, onvif_data);
cout<<"press"<<endl;
}
void Frm05::wMButton9_rls_cb(uint16_t code, LvEvent e) {
/*wMButton9(下)的松开事件*/
moveStop(PAN_TILT_STOP,vecdata[wMDropdown1->getSelectedIndex()]);
cout<<"release"<<endl;
}
void Frm05::wMButton10_prs_cb(uint16_t code, LvEvent e) {
/*wMButton8(+)的按下事件*/
int icam = wMDropdown1->getSelectedIndex();
if (icam < 0) {
cout << "please select a camera!" << endl;
return;
}
struct OnvifData *onvif_data = vecdata[icam];
continuousMove(0, 0, wMSlider3->getValue() / 10.0, onvif_data);
cout << "press" << endl;
}
void Frm05::wMButton10_rls_cb(uint16_t code, LvEvent e) {
/*wMButton8(+)的松开事件*/
moveStop(ZOOM_STOP, vecdata[wMDropdown1->getSelectedIndex()]);
cout << "release" << endl;
}
void Frm05::wMButton11_prs_cb(uint16_t code, LvEvent e) {
/*wMButton8(-)的按下事件*/
int icam = wMDropdown1->getSelectedIndex();
if (icam < 0) {
cout << "please select a camera!" << endl;
return;
}
struct OnvifData *onvif_data = vecdata[icam];
continuousMove(0, 0, -wMSlider3->getValue() / 10.0, onvif_data);
cout << "press" << endl;
}
void Frm05::wMButton11_rls_cb(uint16_t code, LvEvent e) {
/*wMButton8(-)的松开事件*/
moveStop(ZOOM_STOP, vecdata[wMDropdown1->getSelectedIndex()]);
cout << "release" << endl;
}
6 操作说明
1. 点击【搜索摄像头】
如局域网内有支持onvif协议的摄像头,会在下拉框中列出。如所买的摄像头支持onvif协议,默认一般是没有启用的,需要进入摄像头去打开这个功能。
2. 下拉框中选择一个摄像头
3. 输入onvif摄像头的用户名和密码(play按钮左侧,注意,不是摄像头的登录用户!)
4. 点击【play】
5. 点击上、下、左、右、+、-进行控制。三个滑块分别为x(水平转动),y(垂直转动),z(缩放)