Player: runtime source override and play-a-URL on /api/player

The player now owns the effective mode (config or override) and passes it
down: spotify_apply(enable) and hls_set_url(url) instead of both reading
source.mode from the config. /api/player/source forces spotify|hls|off
(config returns to the saved mode), /api/player/url plays an m3u8 now;
neither is saved. GET reports it in `forced`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-25 23:15:38 +10:00
parent fd88e02e96
commit e5c3c0ad8a
6 changed files with 105 additions and 31 deletions
+14 -10
View File
@@ -4,7 +4,6 @@
#include <stdlib.h>
#include <string.h>
#include "aes67_cfg.h"
#include "esp_crt_bundle.h"
#include "esp_heap_caps.h"
#include "esp_http_client.h"
@@ -13,7 +12,7 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define URL_MAX 384
#define URL_MAX HLS_URL_MAX
#define PLAYLIST_MAX (64 * 1024)
#define MAX_SEGMENTS 64
#define LIVE_BACK 3 // start this many segments behind the live edge
@@ -33,7 +32,9 @@ typedef struct {
static hls_sink_t s_sink;
static char *s_text; // playlist buffer (PSRAM)
static media_pl_t *s_pl; // parsed media playlist (PSRAM)
static char s_url[URL_MAX]; // configured URL
static char s_url[URL_MAX]; // URL being played
static char s_want_url[URL_MAX]; // from hls_set_url(), guarded by s_url_lock
static portMUX_TYPE s_url_lock = portMUX_INITIALIZER_UNLOCKED;
static char s_media_url[URL_MAX];
static uint8_t *s_seg; // current segment (PSRAM)
static volatile unsigned s_suspended; // HLS_SUSPEND_* bits
@@ -47,15 +48,18 @@ void hls_suspend(unsigned reason, bool suspend)
}
}
// hls_url when source.mode needs HLS, else "".
void hls_set_url(const char *url)
{
taskENTER_CRITICAL(&s_url_lock);
strlcpy(s_want_url, url, sizeof(s_want_url));
taskEXIT_CRITICAL(&s_url_lock);
}
static void wanted_url(char *out, size_t n)
{
cJSON *src = cfg_get("source");
const char *mode = cJSON_GetObjectItemCaseSensitive(src, "mode")->valuestring;
const char *url = cJSON_GetObjectItemCaseSensitive(src, "hls_url")->valuestring;
bool on = !strcmp(mode, "hls") || !strcmp(mode, "auto");
strlcpy(out, on ? url : "", n);
cJSON_Delete(src);
taskENTER_CRITICAL(&s_url_lock);
strlcpy(out, s_want_url, n);
taskEXIT_CRITICAL(&s_url_lock);
}
static bool still_wanted(void)