- 音视频
- 图形学
- 桌面应用
【免费下载链接】t3
TiXL is an open source software to create realtime motion graphics.
导读
ArtnetOutput是 TiXL 的 Lib.io.dmx 库中用于将 DMX 灯光数据通过 Art-Net 网络协议发送到舞台灯光设备的核心操作符。本文从操作符的使用方法出发,结合 TiXL 开源仓库中 ArtnetOutput.cs 的真实实现,系统讲解每一个输入参数、广播与单播两种发送模式、多 Universe 自动扩展机制、ArtPoll 节点发现、ArtSync 同步以及后台发送线程的底层原理,读完即可在 TiXL 中搭建从画面到真实灯具的完整实时灯光链路。
ArtnetOutput 是什么
ArtnetOutput归属于 Lib.io.dmx 子命名空间,官方文档对其定位为:通过 Art-Net 协议在网络上发送 DMX 数据的操作符("Sends DMX data over the network using the Art-Net protocol")。它可以向灯具、Art-Net 节点或媒体服务器等支持 Art-Net 的设备广播(broadcast)或单播(unicast)DMX 数据,并且能够同时发送多个 DMX Universe,其底层使用专用后台线程保证高吞吐、低延迟的发送性能。
它属于 TiXL 完整的 DMX 输入输出家族中的一环。同族操作符包括:
- ArtnetInput —— 接收 Art-Net 数据(来自调光台、媒体服务器);
- SacnInput / SacnOutput —— 基于 sACN(Streaming ACN / E1.31)协议的收发;
- DmxOutput —— 通过 FTDI 等 USB-DMX 硬件接口发送;
- PointsToDmxLights —— 将 3D 点阵转换为 DMX 通道值,是 ArtnetOutput 最常见的上游数据源。
整个库的概览见 Lib.io.dmx README。
兼容性说明:该操作符依赖第三方原生库
ArtNet.dll(源码中以[ExportDependencies("ArtNet.dll")]声明),该库随仓库依赖目录分发(见 Dependencies/ArtNet.dll),TiXL 会按依赖解析机制自动加载。
核心特性
根据文档并结合源码,ArtnetOutput 提供以下关键能力:
| 特性 | 说明 |
|---|---|
| 多输入支持 | InputsValues为多输入(MultiInput),每个接入的输入列表对应一个独立的 Universe 发送 |
| 自动 Universe 扩展 | 单个输入列表超过 512 通道时,自动切分为多个 512 通道的包依次发送到连续的 Universe |
| ArtPoll 节点发现 | 内置 ArtPoll/ArtPollReply 机制,可自动发现网络上的 Art-Net 节点并填入TargetIpAddress下拉框 |
| 帧率限制 | MaxFps限制最大发送速率,防止网络泛洪 |
| ArtSync 同步 | SendSync开启后,在 DMX 数据后追加 ArtSync 包,用于跨节点同步更新 |
| 自动重连 | 网络异常导致发送连续失败时自动断开,并在配置有效后自动恢复(自动复活逻辑,约 2 秒重试一次) |
官方文档给出的三条快速上手建议:
- 广播模式:将
TargetIpAddress留空即可;单播模式:填写目标节点 IP。 - 用
UniverseChannels为每个输入定义起始 Universe(不足时自动扩展)。 SendTrigger置为 true 开始持续发送,置为 false 停止发送。
搜索标签(AKA):artnet、dmx、lighting、sacn。
输入参数详解
以下是官方文档列出的全部输入参数,并结合源码补充了取值范围、默认值与底层行为。
| 名称(类型) | 说明(含源码级细节) |
|---|---|
| InputsValues(List<int> 多输入) | 多输入槽。每个接入的输入提供一个 Universe 的 DMX 通道数据,值为 float/int 列表,发送时被钳制到 0–255(源码中val < 0 ? 0 : (val > 255 ? 255 : val))。每个输入最多构成一个 512 通道的包,超过部分自动溢出到下一个 Universe |
| UniverseChannels(List<int>) | 定义每个输入对应的起始 Universe 编号。当某个输入通道数超过 512 时自动跨入下一 Universe;输入数量增加时该列表会自动扩展(源码在每帧更新中动态补齐并回写) |
| LocalIpAddress(String) | 发送所用网卡的 IP 地址。下拉框列出本机所有可用网卡(含回环地址127.0.0.1)。多网卡机器务必选择连接灯光网络的网卡,否则广播地址计算错误 |
| SendTrigger(Boolean) | 手动发送开关:从 0 变 1 的上升沿触发启动后台发送线程;置 0 则停止发送。关闭状态下面板显示 "Sending is disabled. Enable 'Send Trigger'." |
| Reconnect(Boolean) | 强制重连网络 Socket(内部会关闭并重建 UDP 套接字,必要时重启发送线程) |
| SendSync(Boolean) | 开启后,每轮 DMX 数据发送完毕后追加一个 ArtSync 包(OpCode 0x0052),用于多节点同步刷新 |
| SendUnicast(Boolean) | 开启后以单播方式向TargetIpAddress发送;关闭则向子网广播地址发送(基于本地 IP 与子网掩码计算,失败时回退到全局广播255.255.255.255) |
| EnableArtNet4(Boolean) | 默认true。开启后启用 Art-Net 4 扩展:当节点列表中存在针对某 Universe 的路由条目(来自 ArtPollReply 的端口地址表)时,该 Universe 的数据包直接单播到对应节点,而非广播 |
| TargetIpAddress(String) | 单播目标 IP。留空则广播到整个网络;通过 ArtPoll 发现的节点会以"名称 (IP)"形式出现在该输入的下拉框中,选择后自动提取括号内 IP |
| PrintArtnetPoll(Boolean) | 开启后发送 ArtPoll 包(OpCode 0x0020)并监听 ArtPollReply(OpCode 0x0021),每 3 秒轮询一次;发现的节点填充TargetIpAddress下拉框。关闭则停止监听 |
| MaxFps(Int32) | 限制最大发送帧率,默认60;0 表示不限速。发送线程用高精度 Stopwatch 做时间调度,空闲时 Sleep(1ms)/SpinWait 降 CPU 占用 |
| PrintToLog(Boolean) | 开启后将状态信息与错误打印到 TiXL 日志,便于调试(发送线程异常时输出 "ArtNet Sender survived error: ...") |
默认值与初始状态(源码佐证)
在 ArtnetOutput.cs 的输入槽定义中可以看到几个重要默认值:
EnableArtNet4默认true,即默认启用 Art-Net 4 单播路由;MaxFps默认60;SendTrigger、Reconnect、SendSync、SendUnicast、PrintToLog默认均为false;LocalIpAddress默认为空,但示例工程(见下文)将其设为127.0.0.1。
输出
| 名称 | 类型 |
|---|---|
| Result | T3.Core.DataTypes.Command |
Result输出一个 Command,在 TiXL 的运算符图中用于表示"已执行一次发送动作",可作为下游逻辑(如触发其他运算)的连接点。
底层实现剖析:它如何在内部工作
ArtnetOutput 的实现远超"发个 UDP 包"的简单程度,其内部包含一套为实时性能设计的多线程架构,全部代码位于 ArtnetOutput.cs(类声明见 第 12 行)。
1. 生产者-消费者模型与零分配队列
- 主线程(更新线程):在
Update()中收集各输入的通道列表、计算 Universe 映射,将数据打包进FrameData后放入ConcurrentQueue<FrameData> _dataQueue。 - 后台发送线程("ArtNetSender"):以
AboveNormal线程优先级独立运行SenderLoop(),从队列取帧并逐 Universe 拆包发送,从而不阻塞 TiXL 主渲染循环。 - 对象池优化:
FrameData复用一个ConcurrentBag对象池(RentFrameData/_frameDataPool),发送完毕的帧回池复用,避免高频分配导致的 GC 压力;当队列积压超过 2 帧时丢弃最旧帧,保证"以最新状态发送"(丢帧保实时)。
2. Art-Net 数据包构建
SendDmxPacket()直接手工构造标准 Art-Net 包(发送到 UDP 6454 端口):
- 前 8 字节为协议 ID
"Art-Net\0"; - OpCode 0x0050(ArtDmx);
- 每 Universe 一个递增序列号(
_universeSequenceNumbers,1–255 循环),用于接收端丢包检测; - Universe 编号拆为低位字节与高位 7 位写入第 15、16 字节;
- 通道长度(sendLength)保证至少 2 字节且为偶数(DMX 起始码要求);
- 通道值逐字节钳制 0–255 后拷贝进 530 字节的复用缓冲区
_packetBuffer。
超过 512 通道的输入在发送线程内被切分为多个 512 通道的块,并依次递增 Universe 编号发送。
3. 广播地址的稳健计算
广播模式下并非简单地发往255.255.255.255:ConnectionSettings.Update()会先尝试用本地 IP 与网卡子网掩码计算子网定向广播地址(CalculateBroadcastAddress,IP 与掩码按位或),失败才回退到全局广播。这样既减少无关网段的流量,也保证回环地址(localhost)下可正常测试。相关逻辑见 第 511-571 行。
4. ArtPoll 节点发现与 Art-Net 4 路由
- 开启
PrintArtnetPoll后启动两个后台组件:每 3 秒发送一次 ArtPoll 的Timer,以及持续ReceiveFrom监听回复的 "ArtNetPollListener" 线程; - 收到 ArtPollReply(长度 ≥ 238 字节,OpCode 0x0021)后,解析节点 IP、短名称(18 字节 ASCII),以
名称 (IP)形式存入发现列表并填充下拉框; - 进一步解析 Net/SwIn/SubSwitch 端口地址表,构建
_universeRoutingTable(Universe → 节点 IP:6454); - 在
EnableArtNet4开启时,发送线程会查询该路由表,将对应 Universe 直接单播到目标节点——这就是"Art-Net 4"智能路由的含义。
5. 连接生命周期与容错
- 网络变化(本地 IP 变更)会触发
needsSocketRebind,自动重建 Socket; - 未连接状态下每 2 秒自动重试连接(
shouldAutoRevive); - 发送线程连续10 次错误(
MAX_CONSECUTIVE_ERRORS)即置_connected = false,触发重连流程;SocketError.WouldBlock / NoBufferSpaceAvailable / ConnectionReset等瞬时错误被宽容处理,不视为失败; - Socket 设置 10MB 发送缓冲区并启用广播、复用地址选项,避免快速重启时的端口占用问题。
上手实战:从 3D 场景到真实灯具
场景 A:与 PointsToDmxLights 配合(推荐)
仓库自带的官方示例 HowToDmx.t3(对应 UI 布局 HowToDmx.t3ui)展示了完整的实战链路:GridPoints生成 3D 点阵 →TransformPoints/PerlinNoise3驱动运动 →PointsToDmxLights将点位置/旋转/颜色映射为 DMX 通道(支持FixtureChannelSize、Pan/Tilt通道与PanRange/TiltRange、FitInUniverse/FillUniverse等参数)→ArtnetOutput发出。
示例中ArtnetOutput节点的关键初始配置(来自 HowToDmx.t3):
"SendTrigger": true, // 直接开启持续发送 "Reconnect": false, "SendUnicast": false, // 广播模式 "SendSync": false, "LocalIpAddress": "127.0.0.1" // 本机回环测试即:默认走广播模式、监听本机回环地址,方便在没有真实灯光网络时先用本机工具验证。
场景 B:最简手动测试
- 拖入
ArtnetOutput操作符; - 用任意数值列表(如
PointsToDmxLights输出或手写 0–255 的列表)接到InputsValues; LocalIpAddress选择连接灯光网络的网卡 IP;- 广播:留空
TargetIpAddress;单播:填目标节点 IP; - 将
SendTrigger置为 true; - 在接收端(如 Art-Net 节点/模拟器)检查数据;配合
PrintToLog观察日志与面板状态("Connected and sending.")。
推荐配置速查
| 目标 | 配置 |
|---|---|
| 快速本地验证 | LocalIpAddress=127.0.0.1、SendUnicast=false、MaxFps=60 |
| 单播到指定灯具节点 | SendUnicast=true,TargetIpAddress=节点IP(可用 ArtPoll 发现) |
| 多 Universe 大场景 | 多个输入接到InputsValues,UniverseChannels自动扩展 |
| 多节点严格同步 | 开启SendSync发送 ArtSync |
| 降低 CPU/网络占用 | 调低MaxFps(如 30) |
| 网络排查 | 开启PrintArtnetPoll(发现节点)+PrintToLog |
故障排查与提示
- 发不出数据:检查
SendTrigger是否开启(面板会提示 "Sending is disabled. Enable 'Send Trigger'.");检查LocalIpAddress是否选择了正确的网卡——多网卡机器选错会导致广播发往错误网段。 - 设备无响应:确认目标设备支持 Art-Net 且端口 6454 未被占用;单播时确认
TargetIpAddress正确,广播时确认子网一致。 - 数据抖动/丢包:调低
MaxFps;确认网络交换机未泛洪;Art-Net 序列号机制可帮助接收端识别乱序。 - 节点找不到:确保
PrintArtnetPoll开启且设备与电脑处于同一网段,等待 3 秒轮询周期。 - 重启后无法绑定端口:Socket 已启用
ReuseAddress;若仍冲突,检查是否有其他 Art-Net 软件占用 6454 端口。 - 与 ArtnetInput 联调:同一台机器上可用 ArtnetInput 反向接收验证闭环(它同样使用
LocalIpAddress指定监听网卡)。
延伸阅读
- 操作符官方文档:ArtnetOutput.md
- 同族操作符:ArtnetInput、SacnOutput、SacnInput、DmxOutput、PointsToDmxLights
- 完整源码:ArtnetOutput.cs
- 可运行示例:HowToDmx.t3(及其 UI 布局)
- 音视频
- 图形学
- 桌面应用
【免费下载链接】t3
TiXL is an open source software to create realtime motion graphics.
相关推荐
TiXL 实时灯光控制实战指南:深入解析 Lib.io.dmx 的 Art-Net、sACN 与 DMX 全套算子
TiXL 实时灯光控制实战指南:深入解析 Lib.io.dmx 的 Art Net、sACN 与 DMX 全套算子 TiXL 不仅是一款实时动态图形创作工具,其
音视频图形学桌面应用TiXL FreeDOutput 操作符实战指南:使用 FreeD 协议经 UDP 发送相机追踪数据
TiXL FreeDOutput 操作符实战指南:使用 FreeD 协议经 UDP 发送相机追踪数据 本指南围绕 TiXL(实时动态图形创作软件)中 Lib.i
音视频图形学桌面应用TiXL OscOutput 操作符实战指南:用 OSC 协议把实时画面数据发送到任意接收端
TiXL OscOutput 操作符实战指南:用 OSC 协议把实时画面数据发送到任意接收端 本篇指南围绕 TiXL 中 Lib.io.osc 库的 OscOu
音视频图形学桌面应用
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考