From 501df4056b8b2318701041e6fcd6e16f03dd1732 Mon Sep 17 00:00:00 2001 From: "F. Duncanh" Date: Tue, 2 Dec 2025 01:04:17 -0500 Subject: [PATCH] HLS removePlaylist improvements --- lib/http_handlers.h | 70 ++++++++++++++++++++++++--------------------- lib/raop.c | 4 +-- lib/raop.h | 2 +- uxplay.cpp | 4 +-- 4 files changed, 43 insertions(+), 37 deletions(-) diff --git a/lib/http_handlers.h b/lib/http_handlers.h index 732cbaa..3ad5e85 100644 --- a/lib/http_handlers.h +++ b/lib/http_handlers.h @@ -493,12 +493,11 @@ http_handler_action(raop_conn_t *conn, http_request_t *request, http_response_t if (PLIST_IS_DICT (req_root_node)) { req_params_node = plist_dict_get_item(req_root_node, "params"); } - if (strcmp(type,"playlistInsert") && !PLIST_IS_DICT (req_params_node)) { //bypass if type=playlistInsert until we have see its plist + if (!PLIST_IS_DICT (req_params_node)) { goto post_action_error; } if (!strcmp(type,"playlistRemove")) { - logger_log(conn->raop->logger, LOGGER_INFO, "unhandled action type playlistRemove (stop playback)"); plist_t req_params_item_node = plist_dict_get_item(req_params_node, "item"); if (!req_params_item_node || !PLIST_IS_DICT (req_params_item_node)) { goto post_action_error; @@ -506,41 +505,48 @@ http_handler_action(raop_conn_t *conn, http_request_t *request, http_response_t plist_t req_params_item_uuid_node = plist_dict_get_item(req_params_item_node, "uuid"); char* remove_uuid = NULL; plist_get_string_val(req_params_item_uuid_node, &remove_uuid); - const char *playback_uuid = get_playback_uuid(airplay_video); - if (remove_uuid) { - if (strcmp(remove_uuid, playback_uuid)) { - logger_log(conn->raop->logger, LOGGER_ERR, "uuid of playlist removal action request did not match current playlist:\n" - " current: %s\n remove: %s", playback_uuid, remove_uuid); + assert(remove_uuid); + int id = get_playlist_by_uuid(conn->raop, remove_uuid); + if (id == conn->raop->current_video) { + conn->raop->current_video = -1; + float position = conn->raop->callbacks.on_video_playlist_remove(conn->raop->callbacks.cls); + float duration = get_duration(airplay_video); + if (duration < (float) MIN_STORED_AIRPLAY_VIDEO_DURATION_SECONDS) { + airplay_video_destroy(airplay_video); /* short duration == probably advertisements */ + conn->raop->airplay_video[id] = NULL; } else { - logger_log(conn->raop->logger, LOGGER_DEBUG, "removal_uuid matches playback_uuid\n"); - } - plist_mem_free (remove_uuid); + set_resume_position_seconds(airplay_video, position); + conn->raop->interrupted_video = id; + } + } else { + logger_log(conn->raop->logger, LOGGER_WARNING, "playlistRemove uuid %s does not match current_video\n", remove_uuid); } + plist_mem_free (remove_uuid); } else if (!strcmp(type, "playlistInsert")) { - logger_log(conn->raop->logger, LOGGER_ERR, "FIXME: playlist insertion not yet implemented"); - logger_log(conn->raop->logger, LOGGER_INFO, "unhandled action type playlistInsert (add new playback)"); - - printf("\n***************FIXME************************\nPlaylist insertion needs more information for it to be implemented:\n" - "please report following output as an \"Issue\" at http://github.com/FDH2/UxPlay:\n"); - char *header_str = NULL; - http_request_get_header_string(request, &header_str); - printf("\n\n%s\n", header_str); - bool data_is_plist = (strstr(header_str,"apple-binary-plist") != NULL); - free(header_str); - if (data_is_plist) { - int request_datalen; - const char *request_data = http_request_get_data(request, &request_datalen); - plist_t req_root_node = NULL; - plist_from_bin(request_data, request_datalen, &req_root_node); - char *plist_xml = NULL; - uint32_t plist_len = 0; - plist_to_xml(req_root_node, &plist_xml, &plist_len); - printf("plist_len = %u\n", plist_len); - printf("%s\n", plist_xml); - plist_mem_free(plist_xml); - exit(0); + logger_log(conn->raop->logger, LOGGER_INFO, "action type playlistInsert (start playback)"); + plist_t req_params_item_node = plist_dict_get_item(req_params_node, "item"); + if (!req_params_item_node || !PLIST_IS_DICT (req_params_item_node)) { + goto post_action_error; } + plist_t req_params_item_uuid_node = plist_dict_get_item(req_params_item_node, "uuid"); + char* remove_uuid = NULL; + plist_get_string_val(req_params_item_uuid_node, &remove_uuid); + if (remove_uuid) { + int id = get_playlist_by_uuid(conn->raop, remove_uuid); + if (id >= 0) { + logger_log(conn->raop->logger, LOGGER_INFO, "playlistInsert uuid %s is stored at airplay_video[%d]", remove_uuid, id); + } else { + logger_log(conn->raop->logger, LOGGER_INFO, "playlistInsert uuid %s is not a stored playlist", remove_uuid); + } + plist_mem_free(remove_uuid); + char *plist_xml = NULL; + uint32_t plist_len = 0; + plist_to_xml(req_params_item_node, &plist_xml, &plist_len); + printf("playlistInsert parameter item list is:\n%s", plist_xml); + plist_mem_free(plist_xml); + } + logger_log(conn->raop->logger, LOGGER_ERR, "FIXME: playlistInsert is not yet implemented"); } else if (!strcmp(type, "unhandledURLResponse")) { /* handling type "unhandledURLResponse" (case 1)*/ diff --git a/lib/raop.c b/lib/raop.c index b755e10..7ca3f62 100644 --- a/lib/raop.c +++ b/lib/raop.c @@ -85,7 +85,7 @@ struct raop_s { /* place to store media_data_store */ airplay_video_t *airplay_video[MAX_AIRPLAY_VIDEO]; int current_video; - int removed_video; + int interrupted_video; /* activate support for HLS live streaming */ bool hls_support; @@ -603,7 +603,7 @@ raop_init(raop_callbacks_t *callbacks) { /* initialize airplay_video */ raop->current_video = -1; - raop->removed_video = -1; + raop->interrupted_video = -1; for (int i= 0; i < MAX_AIRPLAY_VIDEO; i++) { raop->airplay_video[i] = NULL; } diff --git a/lib/raop.h b/lib/raop.h index 4d537bf..42a111a 100644 --- a/lib/raop.h +++ b/lib/raop.h @@ -99,7 +99,7 @@ struct raop_callbacks_s { void (*on_video_rate) (void *cls, const float rate); void (*on_video_stop) (void *cls); void (*on_video_acquire_playback_info) (void *cls, playback_info_t *playback_video); - void (*on_video_playlist_remove) (void *cls, void *airplay_video); + float (*on_video_playlist_remove) (void *cls); }; typedef struct raop_callbacks_s raop_callbacks_t; diff --git a/uxplay.cpp b/uxplay.cpp index 5e4dfed..73c5911 100644 --- a/uxplay.cpp +++ b/uxplay.cpp @@ -2498,14 +2498,14 @@ extern "C" void on_video_rate(void *cls, const float rate) { -extern "C" void on_video_playlist_remove (void *cls, void *airplay_video) { +extern "C" float on_video_playlist_remove (void *cls) { double duration, position; float rate; bool buffer_empty, buffer_full; LOGI("************************* on_video_playlist_remove\n"); video_renderer_pause(); video_get_playback_info(&duration, &position, &rate, &buffer_empty, &buffer_full); - raop_playlist_remove(raop, airplay_video, (float) position); + return (float) position; } extern "C" void on_video_stop(void *cls) {