kunlang_video/src/rtsp_manager.cpp
2025-09-09 09:57:24 +08:00

111 lines
3.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// rtsp_manager.cpp
#include "rtsp_manager.hpp"
#include "logger.hpp"
#include <iostream>
// 静态变量定义
GMainLoop *RTSPManager::loop = nullptr;
GstRTSPServer *RTSPManager::server = nullptr;
std::unordered_map<std::string, bool> RTSPManager::streaming_status; // 播放状态表
void RTSPManager::init()
{
gst_init(nullptr, nullptr);
LOG_INFO("[RTSP] GStreamer initialized.");
}
GstRTSPMediaFactory *RTSPManager::create_media_factory(const Camera &cam)
{
std::string launch_str =
"( v4l2src device=" + cam.device +
" ! video/x-raw,format=NV12,width=" + std::to_string(cam.width) +
",height=" + std::to_string(cam.height) +
",framerate=" + std::to_string(cam.fps) + "/1"
" ! videoconvert ! queue ! mpph264enc ! rtph264pay name=pay0 pt=96 )";
GstRTSPMediaFactory *factory = gst_rtsp_media_factory_new();
gst_rtsp_media_factory_set_launch(factory, launch_str.c_str());
gst_rtsp_media_factory_set_shared(factory, TRUE);
return factory;
}
void RTSPManager::start(const std::vector<Camera> &cameras)
{
server = gst_rtsp_server_new();
gst_rtsp_server_set_service(server, "8554");
// === 不再在启动时挂载摄像头,由调度指令控制推流 ===
loop = g_main_loop_new(nullptr, FALSE);
gst_rtsp_server_attach(server, nullptr);
LOG_INFO("[RTSP] Server running on rtsp://localhost:8554");
g_main_loop_run(loop);
// loop 退出后再释放资源
if (server)
{
g_object_unref(server);
server = nullptr;
}
if (loop)
{
g_main_loop_unref(loop);
loop = nullptr;
}
LOG_INFO("[RTSP] Server stopped.");
}
// === 新增方法:挂载摄像头 ===
void RTSPManager::mount_camera(const Camera &cam)
{
if (!server)
return;
GstRTSPMountPoints *mounts = gst_rtsp_server_get_mount_points(server);
auto factory = create_media_factory(cam);
std::string mount_point = "/" + cam.name;
gst_rtsp_mount_points_add_factory(mounts, mount_point.c_str(), factory);
g_object_unref(mounts);
streaming_status[cam.name] = true; // === 更新播放状态 ===
LOG_INFO("[RTSP] Camera '" + cam.name + "' mounted at rtsp://localhost:8554" + mount_point);
}
// === 新增方法:卸载摄像头 ===
void RTSPManager::unmount_camera(const Camera &cam)
{
if (!server)
return;
GstRTSPMountPoints *mounts = gst_rtsp_server_get_mount_points(server);
std::string mount_point = "/" + cam.name;
gst_rtsp_mount_points_remove_factory(mounts, mount_point.c_str());
g_object_unref(mounts);
streaming_status[cam.name] = false; // === 更新播放状态 ===
LOG_INFO("[RTSP] Camera '" + cam.name + "' unmounted.");
}
bool RTSPManager::is_streaming(const std::string &cam_name)
{
auto it = streaming_status.find(cam_name);
if (it != streaming_status.end())
return it->second;
return false; // 默认未推流
}
void RTSPManager::stop()
{
if (loop)
{
// 仅退出 loop不 unref server
g_main_context_invoke(nullptr, [](gpointer data) -> gboolean
{
GMainLoop *loop = static_cast<GMainLoop*>(data);
g_main_loop_quit(loop);
return G_SOURCE_REMOVE; }, loop);
}
}