Files
terebi/Sources/Core/player.h
T

95 lines
4.4 KiB
C

#ifndef PERSONAL_PLAYER_H
#define PERSONAL_PLAYER_H
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Player Player;
typedef enum PlayerStatus {
PLAYER_EMPTY, PLAYER_OPENING, PLAYER_PAUSED, PLAYER_PLAYING,
PLAYER_ENDED, PLAYER_ERROR
} PlayerStatus;
typedef struct PlayerState {
PlayerStatus status;
double position;
double duration;
// Contiguous retained/playable network range on the position timeline.
// The start may include reusable rewind history; the end includes read-ahead.
// Empty/unavailable (including local playback and pending seeks) is 0, 0.
double buffered_start;
double buffered_end;
bool has_audio;
bool has_video;
// False for live/non-seekable inputs; reflects both inputs for separate streams.
bool can_seek;
// Network playback is waiting for media; the authoritative clock remains stalled.
bool buffering;
// True until all accepted seeks/frame steps on this timeline finish.
bool seek_pending;
// Display width / height, including sample aspect ratio; zero without video.
double video_aspect_ratio;
uint64_t revision;
char error[512];
} PlayerState;
// Playback commands are asynchronous. False means invalid input or a full command queue.
// Paths are copied before returning. All other calls require a live handle.
Player *player_create(void);
// Opt-in reporting must be initialized before opening media. Creates a new 0600
// file exclusively; errors never change playback state. Error buffers hold 512 bytes.
bool player_set_progress_file(Player *player, const char *path, char *error);
// Register immutable queue destinations without changing current playback. Each path is new;
// revisits append only to the original owned inode. Conflicting identities/paths are rejected.
// Atomic batch: all registrations succeed or none do. Strings are copied before returning.
bool player_register_progress_files(Player *player, const char *const *identities,
const char *const *paths, int count, char *error);
bool player_get_progress_error(Player *player, char *error);
// Stops the worker and drains final reporting, allowing errors to be shown before
// destroying the handle. Idempotent; do not call from an audio callback.
bool player_shutdown(Player *player, char *progress_error);
typedef struct PlayerNetworkSource {
// Primary video or combined audio/video HTTP(S) URL; audio_url is optional.
const char *video_url;
const char *audio_url;
// Optional HTTP headers encoded as "Name: value\r\n"; copied with the URLs.
const char *video_headers;
const char *audio_headers;
double duration;
bool is_live;
// Original HTTP(S) video URL (canonical for YouTube), or stable
// miruro:<base64url media_id>:<positive episode> identity, never an extracted CDN URL.
// NULL/empty means no reporting for this source.
const char *media_url;
// Initial restored position, applied before publishing ready state. Zero
// starts at the beginning; out-of-duration bookmarks also start at zero.
double initial_position;
} PlayerNetworkSource;
bool player_open(Player *player, const char *path);
// Streams directly; never downloads or muxes the entire media file before opening.
bool player_open_network(Player *player, const PlayerNetworkSource *source);
bool player_play(Player *player);
bool player_pause(Player *player);
bool player_seek(Player *player, double seconds);
// Direction must be -1 (previous) or +1 (next). Requires ready video media.
// Pauses playback and selects the adjacent decoded presentation frame.
bool player_step_frame(Player *player, int direction);
bool player_close(Player *player);
// Receiver-confirmed Cast facts replace decoder facts in progress reporting until
// the next open/close. The local decoder must be paused before submitting them.
bool player_report_remote_state(Player *player, const PlayerState *state);
// Synchronous, thread-safe gain; survives open, seek, and close. Zero mutes.
// Rejects null handles and non-finite/out-of-range values without changing gain.
bool player_set_volume(Player *player, float normalized0to1);
// Returns the target gain immediately; zero for a null handle.
float player_get_volume(Player *player);
PlayerState player_get_state(Player *player);
// Joins the worker and stops audio; never invoke from an audio callback.
void player_destroy(Player *player);
#ifdef __cplusplus
}
#endif
#endif