修改dockerfile,增加ffmpeg

This commit is contained in:
zengqile 2026-01-26 10:21:21 +08:00
parent 3683bd94d6
commit 005168b8e1
5 changed files with 244 additions and 213 deletions

View File

@ -1,213 +1,213 @@
{ {
"video_service": { "video_service": {
"enabled": true "enabled": true
}, },
"video_streams": [ "video_streams": [
{ {
"enabled": true, "enabled": true,
"id": "cam_01_intrusion", "id": "cam_01_intrusion",
"input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/3101", "input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/3101",
"module_config": { "module_config": {
"class_num": 3, "class_num": 3,
"intrusion_zone": [ "intrusion_zone": [
[ [
4, 4,
8 8
], ],
[ [
1057, 1057,
13 13
], ],
[ [
1053, 1053,
267 267
], ],
[ [
1347, 1347,
289 289
], ],
[ [
1365, 1365,
8 8
], ],
[ [
1911, 1911,
6 6
], ],
[ [
1898, 1898,
1077 1077
], ],
[ [
7, 7,
1077 1077
] ]
], ],
"label_path": "/app/models/human.txt", "label_path": "/app/models/human.txt",
"light_device_ids": [ "light_device_ids": [
"351", "351",
"352", "352",
"353", "353",
"349", "349",
"354", "354",
"350" "350"
], ],
"mode": 2, "mode": 1,
"model_path": "/app/models/human_detection.rknn", "model_path": "/app/models/human_detection.rknn",
"rknn_thread_num": 3, "rknn_thread_num": 3,
"time_threshold_sec": 3 "time_threshold_sec": 3
}, },
"module_type": "human_detection", "module_type": "human_detection",
"output_rtsp": "rtsp://127.0.0.1:8554/ch1901" "output_rtsp": "rtsp://127.0.0.1:8554/ch1901"
}, },
{ {
"enabled": true, "enabled": true,
"id": "cam_02_intrusion", "id": "cam_02_intrusion",
"input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/3201", "input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/3201",
"module_config": { "module_config": {
"class_num": 3, "class_num": 3,
"intrusion_zone": [ "intrusion_zone": [
[ [
11, 11,
13 13
], ],
[ [
1907, 1907,
13 13
], ],
[ [
1911, 1911,
1074 1074
], ],
[ [
7, 7,
1070 1070
] ]
], ],
"label_path": "/app/models/human.txt", "label_path": "/app/models/human.txt",
"light_device_ids": [ "light_device_ids": [
"351", "351",
"352", "352",
"353", "353",
"349", "349",
"354", "354",
"350" "350"
], ],
"mode": 2, "mode": 1,
"model_path": "/app/models/human_detection.rknn", "model_path": "/app/models/human_detection.rknn",
"rknn_thread_num": 3, "rknn_thread_num": 3,
"time_threshold_sec": 3 "time_threshold_sec": 3
}, },
"module_type": "human_detection", "module_type": "human_detection",
"output_rtsp": "rtsp://127.0.0.1:8554/ch1801" "output_rtsp": "rtsp://127.0.0.1:8554/ch1801"
}, },
{ {
"enabled": true, "enabled": true,
"id": "cam_03_intrusion", "id": "cam_03_intrusion",
"input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/1601", "input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/1601",
"module_config": { "module_config": {
"class_num": 3, "class_num": 3,
"intrusion_zone": [ "intrusion_zone": [
[ [
20, 20,
19 19
], ],
[ [
1891, 1891,
35 35
], ],
[ [
1433, 1433,
466 466
], ],
[ [
1006, 1006,
619 619
], ],
[ [
1210, 1210,
1001 1001
], ],
[ [
1201, 1201,
1072 1072
], ],
[ [
2, 2,
1077 1077
] ]
], ],
"label_path": "/app/models/human.txt", "label_path": "/app/models/human.txt",
"model_path": "/app/models/human_detection.rknn", "model_path": "/app/models/human_detection.rknn",
"rknn_thread_num": 3, "rknn_thread_num": 3,
"time_threshold_sec": 3 "time_threshold_sec": 3
}, },
"module_type": "human_detection", "module_type": "human_detection",
"output_rtsp": "rtsp://127.0.0.1:8554/ch2201" "output_rtsp": "rtsp://127.0.0.1:8554/ch2201"
}, },
{ {
"enabled": false, "enabled": false,
"id": "cam_04_intrusion", "id": "cam_04_intrusion",
"input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/1101", "input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/1101",
"module_config": { "module_config": {
"class_num": 3, "class_num": 3,
"intrusion_zone": [ "intrusion_zone": [
[ [
400, 400,
400 400
], ],
[ [
800, 800,
400 400
], ],
[ [
900, 900,
600 600
], ],
[ [
300, 300,
600 600
] ]
], ],
"label_path": "/app/models/human.txt", "label_path": "/app/models/human.txt",
"model_path": "/app/models/human_detection.rknn", "model_path": "/app/models/human_detection.rknn",
"rknn_thread_num": 3, "rknn_thread_num": 3,
"time_threshold_sec": 3 "time_threshold_sec": 3
}, },
"module_type": "human_detection", "module_type": "human_detection",
"output_rtsp": "rtsp://127.0.0.1:8554/ch1201" "output_rtsp": "rtsp://127.0.0.1:8554/ch1201"
}, },
{ {
"enabled": false, "enabled": false,
"id": "cam_01_intrusion", "id": "cam_01_intrusion",
"input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/1101", "input_url": "rtsp://admin:hzx12345@192.168.1.10:554/Streaming/Channels/1101",
"module_config": { "module_config": {
"class_num": 3, "class_num": 3,
"intrusion_zone": [ "intrusion_zone": [
[ [
400, 400,
400 400
], ],
[ [
800, 800,
400 400
], ],
[ [
900, 900,
600 600
], ],
[ [
300, 300,
600 600
] ]
], ],
"label_path": "/app/models/human.txt", "label_path": "/app/models/human.txt",
"model_path": "/app/models/human_detection.rknn", "model_path": "/app/models/human_detection.rknn",
"rknn_thread_num": 3, "rknn_thread_num": 3,
"time_threshold_sec": 3 "time_threshold_sec": 3
}, },
"module_type": "human_detection", "module_type": "human_detection",
"output_rtsp": "rtsp://127.0.0.1:8554/ch1101" "output_rtsp": "rtsp://127.0.0.1:8554/ch1101"
} }
] ]
} }

