// camera_to_rtsp.cpp #include #include #include #include #include #include #include #include #include #include using json = nlohmann::json; GMainLoop *loop = nullptr; // 全局退出标志 std::atomic g_running(true); // Ctrl+C 信号处理 void signalHandler(int signum) { g_running = false; if (loop) g_main_loop_quit(loop); } // GStreamer 日志处理 void gstreamer_log_handler(const gchar *domain, GLogLevelFlags level, const gchar *message, gpointer) { if (level & G_LOG_LEVEL_ERROR) std::cerr << "[GStreamer-ERROR] " << (domain ? domain : "unknown") << ": " << message << std::endl; } // 初始化 GStreamer void init_gstreamer() { gst_init(nullptr, nullptr); g_log_set_default_handler(gstreamer_log_handler, nullptr); // 设置GStreamer调试级别为警告及以上 setenv("GST_DEBUG", "*:2", 1); } // 摄像头结构体 struct Camera { std::string device; std::string name; int width, height, fps; bool enabled; GstElement *src = nullptr; GstRTSPMediaFactory *factory = nullptr; }; // 创建RTSP媒体工厂 GstRTSPMediaFactory *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; } // 主函数 int main() { signal(SIGINT, signalHandler); signal(SIGPIPE, SIG_IGN); init_gstreamer(); // 读取配置文件 std::ifstream ifs("config.json"); if (!ifs.is_open()) { std::cerr << "Failed to open config.json" << std::endl; return -1; } json j; ifs >> j; std::vector cameras; for (auto &c : j["cameras"]) { Camera cam; cam.device = c["device"]; cam.name = c["name"]; cam.width = c["width"]; cam.height = c["height"]; cam.fps = c["fps"]; cam.enabled = c["enabled"]; if (cam.enabled) { cameras.push_back(cam); } } // 创建RTSP服务器 GstRTSPServer *server = gst_rtsp_server_new(); gst_rtsp_server_set_service(server, "8554"); // 设置RTSP服务器端口 // 获取服务器挂载点 GstRTSPMountPoints *mounts = gst_rtsp_server_get_mount_points(server); // 为每个摄像头创建媒体工厂并添加到挂载点 for (auto &cam : cameras) { if (!cam.enabled) continue; cam.factory = create_media_factory(cam); std::string mount_point = "/" + cam.name; gst_rtsp_mount_points_add_factory(mounts, mount_point.c_str(), cam.factory); std::cout << "Camera '" << cam.name << "' available at rtsp://localhost:8554" << mount_point << std::endl; } // 释放挂载点引用 g_object_unref(mounts); // 附加服务器到默认主上下文 loop = g_main_loop_new(nullptr, FALSE); gst_rtsp_server_attach(server, nullptr); std::cout << "RTSP server running on rtsp://localhost:8554" << std::endl; std::cout << "Press Ctrl+C to stop" << std::endl; g_main_loop_run(loop); // 运行主循环 // 清理资源 g_object_unref(server); g_main_loop_unref(loop); std::cout << "RTSP server stopped." << std::endl; return 0; }