Files
terebi/Sources/Core/progress_reporter.hpp
T

62 lines
1.8 KiB
C++

#pragma once
#include "player.h"
#include <array>
#include <atomic>
#include <condition_variable>
#include <deque>
#include <functional>
#include <mutex>
#include <string>
#include <string_view>
#include <thread>
namespace playback {
// The decoder owns media/snapshot methods; the writer owns the file after construction.
class ProgressReporter {
public:
explicit ProgressReporter(const std::string &path, std::function<double()> clock = {});
~ProgressReporter();
ProgressReporter(const ProgressReporter &) = delete;
ProgressReporter &operator=(const ProgressReporter &) = delete;
static bool validMediaURL(std::string_view url) noexcept;
static bool validMediaIdentity(std::string_view identity) noexcept;
void begin(const std::string &mediaURL, bool live = false) noexcept;
void observe(const PlayerState &state) noexcept;
void closeMedia() noexcept;
// Call after the decoder joins; drains queued records and joins the writer.
void finish() noexcept;
std::string error() const;
private:
struct Snapshot {
double position = 0;
double duration = 0;
PlayerStatus status = PLAYER_EMPTY;
bool eligible = false;
} snapshot;
std::string mediaURL;
std::function<double()> clock;
bool live = false;
bool hasSnapshot = false;
bool awaitingReady = false;
bool seekPending = false;
bool thresholdReported = false;
bool finished = false;
double lastRecordAt = 0;
int descriptor = -1;
std::thread writer;
mutable std::mutex mutex;
std::condition_variable wake;
std::deque<std::string> records;
std::array<char, 512> failure{};
std::atomic<bool> disabled{false};
bool stopping = false;
bool emit(const char *event) noexcept;
void disable(const char *message, int osError = 0) noexcept;
void writeRecords() noexcept;
};
}