#pragma once #include #include #include #include #include #include #include struct StreamStats { int64_t currentConnections = 0; // Raw connection count from OME int64_t uniqueViewers = 0; // Unique viewer tokens int64_t totalConnections = 0; int64_t totalBytesIn = 0; int64_t totalBytesOut = 0; double bitrate = 0.0; std::string codec; std::string resolution; double fps = 0.0; bool isLive = false; std::chrono::system_clock::time_point lastUpdated; // Protocol-specific connections struct ProtocolConnections { int64_t webrtc = 0; int64_t hls = 0; int64_t llhls = 0; int64_t dash = 0; } protocolConnections; // Connection history for deduplication std::chrono::system_clock::time_point lastConnectionDrop; int64_t previousTotalConnections = 0; }; class StatsService { public: static StatsService& getInstance() { static StatsService instance; return instance; } void initialize(); void shutdown(); // Get cached stats from Redis void getStreamStats(const std::string& streamKey, std::function callback); // Force update stats for a specific stream void updateStreamStats(const std::string& streamKey); // Get unique viewer count for a stream int64_t getUniqueViewerCount(const std::string& streamKey); private: StatsService() = default; ~StatsService(); StatsService(const StatsService&) = delete; StatsService& operator=(const StatsService&) = delete; bool getPreviousStats(const std::string& streamKey, StreamStats& stats); void pollOmeStats(); void storeStatsInRedis(const std::string& streamKey, const StreamStats& stats); void fetchStatsFromOme(const std::string& streamKey, std::function callback); void updateRealmLiveStatus(const std::string& streamKey, const StreamStats& stats); std::atomic running_{false}; std::optional timerId_; std::chrono::seconds pollInterval_{2}; // Poll every 2 seconds };