#pragma once #include "../../include/Program.hpp" #include #include // TODO: Sync sequence for video and audio (for live stream). namespace QuickMedia { class YoutubeMediaProxy { public: enum Error { OK, ERROR }; virtual ~YoutubeMediaProxy() = default; virtual bool start(const std::string &youtube_media_url, int64_t content_length) = 0; // This should be the last call. Do not call |start| after this. TODO: Allow restarting with |start| after |stop| is called. virtual void stop() = 0; virtual Error update() = 0; virtual bool get_address(std::string &address) = 0; bool start_download(const std::string &media_url, ReadProgram &read_program, int64_t range_start, int64_t end_range, bool include_header); }; class YoutubeStaticMediaProxy : public YoutubeMediaProxy { public: YoutubeStaticMediaProxy(); YoutubeStaticMediaProxy(YoutubeStaticMediaProxy&) = delete; YoutubeStaticMediaProxy&operator=(YoutubeStaticMediaProxy&) = delete; ~YoutubeStaticMediaProxy(); bool start(const std::string &youtube_media_url, int64_t content_length) override; void stop() override; Error update() override; bool get_address(std::string &address) override; private: void on_client_disconnect(); Error read_client_data(); void clear_download_state(); // If |new_range_start| is not -1 then the start range is set to that Error update_download_program_status(bool client_disconnected, int64_t new_range_start = -1, bool restart_download = false); Error continue_send(const char *buffer_start, size_t total_bytes_to_write, int &buffer_offset); Error handle_download(); // Returns the client fd or -1 int accept_client(); private: int socket_fd = -1; int port = 0; int client_fd = -1; std::string youtube_media_url; int64_t content_length = 0; ReadProgram downloader_read_program; int download_read_buffer_offset = 0; ssize_t downloader_num_read_bytes = 0; int64_t download_range_start = 0; int64_t current_download_range = 0; int64_t next_range_length = 0; std::string download_header; bool end_of_file = false; bool download_header_finished = false; bool download_header_sent = false; bool download_header_remaining_sent = false; int download_header_written_offset = 0; int download_header_offset_to_end_of_header = 0; int64_t download_start_time = 0; int64_t total_downloaded_bytes = 0; bool download_started = false; bool client_request_finished = false; std::string client_request_buffer; char download_read_buffer[16384]; }; }