feat: stream YouTube video with coordinated audio and video inputs
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.
This commit is contained in:
@@ -17,6 +17,10 @@ typedef struct PlayerState {
|
||||
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.
|
||||
@@ -28,7 +32,19 @@ typedef struct 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);
|
||||
|
||||
Reference in New Issue
Block a user