使用
需要先定义一个 DeviceManager 类对象(设备管理器类),再调用其中的 enumerate() 函数来遍历设备获得设备对象列表。
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto streamDocks = manager.getStreamDocks();
获取到设备对象列表以后,使用设备时需要先调用 wakeupScreen() 方法唤醒设备,再调用其它方法操作设备
auto it = streamDocks.begin();
auto device = it->second;
device->wakeupScreen();
// 设置亮度
device->setKeyBrightness(100);
示例
基础示例
#include <iostream>
#include <memory>
#include <thread>
#include <chrono>
#include "DeviceManager/devicemanager.h"
#include "HotspotDevice/StreamDockN4/streamdockN4.h"
#include "ImgProcesser/OpenCVImageEncoder/OpenCVImageEncoder.h"
int main()
{
// 获取设备管理器实例
DeviceManager &manager = DeviceManager::instance();
// 枚举当前连接的设备
manager.enumerator();
auto &streamDocks = manager.getStreamDocks();
std::cout << "发现 " << streamDocks.size() << " 台设备" << std::endl;
if (streamDocks.empty()) {
std::cout << "未发现任何StreamDock设备" << std::endl;
return 0;
}
// 启动设备监听线程,处理热插拔
manager.listen([](std::shared_ptr<StreamDock> device) {
std::cout << "新设备连接: " << device->info()->serialNumber << std::endl;
device->wakeupScreen();
device->setKeyBrightness(100);
});
// 处理已连接的设备
for (const auto &devicePair : streamDocks) {
auto device = devicePair.second;
// 唤醒屏幕
device->wakeupScreen();
// 设置图像编码器
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// 设置背景图片
device->setBackgroundImgFile("./img/background.jpg");
device->refresh();
// 设置按键图片
device->setKeyImgFile("./img/key1.jpg", 1);
device->setKeyImgFile("./img/key2.jpg", 2);
device->refresh();
// 启动读取循环
device->reader()->startReadLoop();
// 注册按键事件回调
device->reader()->registerReadCallback(1, []() {
std::cout << "按键1被按下" << std::endl;
}, RegisterEvent::KeyPress);
device->reader()->registerReadCallback(2, []() {
std::cout << "按键2被按下" << std::endl;
}, RegisterEvent::KeyPress);
}
std::cout << "按Enter键退出..." << std::endl;
std::cin.get();
// 停止监听
manager.stopListen();
return 0;
}
多设备支持示例
#include <iostream>
#include <memory>
#include "DeviceManager/devicemanager.h"
#include "HotspotDevice/StreamDockN4/streamdockN4.h"
#include "HotspotDevice/StreamDockM18/streamdockM18.h"
#include "ImgProcesser/OpenCVImageEncoder/OpenCVImageEncoder.h"
void handleN4Device(std::shared_ptr<StreamDock> device) {
std::cout << "处理N4设备" << std::endl;
device->wakeupScreen();
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// N4特有功能:设置第二屏幕
device->setBackgroundImgFile("./img/n4_background.jpg");
device->refresh();
// 注册旋钮事件
device->reader()->registerReadCallback(16, []() {
std::cout << "旋钮1左转" << std::endl;
}, RegisterEvent::KnobLeft);
device->reader()->registerReadCallback(17, []() {
std::cout << "旋钮1右转" << std::endl;
}, RegisterEvent::KnobRight);
// 注册触摸屏滑动事件
device->reader()->registerReadCallback(28, []() {
std::cout << "触摸屏左滑" << std::endl;
}, RegisterEvent::SwipeLeft);
}
void handleM18Device(std::shared_ptr<StreamDock> device) {
std::cout << "处理M18设备" << std::endl;
device->wakeupScreen();
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// M18特有功能:设置LED颜色
device->rgber()->setLedColor(255, 0, 0); // 红色
device->rgber()->setLedBrightness(50);
// 设置背景动画
device->gifer()->setBackgroundGifFile("./img/background.gif");
device->gifer()->startGifLoop();
}
int main() {
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto &devices = manager.getStreamDocks();
// 根据设备类型进行不同处理
for (const auto &devicePair : devices) {
auto device = devicePair.second;
device->reader()->startReadLoop();
switch (device->info()->originType) {
case DeviceOriginType::SDN4:
handleN4Device(device);
break;
case DeviceOriginType::SDM18:
handleM18Device(device);
break;
default:
std::cout << "未知设备类型" << std::endl;
break;
}
}
std::cout << "按Enter键退出..." << std::endl;
std::cin.get();
return 0;
}
GIF动画示例
#include <iostream>
#include <memory>
#include "DeviceManager/devicemanager.h"
#include "ImgProcesser/OpenCVImageEncoder/OpenCVImageEncoder.h"
int main() {
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto &devices = manager.getStreamDocks();
for (const auto &devicePair : devices) {
auto device = devicePair.second;
// 检查设备是否支持GIF
if (!device->feature()->isDualDevice) {
std::cout << "设备不支持GIF功能" << std::endl;
continue;
}
device->wakeupScreen();
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// 设置按键GIF动画
device->gifer()->setKeyGifFile("./img/animation1.gif", 1);
device->gifer()->setKeyGifFile("./img/animation2.gif", 2);
device->gifer()->setKeyGifFile("./img/animation3.gif", 3);
// 设置背景GIF动画(如果支持)
if (device->feature()->supportBackGroundGif) {
device->gifer()->setBackgroundGifFile("./img/background.gif");
}
// 启动GIF循环
device->gifer()->startGifLoop();
std::cout << "GIF动画已启动" << std::endl;
}
std::cout << "按Enter键退出..." << std::endl;
std::cin.get();
return 0;
}
错误处理示例
#include <iostream>
#include <memory>
#include "DeviceManager/devicemanager.h"
#include "ImgProcesser/OpenCVImageEncoder/OpenCVImageEncoder.h"
int main() {
try {
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto &devices = manager.getStreamDocks();
if (devices.empty()) {
std::cout << "未发现任何设备,请检查:" << std::endl;
std::cout << "1. 设备是否正确连接" << std::endl;
std::cout << "2. 是否有足够的权限访问设备" << std::endl;
std::cout << "3. udev规则是否正确配置" << std::endl;
return 1;
}
for (const auto &devicePair : devices) {
auto device = devicePair.second;
try {
device->wakeupScreen();
device->setEncoder(std::make_shared<OpenCVImageEncoder>());
// 尝试设置图像
device->setBackgroundImgFile("./img/background.jpg");
// 检查是否有错误
std::wstring error = device->lastError();
if (!error.empty()) {
std::wcout << L"设备错误: " << error << std::endl;
continue;
}
device->refresh();
std::cout << "设备初始化成功" << std::endl;
} catch (const std::exception &e) {
std::cout << "设备操作失败: " << e.what() << std::endl;
}
}
} catch (const std::exception &e) {
std::cout << "程序异常: " << e.what() << std::endl;
return 1;
}
std::cout << "按Enter键退出..." << std::endl;
std::cin.get();
return 0;
}
设备热插拔监听
#include <iostream>
#include <memory>
#include "DeviceManager/devicemanager.h"
int main() {
DeviceManager &manager = DeviceManager::instance();
// 启动设备监听
manager.listen([](std::shared_ptr<StreamDock> device) {
std::cout << "设备连接: " << device->info()->serialNumber << std::endl;
std::cout << "设备类型: " << static_cast<int>(device->info()->originType) << std::endl;
// 自动初始化新连接的设备
device->wakeupScreen();
device->setKeyBrightness(80);
});
std::cout << "设备监听已启动,可以插拔设备进行测试" << std::endl;
std::cout << "按Enter键退出..." << std::endl;
std::cin.get();
manager.stopListen();
return 0;
}
多线程处理
#include <iostream>
#include <memory>
#include <thread>
#include <atomic>
#include "DeviceManager/devicemanager.h"
std::atomic<bool> running(true);
void deviceReadThread(std::shared_ptr<StreamDock> device) {
uint8_t response[64];
size_t length;
while (running) {
try {
device->reader()->read(response, &length, 100);
if (length > 0) {
std::cout << "收到数据: ";
for (size_t i = 0; i < length; i++) {
printf("%02X ", response[i]);
}
std::cout << std::endl;
}
} catch (const std::exception &e) {
std::cout << "读取线程异常: " << e.what() << std::endl;
break;
}
}
}
int main() {
DeviceManager &manager = DeviceManager::instance();
manager.enumerator();
auto &devices = manager.getStreamDocks();
if (devices.empty()) {
std::cout << "未发现设备" << std::endl;
return 0;
}
// 为每个设备创建读取线程
std::vector<std::thread> readThreads;
for (const auto &devicePair : devices) {
auto device = devicePair.second;
device->wakeupScreen();
// 创建读取线程
readThreads.emplace_back(deviceReadThread, device);
}
std::cout << "多线程处理已启动,按Enter键退出..." << std::endl;
std::cin.get();
running = false;
// 等待所有线程结束
for (auto &thread : readThreads) {
if (thread.joinable()) {
thread.join();
}
}
return 0;
}
