fix(broadcast): 修复播放音乐失败 + 临时广播失败 (group.memberNames nodeId/stationName 语义混淆)

根因: getStationGroups (L881) + resolveStationGroup 单站分支 (L942) 错误地把
  memberNames = nodes.map(n => n.nodeId || '')
填成了 nodeId 数组 (n_msx5ieg9_9iy1dw 这类), 但下游 4 处消费方
  /api/music/start, /api/music/stop, /api/temp-broadcast/publish
全部把 memberNames[i] 当 stationName 用:
  getStationWs(memberName) → stations[n_xxx] = undefined → null
  stopStationMusic(memberName) → 按错 key 清队列
  stationMusicStates.set(memberName) → 按错 key 存状态
  enqueueStationAudioTask(memberName) → 按错 station 名入队

后果: 所有成员永远被判为 offline (reason=offline), 所以 API 返回 sent=0 failed=1,
音乐和临时广播 100% 无法触发推流, 端到端链路完全中断.

修法: 对 CC station group 语义来说 memberNames = 该 group 包含的每个子站的
stationName 数组 (同 cable group 的 stationNames 语义). 单站 selector 只包含
一个成员 [st.name], 无论这个站挂了多少个 node 连接, 最终 enqueue 都是按
stationName 维度合并到同一个队列, 不会重复推多次.

端到端验证通过:
  MUSIC START: sent=1 failed=0 ✓
  TEMP PUBLISH: success=true sent=1 failed=0 ✓
  Live WAV chunk stream start/end 两条日志完整闭合, 说明 ffmpeg 分块
  → WS 推送 → 结束 全链路走通.
This commit is contained in:
2026-08-17 19:34:10 +08:00
parent 8c9c72fcba
commit dc8f94ce22
+2 -2
View File
@@ -878,7 +878,7 @@ function getStationGroups() {
}; };
}); });
const memberNames = nodes.map(n => n.nodeId || ''); const memberNames = [st.name];
const mergedTags = ['CC']; const mergedTags = ['CC'];
if (hostCount > 0) mergedTags.push(`HOST:${hostCount}`); if (hostCount > 0) mergedTags.push(`HOST:${hostCount}`);
if (slaveCount > 0) mergedTags.push(`SLAVE:${slaveCount}`); if (slaveCount > 0) mergedTags.push(`SLAVE:${slaveCount}`);
@@ -939,7 +939,7 @@ function resolveStationGroup(selector) {
name: st.name, name: st.name,
code, code,
platform, platform,
memberNames: nodes.map(n => n.nodeId || ''), memberNames: [st.name],
memberCount: nodes.length, memberCount: nodes.length,
primaryName: st.name, primaryName: st.name,
masterNodeId: master?.nodeId || '' masterNodeId: master?.nodeId || ''