From be9f5bcc14c79514fb148ecf41f3c985373a6cad Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Mon, 15 Dec 2025 02:23:49 -0500 Subject: [PATCH] cleanups for hls. --- lib/http_handlers.h | 59 ++++++++++++++++++++++++++++++--------------- lib/raop.c | 15 +++++------- lib/raop.h | 4 +-- uxplay.cpp | 1 - 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/lib/http_handlers.h b/lib/http_handlers.h index 4f14c26..aa88f20 100644 --- a/lib/http_handlers.h +++ b/lib/http_handlers.h @@ -158,7 +158,7 @@ http_handler_set_property(raop_conn_t *conn, selectedMediaArray contains plist with language choice: */ - airplay_video_t *airplay_video = raop->airplay_video[raop->current_video]; + airplay_video_t *airplay_video = (airplay_video_t *) raop_get_current_video(raop); if (!strcmp(property, "selectedMediaArray")) { /* verify that this request contains a binary plist*/ char *header_str = NULL; @@ -438,7 +438,7 @@ http_handler_action(raop_conn_t *conn, http_request_t *request, http_response_t char **response_data, int *response_datalen) { raop_t *raop = conn->raop; - airplay_video_t *airplay_video = raop->airplay_video[raop->current_video]; + airplay_video_t *airplay_video = (airplay_video_t *) raop_get_current_video(raop); bool data_is_plist = false; plist_t req_root_node = NULL; uint64_t uint_val = 0; @@ -689,6 +689,21 @@ http_handler_action(raop_conn_t *conn, http_request_t *request, http_response_t "start position in seconds". Once this request is received by the Sever, the Server sends a POST /event "FCUP Request" request to the Client on the reverse http channel, to request the HLS Master Playlist */ +static void +delete_short_playlist(raop_t *raop, int id) { + if (!raop->airplay_video[id]) { + return; + } + float duration = get_duration(raop->airplay_video[id]); + if (duration < (float) MIN_STORED_AIRPLAY_VIDEO_DURATION_SECONDS ) { //likely to be an advertisement + logger_log(raop->logger, LOGGER_INFO, + "deleting playlist playback_uuid %s duration (seconds) %f", + get_playback_uuid(raop->airplay_video[id]), duration); + airplay_video_destroy(raop->airplay_video[id]); + raop->airplay_video[id] = NULL; + } +} + static void http_handler_play(raop_conn_t *conn, http_request_t *request, http_response_t *response, char **response_data, int *response_datalen) { @@ -735,7 +750,6 @@ http_handler_play(raop_conn_t *conn, http_request_t *request, http_response_t *r char* playback_uuid = NULL; plist_get_string_val(req_uuid_node, &playback_uuid); - /* check if playlist is already dowloaded and stored (may have been interruoted by advertisements ) */ #if 0 for (int i = 0; i < MAX_AIRPLAY_VIDEO; i++) { printf("old: airplay_video[%d] %p %s %f\n", i, raop->airplay_video[i], @@ -748,9 +762,16 @@ http_handler_play(raop_conn_t *conn, http_request_t *request, http_response_t *r int id = -1; id = get_playlist_by_uuid(raop, playback_uuid); + + /* check if playlist is already dowloaded and stored (may have been interruoted by advertisements ) */ if (id >= 0) { printf("use: airplay_video[%d] %p %s %s\n", id, airplay_video, playback_uuid, get_playback_uuid(airplay_video)); - airplay_video = raop->airplay_video[id]; + int current_video = raop->current_video; + if (current_video >= 0 && current_video != id) { + delete_short_playlist(raop, current_video); + } + raop->current_video = id; + airplay_video = raop_get_current_video(raop); assert(airplay_video); set_apple_session_id(airplay_video, apple_session_id, strlen(apple_session_id)); raop->callbacks.on_video_play(raop->callbacks.cls, @@ -765,17 +786,10 @@ http_handler_play(raop_conn_t *conn, http_request_t *request, http_response_t *r int count = 0; for (int i = 0; i < MAX_AIRPLAY_VIDEO; i++) { if (raop->airplay_video[i]) { - float duration = get_duration(raop->airplay_video[i]); - if (duration < (float) MIN_STORED_AIRPLAY_VIDEO_DURATION_SECONDS ) { - logger_log(raop->logger, LOGGER_INFO, - "deleting playlist playback_uuid %s duration (seconds) %f", - get_playback_uuid(raop->airplay_video[i]), duration); - airplay_video_destroy(raop->airplay_video[i]); - raop->airplay_video[i] = NULL; - } else { - count++; - //printf(" %d %d duration %f : keep\n", i, count, duration); - } + delete_short_playlist(raop, i); + } + if (raop->airplay_video[i]) { + count++; } } @@ -793,12 +807,12 @@ http_handler_play(raop_conn_t *conn, http_request_t *request, http_response_t *r exit(1); } - airplay_video = airplay_video_init(raop, raop->port, raop->lang); + raop->current_video = id; + raop->airplay_video[id] = airplay_video_init(raop, raop->port, raop->lang); + airplay_video = raop_get_current_video(raop); if (airplay_video) { set_playback_uuid(airplay_video, playback_uuid, strlen(playback_uuid)); plist_mem_free (playback_uuid); - raop->current_video = id; - raop->airplay_video[id] = airplay_video; count++; printf("created new airplay_video %p %s\n\n", airplay_video, get_playback_uuid(airplay_video)); } else { @@ -906,7 +920,12 @@ static void http_handler_hls(raop_conn_t *conn, http_request_t *request, http_response_t *response, char **response_data, int *response_datalen) { raop_t *raop = conn->raop; - airplay_video_t *airplay_video = raop->airplay_video[raop->current_video]; + if (raop->current_video == -1) { + logger_log(raop->logger, LOGGER_ERR,"airplay_video playlist not found"); + *response_datalen = 0; + http_response_init(response, "HTTP/1.1", 404, "Not Found"); + return; + } const char *method = http_request_get_method(request); assert (!strcmp(method, "GET")); const char *url = http_request_get_url(request); @@ -920,7 +939,7 @@ http_handler_hls(raop_conn_t *conn, http_request_t *request, http_response_t *r free (header_str); return; } - + airplay_video_t *airplay_video = (airplay_video_t *) raop_get_current_video(raop); if (!strcmp(url, "/master.m3u8")){ char * master_playlist = get_master_playlist(airplay_video); if (master_playlist) { diff --git a/lib/raop.c b/lib/raop.c index 5a47883..d57dad2 100644 --- a/lib/raop.c +++ b/lib/raop.c @@ -863,16 +863,13 @@ void raop_playlist_remove(raop_t *raop, void *opaque, float position_seconds) { } } -int raop_current_playlist_delete(raop_t *raop) { - int current_video = raop->current_video; - assert (current_video < MAX_AIRPLAY_VIDEO); - if (current_video >= 0) { - raop_destroy_airplay_video(raop, current_video); - raop->current_video = -1; - } else { - logger_log(raop->logger, LOGGER_ERR, "raop_current_playlist_delete: failed to identify current_playlist"); +void *raop_get_current_video(raop_t *raop) { + if (raop->current_video < 0) { + logger_log(raop->logger, LOGGER_ERR, "raop_get_current_video: failed to identify current_playlist"); + return NULL; } - return current_video; + assert(raop->airplay_video[raop->current_video]); + return (void *) raop->airplay_video[raop->current_video]; } int get_playlist_by_uuid(raop_t *raop, const char *uuid) { diff --git a/lib/raop.h b/lib/raop.h index 915e9f2..2201187 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -111,7 +111,8 @@ airplay_video_t *airplay_video_init(raop_t *raop, unsigned short port, const cha int get_playlist_by_uuid(raop_t *raop, const char *uuid); char *raop_get_lang(raop_t *raop); uint64_t get_local_time(); - +void *raop_get_current_video(raop_t *raop); + RAOP_API raop_t *raop_init(raop_callbacks_t *callbacks); RAOP_API int raop_init2(raop_t *raop, int nohold, const char *device_id, const char *keyfile); RAOP_API void raop_set_log_level(raop_t *raop, int level); @@ -131,7 +132,6 @@ RAOP_API void raop_destroy(raop_t *raop); RAOP_API void raop_remove_known_connections(raop_t * raop); RAOP_API void raop_remove_hls_connections(raop_t * raop); RAOP_API void raop_destroy_airplay_video(raop_t *raop, int id); -RAOP_API int raop_current_playlist_delete(raop_t *raop); RAOP_API void raop_playlist_remove(raop_t *raop, void *airplay_video, float position); #ifdef __cplusplus diff --git a/uxplay.cpp b/uxplay.cpp index e320343..6e57199 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -727,7 +727,6 @@ static void main_loop() { if (gst_audio_bus_watch_id[i] > 0) g_source_remove(gst_audio_bus_watch_id[i]); } if (gst_x11_window_id > 0) g_source_remove(gst_x11_window_id); - if (video_eos_watch_id > 0) g_source_remove(video_eos_watch_id); if (reset_watch_id > 0) g_source_remove(reset_watch_id); if (progress_id > 0) g_source_remove(progress_id); if (video_eos_watch_id > 0) g_source_remove(video_eos_watch_id);