跳转到内容
文档
下载
简体中文

连接 Sound Show 2

使用自己的脚本、硬件控制器或集成功能控制正在运行的 Sound Show 2。WebSocket API 可启动可播放项目、控制播放器和输出、执行提示操作,并将实时状态发回控制器。

本指南介绍协议 v2,直接连接计算机或局域网中的 Sound Show。无需网站 API 密钥或账户访问令牌。此 API 不支持编辑项目或上传文件。

  • 从这里开始连接并运行示例。
  • 通过命令参考添加控制功能。
  • 通过状态与事件查找 ID 并显示当前演出状态。

  1. 在桌面计算机上打开 Sound Show 2 并加载项目。主机需要 Pro 使用权限,有效的 Pro 试用也可以。参见 Free 与 Pro。
  2. 打开选项 → 集成 → 远程服务器,也可使用远程面板的设置按钮。
  3. 选择端口(默认为 8080),设置至少六个字符的密码并保存。请为此连接使用独立密码。
  4. 使用连接按钮启动服务器。如果密码为空,请确认应用关于无密码访问的警告。
  5. 复制 Sound Show 显示的地址。如需使用内置浏览器遥控器,请保持提供网页开启;关闭该选项也不影响 WebSocket 端点。

浏览器遥控器与 WebSocket API 使用相同的主机和端口。

用途 在 Sound Show 计算机上的示例
WebSocket 连接 ws://127.0.0.1:8080/ws
内置浏览器遥控器 http://127.0.0.1:8080/
服务器健康检查 http://127.0.0.1:8080/health

从其他设备连接时,将 127.0.0.1 替换为 Sound Show 计算机的地址,例如 ws://192.168.1.20:8080/ws。如果配置的端口不是 8080,请使用实际端口。localhost 始终指运行客户端的设备。

健康检查端点返回类似 {"status":"ok","protocol_version":2} 的对象,只确认服务器可达,不会验证客户端身份。

默认情况下,Sound Show 检查浏览器的 Origin 请求头。它必须是使用服务器端口的 HTTP 来源,主机须为 localhost、检测到的 LAN 地址或配置的通告主机。通过 Sound Show 显示的地址打开内置遥控器即可使用受允许的来源。

在其他设备、网站或开发服务器端口上托管的自定义页面,需要启用下述允许外部来源选项。原生客户端(包括本页的 JavaScript 终端示例)可以省略 Origin,不需要该选项。

当您将自定义浏览器遥控器托管在 Sound Show 之外时,启用此选项:

  1. 打开选项 → 集成 → 远程服务器,或远程面板的设置。
  2. 设置远程密码,开启允许外部来源并应用设置。此选项默认关闭。如果找不到,请更新至包含此选项的 Sound Show 版本。
  3. 在能访问 Sound Show 计算机的设备上打开自定义遥控页面。将其 WebSocket 连接到 Sound Show 的地址,而不是页面托管地址,并发送包含密码的常规 hello 消息。

例如,托管于 http://192.168.1.30:3000 的控制器可以连接到 ws://192.168.1.20:8080/ws 上的 Sound Show。浏览器脚本可以这样开始:

const remotePassword = window.prompt("Sound Show remote password");
if (remotePassword !== null) {
const socket = new WebSocket("ws://192.168.1.20:8080/ws");
socket.addEventListener("open", () => {
socket.send(JSON.stringify({
type: "hello", version: 2, password: remotePassword,
features: ["runtime_snapshots"],
}));
});
socket.addEventListener("message", (event) => {
const message = JSON.parse(event.data);
console.log(message); // Handle hello_rejected, errors, and snapshots here.
});
}

将示例地址替换为您的主机和端口。收到第一条 state 后再启用播放控制,并采用完整 JavaScript 示例中的快照处理逻辑。将密码保留在控制器会话中,不要嵌入公开托管的页面。

此选项接受主机或端口不同的 HTTP 和 HTTPS 页面来源。密码握手和 Pro 要求仍然适用。保存更改会立即生效并断开客户端,因此需要重新连接和验证身份。关闭选项也会结束现有的外部会话。内置浏览器遥控器可在此选项关闭时使用。

浏览器限制仍然适用。 对于简单的 LAN 配置,请通过 HTTP 提供自定义页面。HTTPS 页面可能阻止未加密的 ws:// 连接;启用此选项不会提供安全的 wss:// 端点。HTTPS 控制器需要浏览器兼容的安全连接,例如另行配置的 TLS 代理。浏览器还可能要求本地网络权限或施加其他网络限制。此选项不会为 HTTP 端点添加 CORS 请求头。file:// 页面和不透明的 null 来源仍会被拒绝:请使用 HTTP 服务器提供本地 HTML 文件。

套接字打开后立即发送一条 JSON 文本消息,须在十秒内完成。消息应包含 Sound Show 中配置的远程密码:

{
"type": "hello",
"version": 2,
"password": "your-remote-password",
"features": ["runtime_snapshots"]
}

对于已确认允许无密码访问的服务器,可省略 password 或使用空字符串。features 为可选字段;请求 runtime_snapshots 后,客户端会分别收到控制状态、指令、播放列表及可播放项目活动的实时更新。

成功时服务器发送:

{
"type": "hello_ok",
"protocol_version": 2,
"requested_version": 2,
"state_mode": "full_snapshot",
"features": ["ping", "runtime_snapshots"]
}

随后自动发送完整的 state 消息。收到它之后,再选择目标或发送演出命令。后续消息会替换整个状态或其中一个具名部分。没有订阅命令,也没有逐条命令的成功确认:以最终状态为准。

