1
This commit is contained in:
parent
d802f80213
commit
befef76a3e
@ -14,6 +14,12 @@
|
||||
|
||||
#include "logger.hpp"
|
||||
|
||||
static bool device_exists(const std::string &path)
|
||||
{
|
||||
struct stat st;
|
||||
return (stat(path.c_str(), &st) == 0);
|
||||
}
|
||||
|
||||
static std::string get_ip_address(const std::string &ifname)
|
||||
{
|
||||
struct ifaddrs *ifaddr, *ifa;
|
||||
@ -129,6 +135,14 @@ RTMPManager::StreamResultInfo RTMPManager::start_camera(const Camera &cam, Strea
|
||||
return res;
|
||||
}
|
||||
|
||||
// 新增:设备节点存在性检查
|
||||
if (!device_exists(cam.device))
|
||||
{
|
||||
res.result = 1;
|
||||
res.reason = "Device not found: " + cam.device;
|
||||
return res;
|
||||
}
|
||||
|
||||
const std::string key = make_stream_key(cam.name, type);
|
||||
|
||||
std::unique_ptr<StreamContext> ctx;
|
||||
@ -139,15 +153,13 @@ RTMPManager::StreamResultInfo RTMPManager::start_camera(const Camera &cam, Strea
|
||||
auto it = streams.find(key);
|
||||
if (it != streams.end() && it->second->running.load())
|
||||
{
|
||||
res.result = 0;
|
||||
res.result = 1; // 修改为 1:表示重复启动,不是真成功
|
||||
res.reason = "Already streaming";
|
||||
return res;
|
||||
}
|
||||
|
||||
ctx = std::make_unique<StreamContext>();
|
||||
ctx->running.store(true);
|
||||
|
||||
// 重要:在把 ctx 放入 map 之前,先从 ctx->start_promise 拿到 future
|
||||
status_future = ctx->start_promise.get_future();
|
||||
|
||||
StreamContext *ctx_ptr = ctx.get();
|
||||
@ -202,7 +214,7 @@ RTMPManager::StreamResultInfo RTMPManager::stop_camera(const std::string &cam_na
|
||||
streams.erase(it);
|
||||
}
|
||||
|
||||
bool was_running = ctx->status.running; // ✅ 新增:判断是否真的在推流
|
||||
bool was_running = ctx->running.load(); // ✅ 改为使用 running
|
||||
ctx->running.store(false);
|
||||
|
||||
if (ctx->thread.joinable()) ctx->thread.join();
|
||||
@ -262,17 +274,15 @@ void RTMPManager::stream_loop(Camera cam, StreamType type, StreamContext *ctx)
|
||||
|
||||
while (true)
|
||||
{
|
||||
// 手动停止
|
||||
if (!ctx->running.load())
|
||||
{
|
||||
status.running = false;
|
||||
status.last_result = StreamResult::UNKNOWN;
|
||||
status.last_error = "Stream stopped manually";
|
||||
try_set_start(status); // 若启动阶段还没返回,这里补一次
|
||||
try_set_start(status);
|
||||
break;
|
||||
}
|
||||
|
||||
// 首帧超时(5s)
|
||||
if (!first_frame &&
|
||||
std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - t0).count() > 5)
|
||||
{
|
||||
@ -301,8 +311,7 @@ void RTMPManager::stream_loop(Camera cam, StreamType type, StreamContext *ctx)
|
||||
status.running = true;
|
||||
ctx->status.running = true;
|
||||
status.last_result = StreamResult::OK;
|
||||
status.last_error.clear();
|
||||
try_set_start(status); // 首帧成功:通知 start_camera
|
||||
try_set_start(status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -331,19 +340,21 @@ void RTMPManager::stream_loop(Camera cam, StreamType type, StreamContext *ctx)
|
||||
|
||||
gst_message_unref(msg);
|
||||
|
||||
// 错误/EOS 后退出循环
|
||||
if (status.last_result == StreamResult::CONNECTION_FAIL || status.last_result == StreamResult::EOS_RECEIVED)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
if (bus) gst_object_unref(bus);
|
||||
gst_object_unref(pipeline);
|
||||
if (pipeline)
|
||||
{
|
||||
gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
gst_object_unref(pipeline);
|
||||
}
|
||||
if (bus)
|
||||
{
|
||||
gst_object_unref(bus);
|
||||
}
|
||||
|
||||
ctx->status.running = false;
|
||||
// 线程收尾:这里不要删 map 里的 ctx,stop_camera 已经负责转移并 join
|
||||
}
|
||||
|
||||
void RTMPManager::stop_all()
|
||||
@ -400,21 +411,24 @@ std::vector<RTMPManager::StreamResultInfo> RTMPManager::process_push_request(con
|
||||
|
||||
for (int ch : item.channels)
|
||||
{
|
||||
if (ch < 0 || ch >= static_cast<int>(g_app_config.cameras.size())) continue;
|
||||
if (ch < 0 || ch >= static_cast<int>(g_app_config.cameras.size()))
|
||||
{
|
||||
StreamResultInfo info;
|
||||
info.loc = ch;
|
||||
info.result = 1;
|
||||
info.reason = "Invalid channel index";
|
||||
info.url = "";
|
||||
results.push_back(info);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto &cam = g_app_config.cameras[ch];
|
||||
StreamResultInfo info;
|
||||
|
||||
if (item.switchVal == 0)
|
||||
{
|
||||
// 开启推流
|
||||
info = start_camera(cam, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 停止推流
|
||||
info = stop_camera(cam.name, type);
|
||||
}
|
||||
|
||||
results.push_back(info);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user