You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
2.9 KiB

import Foundation
/// A screen identified across restarts and machines: by name first, position as fallback.
/// (CGDirectDisplayIDs differ between Macs and can change after a reboot.)
public struct ScreenRef: Codable, Hashable, Sendable {
public var name: String
/// Position in the system's screen list (0 = main screen).
public var index: Int
public init(name: String, index: Int) {
self.name = name
self.index = index
}
}
/// One NDI source fullscreen on one screen.
public struct VideoAssignment: Codable, Hashable, Sendable {
public var screen: ScreenRef
public var source: Source
public init(screen: ScreenRef, source: Source) {
self.screen = screen
self.source = source
}
}
/// One audio source on one output channel.
public struct AudioAssignment: Codable, Hashable, Sendable {
public enum SourceSpec: Codable, Hashable, Sendable {
case ndi(name: String)
/// Input device by UID; the name is the fallback when the UID changes (e.g. other USB port).
case input(uid: String, name: String)
}
public var source: SourceSpec
public var deviceUID: String
public var deviceName: String
public var channel: Int // 0-based
public var selection: ChannelSelection
public var gainDB: Float
public var muted: Bool
public init(source: SourceSpec, deviceUID: String, deviceName: String, channel: Int,
selection: ChannelSelection = .mono, gainDB: Float = 0, muted: Bool = false) {
self.source = source
self.deviceUID = deviceUID
self.deviceName = deviceName
self.channel = channel
self.selection = selection
self.gainDB = gainDB
self.muted = muted
}
/// Identity of the route (what goes where), without its settings.
public var key: String {
let sourceKey = switch source {
case .ndi(let name): "ndi:\(name)"
case .input(let uid, _): "input:\(uid)"
}
return "\(sourceKey)→\(deviceUID)#\(channel)"
}
}
/// Everything one Mac outputs.
public struct MachineConfig: Codable, Hashable, Sendable {
public var video: [VideoAssignment]
public var audio: [AudioAssignment]
public init(video: [VideoAssignment] = [], audio: [AudioAssignment] = []) {
self.video = video
self.audio = audio
}
public static let empty = MachineConfig()
}
/// A complete setup of the control Mac and its nodes, e.g. "OP-Live".
public struct Scene: Codable, Identifiable, Hashable, Sendable {
public var id: UUID
public var name: String
public var control: MachineConfig
/// Node name (computer name) → what that node shows.
public var nodes: [String: MachineConfig]
public init(id: UUID = UUID(), name: String, control: MachineConfig = .empty, nodes: [String: MachineConfig] = [:]) {
self.id = id
self.name = name
self.control = control
self.nodes = nodes
}
}

Powered by TurnKey Linux.