新增录像功能开关
This commit is contained in:
parent
2cdd2d4f4f
commit
7c90feb3f7
@ -73,6 +73,7 @@ struct MQTTConfig
|
||||
// ------------------- 总配置 -------------------
|
||||
struct AppConfig
|
||||
{
|
||||
bool record_enabled = true;
|
||||
std::vector<Camera> cameras;
|
||||
MQTTConfig mqtt;
|
||||
|
||||
@ -90,6 +91,9 @@ struct AppConfig
|
||||
json j;
|
||||
ifs >> j;
|
||||
|
||||
cfg.record_enabled = j.value("record_enabled", true);
|
||||
LOG_INFO("[Config] Global record_enabled = " + std::string(cfg.record_enabled ? "true" : "false"));
|
||||
|
||||
// 读取摄像头
|
||||
if (j.contains("cameras"))
|
||||
{
|
||||
|
||||
@ -47,6 +47,8 @@ class RTMPManager
|
||||
static void set_live_enabled_all(bool enable);
|
||||
static void set_live_enabled(const std::string& cam_name, bool enable);
|
||||
|
||||
static bool g_record_enabled;
|
||||
|
||||
private:
|
||||
struct StreamContext
|
||||
{
|
||||
@ -57,6 +59,7 @@ class RTMPManager
|
||||
std::mutex status_mutex;
|
||||
|
||||
GstElement* live_valve{nullptr};
|
||||
GstElement* record_valve = nullptr;
|
||||
};
|
||||
|
||||
static void stream_loop(Camera cam, StreamContext* ctx);
|
||||
@ -65,6 +68,7 @@ class RTMPManager
|
||||
|
||||
static std::unordered_map<std::string, std::unique_ptr<StreamContext>> streams;
|
||||
static std::mutex streams_mutex;
|
||||
|
||||
static std::atomic<bool> g_live_enabled;
|
||||
|
||||
static constexpr int RETRY_BASE_DELAY_MS = 3000;
|
||||
|
||||
@ -61,6 +61,8 @@ int main()
|
||||
// ---------- 初始化 GStreamer ----------
|
||||
RTMPManager::init();
|
||||
|
||||
RTMPManager::g_record_enabled = g_app_config.record_enabled;
|
||||
|
||||
// ---------- 自动推流(8 路录像守护) ----------
|
||||
LOG_INFO("[MAIN] Starting all record streams...");
|
||||
RTMPManager::start_all();
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include <thread>
|
||||
|
||||
std::atomic<bool> RTMPManager::g_live_enabled{false};
|
||||
bool RTMPManager::g_record_enabled = true;
|
||||
|
||||
// =======================================================
|
||||
// 工具函数
|
||||
@ -89,8 +90,10 @@ GstElement* RTMPManager::create_pipeline(const Camera& cam)
|
||||
"! h264parse config-interval=1 "
|
||||
"! tee name=t "
|
||||
|
||||
// ===== record:永远稳定 =====
|
||||
// ===== record:可开关 =====
|
||||
"t. ! queue max-size-buffers=8 leaky=downstream "
|
||||
"! valve name=record_valve drop=true " // ★★ 新增
|
||||
"! queue max-size-buffers=8 leaky=downstream "
|
||||
"! flvmux name=rec_mux streamable=true "
|
||||
"! rtmpsink name=rec_sink location=\"" +
|
||||
record_rtmp +
|
||||
@ -173,6 +176,30 @@ void RTMPManager::stream_loop(Camera cam, StreamContext* ctx)
|
||||
ctx->live_valve = live_valve; // ⚠️ live_valve 引用交给 ctx 管理
|
||||
}
|
||||
|
||||
// 2.x 获取 record_valve
|
||||
GstElement* record_valve = gst_bin_get_by_name(GST_BIN(pipeline), "record_valve");
|
||||
if (!record_valve)
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(ctx->status_mutex);
|
||||
ctx->status.running = false;
|
||||
ctx->status.last_error = "record_valve not found";
|
||||
}
|
||||
LOG_ERROR("[RTMP] " + key + " - record_valve not found");
|
||||
gst_object_unref(pipeline);
|
||||
std::this_thread::sleep_for(std::chrono::seconds(3));
|
||||
continue;
|
||||
}
|
||||
|
||||
// 保存到 ctx
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(ctx->status_mutex);
|
||||
if (ctx->record_valve) gst_object_unref(ctx->record_valve);
|
||||
ctx->record_valve = record_valve;
|
||||
}
|
||||
|
||||
g_object_set(G_OBJECT(ctx->record_valve), "drop", g_record_enabled.load() ? FALSE : TRUE, nullptr);
|
||||
|
||||
g_object_set(G_OBJECT(ctx->live_valve), "drop", g_live_enabled.load() ? FALSE : TRUE, nullptr);
|
||||
|
||||
GstBus* bus = gst_element_get_bus(pipeline);
|
||||
@ -248,11 +275,18 @@ void RTMPManager::stream_loop(Camera cam, StreamContext* ctx)
|
||||
cleanup:
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(ctx->status_mutex);
|
||||
|
||||
if (ctx->live_valve)
|
||||
{
|
||||
gst_object_unref(ctx->live_valve);
|
||||
ctx->live_valve = nullptr;
|
||||
}
|
||||
|
||||
if (ctx->record_valve)
|
||||
{
|
||||
gst_object_unref(ctx->record_valve);
|
||||
ctx->record_valve = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
@ -317,11 +351,18 @@ void RTMPManager::stop_all()
|
||||
kv.second->thread_running.store(false);
|
||||
|
||||
std::lock_guard<std::mutex> lk(kv.second->status_mutex);
|
||||
|
||||
if (kv.second->live_valve)
|
||||
{
|
||||
gst_object_unref(kv.second->live_valve);
|
||||
kv.second->live_valve = nullptr;
|
||||
}
|
||||
|
||||
if (kv.second->record_valve)
|
||||
{
|
||||
gst_object_unref(kv.second->record_valve);
|
||||
kv.second->record_valve = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto& kv : streams)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user