8fb08db6f3
Resolve public YouTube URLs through external yt-dlp and play selected streams in the existing native window. Independent bounded network readers keep one authored timeline. Successful seeks clear FFmpeg's sticky aborted-read AVIO error; manifest seekability uses native format flags rather than a top-level I/O handle. Verified real YouTube playback, seeking, frame stepping, compact mode, cancellation, and the complete native regression checks.
68 lines
2.5 KiB
C
68 lines
2.5 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;
|
|
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);
|
|
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;
|
|
} 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);
|
|
// 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
|