mirror of
https://github.com/johndoe6345789/metabuilder.git
synced 2026-04-25 14:25:02 +00:00
397 lines
11 KiB
C++
397 lines
11 KiB
C++
#pragma once
|
|
|
|
#include "media/types.hpp"
|
|
#include "media/plugin_manager.hpp"
|
|
#include <memory>
|
|
#include <map>
|
|
#include <mutex>
|
|
#include <thread>
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
|
|
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<Resolution> 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<TvScheduleEntry> schedule;
|
|
size_t current_program_index = 0;
|
|
|
|
// Streaming state
|
|
std::atomic<bool> 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<std::string, void*> encoder_handles;
|
|
|
|
// Statistics
|
|
std::chrono::system_clock::time_point started_at;
|
|
std::atomic<int> 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<void> 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<std::string> create_channel(const TvChannelConfig& config);
|
|
|
|
/**
|
|
* Delete a TV channel
|
|
* @param channel_id Channel ID
|
|
* @return Result indicating success or failure
|
|
*/
|
|
Result<void> 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<void> 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<TvChannelStatus> 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<TvChannelStatus> 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<std::string, std::string> quality_urls; // resolution -> URL
|
|
};
|
|
Result<StreamUrls> start_channel(const std::string& channel_id);
|
|
|
|
/**
|
|
* Stop streaming a channel
|
|
* @param channel_id Channel ID
|
|
* @return Result indicating success or failure
|
|
*/
|
|
Result<void> 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<void> set_schedule(
|
|
const std::string& channel_id,
|
|
const std::vector<TvScheduleEntry>& entries
|
|
);
|
|
|
|
/**
|
|
* Add program to schedule
|
|
* @param channel_id Channel ID
|
|
* @param entry Schedule entry
|
|
* @return Result indicating success or failure
|
|
*/
|
|
Result<void> 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<void> 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<std::vector<TvScheduleEntry>> 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<EpgEntry> 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<std::vector<EpgEntry>> 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<TvProgram> 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<TvProgram> 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<void> 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<void> set_commercials(
|
|
const std::string& channel_id,
|
|
const std::vector<std::string>& 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<bool> initialized_{false};
|
|
|
|
// Channels
|
|
mutable std::mutex channels_mutex_;
|
|
std::map<std::string, std::unique_ptr<TvChannelState>> channels_;
|
|
|
|
// EPG refresh thread
|
|
std::thread epg_thread_;
|
|
std::atomic<bool> epg_running_{false};
|
|
};
|
|
|
|
} // namespace media
|