meowpanel: 新增 /api/audio(audiod MSG_AUDIO_QUERY→STATE 透传, 不在时 available:false)+ 前端「音频」页(5s轮询只读)与「字体」页(列表/上传进度态/导出/409冲突确认force重试); 后端 md5 015f9cf1
This commit is contained in:
1 parent
f149e24f28
commit
7cb1bdace4
6 files changed
+253
-7
No files matched your search
@@ -92,6 +92,7 @@ static const char *g_notif_log = NULL; /* 通知转储日志:<card>/notificat
|
||||
#define PERF_SOCK "/usr/data/meow_perf.sock"
|
||||
#define POWER_SOCK "/usr/data/meow_power.sock"
|
||||
#define LAUNCHER_SOCK "/usr/data/meow_ipc.sock" /* launcher 主 IPC(通知活跃集查询/撤清) */
|
||||
#define AUDIO_SOCK "/usr/data/meow_audio.sock" /* meow_audiod 状态快照(MSG_AUDIO_QUERY→STATE) */
|
||||
#define NYAI_PATH "/usr/bin/nyai" /* 固件内置(权威) */
|
||||
#define NYAI_PATH_CARD "/usr/data/mnt/sd_0/MeowOS/opt/bin/nyai" /* 旧卡上路径(回退) */
|
||||
#define BOOT_DEFAULT_FILE "/data/meow_boot_default"
|
||||
@@ -123,6 +124,7 @@ static const char *g_sensitive_names[] = {
|
||||
static const char *g_sock_perf = PERF_SOCK;
|
||||
static const char *g_sock_power = POWER_SOCK;
|
||||
static const char *g_sock_launcher = LAUNCHER_SOCK;
|
||||
static const char *g_sock_audio = AUDIO_SOCK;
|
||||
|
||||
/* ---------------- 增量帧缓存(GET /api/screen.jpeg?delta=1,阶段 C 增强) ----------------
|
||||
* 服务端缓存上一帧紧凑 RGB565,按 8×8 块比对,只编码变化块(外接 bbox 子图)并以响应头回传偏移。
|
||||
@@ -908,6 +910,72 @@ done:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ---------------- 音频状态:meow_audiod IPC(MSG_AUDIO_QUERY→MSG_AUDIO_STATE) ----------------
|
||||
* audiod 无 MSG_HELLO 握手(见 patch_v2/meow_audiod/meow_audio.c CLI:直连发空负载 QUERY,
|
||||
* 收 STATE 文本帧——"k=v" 空格分隔、NUL 结尾)。audiod 不在/超时/应答异常一律回
|
||||
* {"available":false}(HTTP 200,不报错)——面板音频页据此显示「audiod 不可用」。
|
||||
* socket 可被 env MEOW_AUDIO_SOCK / --sock-audio 覆盖(宿主/qemu 测试用,与 audiod CLI 同 env)。 */
|
||||
static const char *audio_kv(const char *txt, const char *key, char *out, size_t cap)
|
||||
{
|
||||
size_t kl = strlen(key);
|
||||
const char *p = txt;
|
||||
while (p && *p) {
|
||||
if (!strncmp(p, key, kl) && p[kl] == '=') {
|
||||
p += kl + 1;
|
||||
size_t n = strcspn(p, " \t\n");
|
||||
if (n >= cap) n = cap - 1;
|
||||
memcpy(out, p, n);
|
||||
out[n] = 0;
|
||||
return out;
|
||||
}
|
||||
p = strchr(p, ' ');
|
||||
if (p) p++;
|
||||
}
|
||||
out[0] = 0;
|
||||
return NULL;
|
||||
}
|
||||
static long long audio_kv_ll(const char *txt, const char *key, long long defv)
|
||||
{
|
||||
char b[64];
|
||||
if (!audio_kv(txt, key, b, sizeof b) || !b[0]) return defv;
|
||||
return strtoll(b, NULL, 10);
|
||||
}
|
||||
|
||||
static int api_audio(int sock)
|
||||
{
|
||||
int fd = ipc_connect_tmo(g_sock_audio, IPC_TIMEOUT_MS);
|
||||
if (fd < 0) return send_json(sock, 200, "{\"available\":false}");
|
||||
uint8_t buf[MEOW_IPC_MAX];
|
||||
uint16_t type = 0; uint32_t rid = 0;
|
||||
int n = -1;
|
||||
if (send_frame(fd, MSG_AUDIO_QUERY, 5, NULL, 0) == 0)
|
||||
n = recv_frame(fd, &type, &rid, buf, sizeof buf - 1);
|
||||
close(fd);
|
||||
if (n <= 0 || type != MSG_AUDIO_STATE)
|
||||
return send_json(sock, 200, "{\"available\":false}");
|
||||
buf[n] = 0;
|
||||
const char *txt = (const char *)buf;
|
||||
char app[MEOW_APP_ID_MAX + 8], fmt[32], rmode[16];
|
||||
audio_kv(txt, "app", app, sizeof app);
|
||||
audio_kv(txt, "fmt", fmt, sizeof fmt);
|
||||
audio_kv(txt, "route_mode", rmode, sizeof rmode);
|
||||
sbuf_t s = {0};
|
||||
sA(&s, "{\"available\":true,\"active\":%lld,\"app\":", audio_kv_ll(txt, "active", 0));
|
||||
sA_str(&s, app);
|
||||
sA(&s, ",\"sid\":%lld,\"rate\":%lld,\"ch\":%lld,\"fmt\":",
|
||||
audio_kv_ll(txt, "sid", 0), audio_kv_ll(txt, "rate", 0), audio_kv_ll(txt, "ch", 0));
|
||||
sA_str(&s, fmt);
|
||||
sA(&s, ",\"written_frames\":%lld,\"played_frames\":%lld,\"underrun\":%lld,\"paused\":%lld,\"route_mode\":",
|
||||
audio_kv_ll(txt, "written", 0), audio_kv_ll(txt, "played", 0),
|
||||
audio_kv_ll(txt, "underrun", 0), audio_kv_ll(txt, "paused", 0));
|
||||
sA_str(&s, rmode);
|
||||
sA(&s, ",\"port\":%lld,\"vol\":%lld}",
|
||||
audio_kv_ll(txt, "port", -1), audio_kv_ll(txt, "vol", -1));
|
||||
int rc = send_json(sock, 200, s.b ? s.b : "");
|
||||
sbuf_free(&s);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* ---------------- 路径安全 ---------------- */
|
||||
static int tf_present(void)
|
||||
{
|
||||
@@ -4385,6 +4453,9 @@ static int handle(int sock, req_t *r)
|
||||
if (!strcmp(r->method, "GET") && !strcmp(p, "/api/fonts")) return api_fonts_list(sock);
|
||||
if (!strcmp(r->method, "GET") && !strcmp(p, "/api/fonts/export")) return api_fonts_export(sock, r);
|
||||
|
||||
/* ---- 音频状态(meow_audiod 快照,只读) ---- */
|
||||
if (!strcmp(r->method, "GET") && !strcmp(p, "/api/audio")) return api_audio(sock);
|
||||
|
||||
/* ---- 实时画面(阶段 C) ---- */
|
||||
if (!strcmp(r->method, "GET") && !strcmp(p, "/api/screen.jpeg"))
|
||||
return api_screen_jpeg(sock, r);
|
||||
@@ -4513,10 +4584,11 @@ int main(int argc, char **argv)
|
||||
else if (!strcmp(argv[i], "--sock-perf") && i + 1 < argc) g_sock_perf = argv[++i];
|
||||
else if (!strcmp(argv[i], "--sock-power") && i + 1 < argc) g_sock_power = argv[++i];
|
||||
else if (!strcmp(argv[i], "--sock-launcher") && i + 1 < argc) g_sock_launcher = argv[++i];
|
||||
else if (!strcmp(argv[i], "--sock-audio") && i + 1 < argc) g_sock_audio = argv[++i];
|
||||
else if (!strcmp(argv[i], "--sock") && i + 1 < argc) { g_sock_perf = argv[++i]; g_sock_power = g_sock_perf; }
|
||||
else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
|
||||
printf("MeowPanel backend %s\n", PANEL_VERSION);
|
||||
printf("usage: meowpanel [-p PORT] [--sock-perf P] [--sock-power P] [--sock-launcher P]\n");
|
||||
printf("usage: meowpanel [-p PORT] [--sock-perf P] [--sock-power P] [--sock-launcher P] [--sock-audio P]\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -4527,6 +4599,8 @@ int main(int argc, char **argv)
|
||||
if (env && env[0]) g_sock_power = env;
|
||||
env = getenv("MEOW_IPC_LAUNCHER_SOCK");
|
||||
if (env && env[0]) g_sock_launcher = env;
|
||||
env = getenv("MEOW_AUDIO_SOCK");
|
||||
if (env && env[0]) g_sock_audio = env; /* 与 audiod CLI 同 env(宿主/qemu 测试用) */
|
||||
env = getenv("MEOW_SETTINGS_FILE");
|
||||
if (env && env[0]) g_settings_file = env; /* 设置文件覆盖(宿主测试用;设备默认 /usr/data/meow/settings.conf) */
|
||||
|
||||
|
||||
Reference in new issue
Block a user