#pragma once #include "media/types.hpp" #include "media/plugin_manager.hpp" #include #include #include #include #include #include namespace media { /** * TV Engine Configuration */ struct TvEngineConfig { // General int max_channels = 5; // Video settings struct Resolution { std::string name; int width; int height; int bitrate_kbps; }; std::vector resolutions = { {"1080p", 1920, 1080, 5000}, {"720p", 1280, 720, 2500}, {"480p", 854, 480, 1000} }; std::string default_video_codec = "h264"; std::string video_preset = "fast"; // Audio settings std::string default_audio_codec = "aac"; int audio_bitrate_kbps = 128; int audio_sample_rate = 48000; // HLS settings std::string hls_output_dir = "/data/hls/tv"; int hls_segment_duration = 4; int hls_playlist_size = 10; // EPG settings int epg_lookahead_hours = 24; int epg_refresh_interval_minutes = 15; // Notification callback NotificationCallback notification_callback; }; /** * Internal TV Channel State */ struct TvChannelState { TvChannelConfig config; TvChannelStatus status; // Schedule std::vector schedule; size_t current_program_index = 0; // Streaming state std::atomic is_running{false}; std::thread stream_thread; std::condition_variable cv; std::mutex mutex; // Current playback position std::chrono::system_clock::time_point playback_position; // FFmpeg process handles per resolution std::map encoder_handles; // Statistics std::chrono::system_clock::time_point started_at; std::atomic viewer_count{0}; }; /** * TV Engine * * Manages TV channel simulation with scheduling, EPG generation, * multi-resolution HLS output, and commercial/bumper insertion. */ class TvEngine { public: TvEngine(); ~TvEngine(); // Disable copying TvEngine(const TvEngine&) = delete; TvEngine& operator=(const TvEngine&) = delete; // ======================================================================== // Initialization // ======================================================================== /** * Initialize the TV engine * @param config Engine configuration * @param plugin_manager Plugin manager for video processing * @return Result indicating success or failure */ Result initialize( const TvEngineConfig& config, PluginManager* plugin_manager ); /** * Shutdown all channels and cleanup */ void shutdown(); // ======================================================================== // Channel Management // ======================================================================== /** * Create a new TV channel * @param config Channel configuration * @return Result with channel ID or error */ Result create_channel(const TvChannelConfig& config); /** * Delete a TV channel * @param channel_id Channel ID * @return Result indicating success or failure */ Result delete_channel(const std::string& channel_id); /** * Update channel configuration * @param channel_id Channel ID * @param config New configuration * @return Result indicating success or failure */ Result update_channel( const std::string& channel_id, const TvChannelConfig& config ); /** * Get channel status * @param channel_id Channel ID * @return Result with channel status or error */ Result get_channel_status( const std::string& channel_id ) const; /** * List all channels * @param tenant_id Filter by tenant (empty for all) * @return Vector of channel statuses */ std::vector list_channels( const std::string& tenant_id = "" ) const; // ======================================================================== // Streaming Control // ======================================================================== /** * Start streaming a channel * @param channel_id Channel ID * @return Result with stream URLs or error */ struct StreamUrls { std::string hls_url; std::string dash_url; std::map quality_urls; // resolution -> URL }; Result start_channel(const std::string& channel_id); /** * Stop streaming a channel * @param channel_id Channel ID * @return Result indicating success or failure */ Result stop_channel(const std::string& channel_id); // ======================================================================== // Schedule Management // ======================================================================== /** * Set channel schedule * @param channel_id Channel ID * @param entries Schedule entries * @return Result indicating success or failure */ Result set_schedule( const std::string& channel_id, const std::vector& entries ); /** * Add program to schedule * @param channel_id Channel ID * @param entry Schedule entry * @return Result indicating success or failure */ Result add_program( const std::string& channel_id, const TvScheduleEntry& entry ); /** * Remove program from schedule * @param channel_id Channel ID * @param program_id Program ID * @return Result indicating success or failure */ Result remove_program( const std::string& channel_id, const std::string& program_id ); /** * Get channel schedule * @param channel_id Channel ID * @param start_time Start of time range * @param end_time End of time range * @return Result with schedule or error */ Result> get_schedule( const std::string& channel_id, std::chrono::system_clock::time_point start_time, std::chrono::system_clock::time_point end_time ) const; // ======================================================================== // EPG (Electronic Program Guide) // ======================================================================== /** * Generate EPG for all channels * @param hours_ahead Hours of programming to include * @return Vector of EPG entries */ std::vector generate_epg(int hours_ahead = 24) const; /** * Generate EPG for specific channel * @param channel_id Channel ID * @param hours_ahead Hours of programming * @return Result with EPG entries or error */ Result> generate_channel_epg( const std::string& channel_id, int hours_ahead = 24 ) const; /** * Export EPG as XMLTV format * @param hours_ahead Hours of programming * @return XMLTV formatted string */ std::string export_xmltv(int hours_ahead = 24) const; // ======================================================================== // Now Playing // ======================================================================== /** * Get current program * @param channel_id Channel ID * @return Result with current program or error */ Result get_now_playing(const std::string& channel_id) const; /** * Get next program * @param channel_id Channel ID * @return Result with next program or error */ Result get_next_program(const std::string& channel_id) const; // ======================================================================== // Interstitials (Bumpers/Commercials) // ======================================================================== /** * Set channel bumpers * @param channel_id Channel ID * @param intro_bumper Path to intro bumper video * @param outro_bumper Path to outro bumper video * @return Result indicating success or failure */ Result set_bumpers( const std::string& channel_id, const std::string& intro_bumper, const std::string& outro_bumper ); /** * Set commercial break playlist * @param channel_id Channel ID * @param commercials List of commercial video paths * @param break_duration_seconds Target break duration * @return Result indicating success or failure */ Result set_commercials( const std::string& channel_id, const std::vector& commercials, int break_duration_seconds = 120 ); // ======================================================================== // Statistics // ======================================================================== /** * Update viewer count (called by stream server) * @param channel_id Channel ID * @param delta Change in viewer count */ void update_viewer_count(const std::string& channel_id, int delta); /** * Get total viewer count across all channels */ int get_total_viewers() const; private: /** * Stream thread function */ void stream_thread(const std::string& channel_id); /** * Get current program based on schedule */ const TvScheduleEntry* get_current_scheduled_program( const TvChannelState& state ) const; /** * Prepare next segment */ void prepare_next_segment(TvChannelState& state); /** * Encode video segment */ void encode_segment( TvChannelState& state, const std::string& input_path, double start_time, double duration ); /** * Generate HLS master playlist */ void generate_master_playlist(const std::string& channel_id); /** * Update variant playlists */ void update_variant_playlist( const std::string& channel_id, const std::string& resolution, const std::string& segment_filename ); /** * Insert bumper/commercial */ void insert_interstitial( TvChannelState& state, const std::string& video_path ); // Configuration TvEngineConfig config_; PluginManager* plugin_manager_ = nullptr; // State std::atomic initialized_{false}; // Channels mutable std::mutex channels_mutex_; std::map> channels_; // EPG refresh thread std::thread epg_thread_; std::atomic epg_running_{false}; }; } // namespace media