失败时会收到包含 reason 和 message 的 hello_rejected,随后断开连接。原因包括 invalid_password、unsupported_version 和 rate_limited。参见错误与限制。

尝试 JavaScript 客户端

“尝试 JavaScript 客户端”章节

将代码保存为 soundshow-client.mjs,使用 Node.js 22.12 或更新版本运行。它使用内置 WebSocket 客户端,无需安装软件包。示例列出项目中的可播放项目并跟踪实时状态;只有通过命令行参数传入可播放项目 ID 时才会开始播放。

const url = process.env.SOUNDSHOW_REMOTE_URL ?? "ws://127.0.0.1:8080/ws";
const password = process.env.SOUNDSHOW_REMOTE_PASSWORD ?? "";
const playableId = process.argv[2];
const ws = new WebSocket(url);
let state = null;
let firstSnapshot = true;
const domains = {
control_snapshot: "control",
players_snapshot: "players",
instructions_snapshot: "instructions",
playlists_snapshot: "playlists",
playable_runtime_snapshot: "playable_runtime",
logical_devices_snapshot: "logical_devices",
timers_snapshot: "timers",
audio_controls_snapshot: "audio_controls",
lights_snapshot: "lights",
};
function send(command) {
if (!state || ws.readyState !== WebSocket.OPEN) {
throw new Error("Wait for the first state snapshot before sending commands.");
}
ws.send(JSON.stringify(command));
}
ws.addEventListener("open", () => {
ws.send(JSON.stringify({
type: "hello", version: 2, password, features: ["runtime_snapshots"],
}));
});
ws.addEventListener("message", (event) => {
const message = JSON.parse(event.data);
if (message.type === "hello_rejected" || message.type === "error") {
console.error(message.reason ?? message.code ?? "error", message.message);
return;
}
if (message.type === "state") {
state = message.state; // Replace the entire state, even after a project change.
} else {
const domain = domains[message.type];
if (!state || !domain) return; // Ignore unknown additive message types.
if ((domain === "audio_controls" || domain === "lights") &&
message.revision < (state[domain]?.revision ?? -1)) return;
state = { ...state, [domain]: message[domain] };
}
if (firstSnapshot) {
firstSnapshot = false;
const playables = (state.project?.categories ?? []).flatMap((category) =>
category.playables.map((p) => ({
id: p.id, name: p.name, kind: p.kind, category: category.name,
}))
);
console.table(playables);
if (playableId) {
if (playables.some((p) => p.id === playableId)) {
send({ type: "play_playable", playable_id: playableId, action: "start" });
} else {
console.error("That playable ID is not in the current project.");
}
}
console.log("Connected. Press Ctrl+C to disconnect.");
}
// Use `state` here to update your controller after every snapshot.
});
ws.addEventListener("error", () => console.error("Connection failed. Check the server address and settings."));
ws.addEventListener("close", (event) => {
state = null;
console.log("Disconnected:", event.code, event.reason);
});
process.on("SIGINT", () => ws.close());

在 PowerShell 中设置地址和远程密码,然后列出可播放项目:

终端窗口
$env:SOUNDSHOW_REMOTE_URL = 'ws://127.0.0.1:8080/ws'
$env:SOUNDSHOW_REMOTE_PASSWORD = 'your-remote-password'
node soundshow-client.mjs

在 macOS 或 Linux 终端中:

终端窗口
export SOUNDSHOW_REMOTE_URL='ws://127.0.0.1:8080/ws'
export SOUNDSHOW_REMOTE_PASSWORD='your-remote-password'
node soundshow-client.mjs

不要在共享脚本中写入真实密码。无密码服务器使用空值。按 Ctrl+C 停止脚本,从表中复制一个可播放项目 ID,然后重新运行,将该项目触发一次:

终端窗口
node soundshow-client.mjs "paste-a-playable-id-here"

示例不会自动重连或重放命令。构建长期运行的控制器前,请加入连接恢复逻辑,并从命令参考选择命令。

症状 检查事项
连接被拒绝或超时 保持 Sound Show 打开并启动服务器。检查端口、主机地址、防火墙以及两台设备能否在网络上互相访问。
服务器无法启动 检查 Pro 权限、连接日志以及端口是否被其他应用占用。
连接时出现 HTTP 403 检查 Pro 权限和浏览器来源。页面托管于其他设备、端口或网站时,在 Sound Show 中开启允许外部来源。
允许外部来源后仍无法连接自定义遥控器 检查 Sound Show 主机地址、防火墙和浏览器控制台。该选项不会绕过混合内容或本地网络限制;请使用上文的 HTTP LAN 配置。
invalid_password 使用远程服务器密码,而不是 Sound Show 账户密码。
unsupported_version 发送 version: 2 并使用 /ws。Sound Show 1 消息不兼容。
HTTP 429 或 rate_limited 停止快速重试或发送命令,并遵循重试指引。
已连接但没有状态 先发送 hello,检查拒绝消息或格式错误的 JSON。
命令无效 从最新状态获取 ID;检查锁定、目标可用性、许可证和 error 消息。
控制器显示过时 同时处理域快照和完整 state 消息。没有消息本身并不意味着连接已断开。

使用 /ws 代替 /SoundShow,使用小写 type 字段代替 $type 和 .NET 类名。发送 v2 hello 握手。使用播放器 ID 和逻辑设备 ID,而不是播放器或输出的数字索引。图标是 HTTP icon_url 资源,状态则以完整快照或域快照发送。