View File

@ -95,6 +95,7 @@ RUN unzip -q /tmp/librga-1.10.0.zip -d /tmp/ && \
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------
RUN apt-get update && \ RUN apt-get update && \
apt-get install -y --no-install-recommends \ apt-get install -y --no-install-recommends \
ffmpeg \
gstreamer1.0-rockchip \ gstreamer1.0-rockchip \
libgstreamer1.0-dev \ libgstreamer1.0-dev \
libgstreamer-plugins-base1.0-dev \ libgstreamer-plugins-base1.0-dev \

View File

@ -9,6 +9,7 @@ LightController::LightController(std::string baseUrl, std::string token)
: baseUrl(baseUrl), token(token) { : baseUrl(baseUrl), token(token) {
// 启动后台工作线程 // 启动后台工作线程
running_ = true; running_ = true;
InitializeDevices();
worker_thread_ = std::thread(&LightController::WorkerLoop, this); worker_thread_ = std::thread(&LightController::WorkerLoop, this);
spdlog::info("[LightController] Worker thread started."); spdlog::info("[LightController] Worker thread started.");
} }
@ -97,7 +98,11 @@ void LightController::UpdateAutoLight(std::string deviceId, std::string sourceId
bool is_on = !votes.empty(); bool is_on = !votes.empty();
// 只有状态改变才触发 // 只有状态改变才触发
if (was_on != is_on) { if (was_on != is_on || deviceStatus[deviceId]) {
if (deviceStatus[deviceId]) {
spdlog::info("[AutoLight] ForceControll.");
}
deviceStatus[deviceId] = false;
std::string action = is_on ? "1" : "0"; std::string action = is_on ? "1" : "0";
spdlog::info("[AutoLight] Logic Change: Device {} -> {}", deviceId, is_on ? "ON" : "OFF"); spdlog::info("[AutoLight] Logic Change: Device {} -> {}", deviceId, is_on ? "ON" : "OFF");
@ -126,7 +131,11 @@ void LightController::RemoveSession(std::string sourceId) {
votes.erase(sourceId); votes.erase(sourceId);
bool is_on = !votes.empty(); bool is_on = !votes.empty();
if (was_on && !is_on) { if ((was_on && !is_on) || deviceStatus[deviceId]) {
if (deviceStatus[deviceId]) {
spdlog::info("[AutoLight] ForceControll.");
}
deviceStatus[deviceId] = false;
spdlog::info("[AutoLight] Source {} disconnect. Turning OFF {}.", sourceId, spdlog::info("[AutoLight] Source {} disconnect. Turning OFF {}.", sourceId,
deviceId); deviceId);
{ {

View File

@ -20,6 +20,9 @@ public:
void UpdateAutoLight(std::string deviceId, std::string sourceId, bool voteOn); void UpdateAutoLight(std::string deviceId, std::string sourceId, bool voteOn);
void RemoveSession(std::string sourceId); void RemoveSession(std::string sourceId);
public:
std::map<std::string, bool> deviceStatus;
private: private:
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp); static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp);
bool SendHttpCommand(std::string deviceId, std::string switchType); bool SendHttpCommand(std::string deviceId, std::string switchType);
@ -41,4 +44,14 @@ private:
// 待执行的任务表Key=设备ID, Value=动作("1"或"0") // 待执行的任务表Key=设备ID, Value=动作("1"或"0")
// 使用 map 的好处是:同一个设备的多次指令会自动覆盖,只保留最新的! // 使用 map 的好处是:同一个设备的多次指令会自动覆盖,只保留最新的!
std::map<std::string, std::string> pending_actions_; std::map<std::string, std::string> pending_actions_;
void InitializeDevices() {
// 假设这些是你的设备 ID
std::vector<std::string> deviceIds = {"349", "350", "351", "352", "353", "354"};
// 遍历 ID 并初始化为 false
for (const auto& id : deviceIds) {
deviceStatus[id] = false;
}
}
}; };

View File

@ -781,6 +781,7 @@ void WebServer::setup_routes() {
auto service = m_video_manager.getService(stream_id); auto service = m_video_manager.getService(stream_id);
if (service) { if (service) {
service->set_analysis_mode(1); service->set_analysis_mode(1);
affected_streams.push_back(stream_id); affected_streams.push_back(stream_id);
} }
} }
@ -961,6 +962,7 @@ void WebServer::setup_routes() {
* - mode: 1 (), 2 () * - mode: 1 (), 2 ()
*/ */
CROW_ROUTE((*this), "/api/video/mode").methods("POST"_method)([this](const crow::request& req) { CROW_ROUTE((*this), "/api/video/mode").methods("POST"_method)([this](const crow::request& req) {
LightController* ctrl = &m_light_controller;
crow::json::rvalue j_body; crow::json::rvalue j_body;
try { try {
j_body = crow::json::load(req.body); j_body = crow::json::load(req.body);
@ -980,6 +982,12 @@ void WebServer::setup_routes() {
if (service) { if (service) {
// 调用内存中的对象修改状态 // 调用内存中的对象修改状态
bool result = service->set_analysis_mode(mode); bool result = service->set_analysis_mode(mode);
if (mode == 2) {
for (auto& [id, status] : ctrl->deviceStatus){
status = true;
spdlog::info("force controll set:{}", status);
}
}
if (!result) { if (!result) {
spdlog::warn("Failed to set runtime mode for stream {}", stream_id); spdlog::warn("Failed to set runtime mode for stream {}", stream_id);
// 注意:这里即使运行时失败,只要配置能保存,也可以继续往下走,或者直接返回错误 // 注意:这里即使运行时失败,只要配置能保存,也可以继续往下走,或者直接返回错误