support separate audio and video domains

This commit is contained in:
Dmitry Sergeev
2026-08-28 23:09:50 +03:00
parent 27dcbd1b40
commit 774361df47
2 changed files with 71 additions and 36 deletions
+64 -29
View File
@@ -75,26 +75,27 @@ func printUsage(w io.Writer) {
} }
func checkMXLargs(args appArgs) { func checkMXLargs(args appArgs) {
if args.VideoFlowId == "" && args.AudioFlowId == "" { checkDomain := func(label, domain string) {
return if domain == "" {
} fmt.Fprintf(os.Stderr, "%s domain is required when its UUID is configured\n", label)
if args.Domain == "" {
fmt.Fprintln(
os.Stderr,
"You must provide a domain when a feed UUID is configured",
)
printUsage(os.Stderr) printUsage(os.Stderr)
os.Exit(2) os.Exit(2)
} }
info, err := os.Stat(domain)
fi, err := os.Stat(args.Domain) if err != nil || !info.IsDir() {
if err != nil || !fi.IsDir() { fmt.Fprintf(os.Stderr, "Invalid %s MXL domain: %s\n", label, domain)
fmt.Fprintln(os.Stderr, "Invalid MXL domain:", args.Domain)
fmt.Fprintln(os.Stderr, "Domain must be a directory in tmpfs") fmt.Fprintln(os.Stderr, "Domain must be a directory in tmpfs")
printUsage(os.Stderr) printUsage(os.Stderr)
os.Exit(2) os.Exit(2)
} }
}
if args.VideoFlowId != "" {
checkDomain("video", args.VideoDomain)
}
if args.AudioFlowId != "" {
checkDomain("audio", args.AudioDomain)
}
} }
func main() { func main() {
@@ -107,7 +108,15 @@ func main() {
flagSet.SortFlags = false flagSet.SortFlags = false
flagSet.Usage = func() { printUsage(os.Stderr) } flagSet.Usage = func() { printUsage(os.Stderr) }
flagSet.BoolVarP(&args.ShowHelp, "help", "h", false, "Show help message and exit") flagSet.BoolVarP(&args.ShowHelp, "help", "h", false, "Show help message and exit")
flagSet.StringVarP(&args.Domain, "domain", "d", "", "MXL domain directory") flagSet.StringVarP(
&args.Domain,
"domain",
"d",
"",
"Default MXL domain for feeds without a specific domain",
)
flagSet.StringVar(&args.VideoDomain, "video-domain", "", "MXL domain for the video feed")
flagSet.StringVar(&args.AudioDomain, "audio-domain", "", "MXL domain for the audio feed")
flagSet.StringVarP(&args.VideoFlowId, "video", "v", "", "Video flow UUID") flagSet.StringVarP(&args.VideoFlowId, "video", "v", "", "Video flow UUID")
flagSet.StringVarP(&args.AudioFlowId, "audio", "a", "", "Audio flow UUID") flagSet.StringVarP(&args.AudioFlowId, "audio", "a", "", "Audio flow UUID")
flagSet.BoolVarP( flagSet.BoolVarP(
@@ -152,9 +161,25 @@ func main() {
fmt.Fprintln(os.Stderr, "invalid retry configuration:", err) fmt.Fprintln(os.Stderr, "invalid retry configuration:", err)
os.Exit(2) os.Exit(2)
} }
if args.VideoDomain == "" {
args.VideoDomain = args.Domain
}
if args.AudioDomain == "" {
args.AudioDomain = args.Domain
}
if !args.ListAudio && !args.ListGPU { if !args.ListAudio && !args.ListGPU {
checkMXLargs(args) checkMXLargs(args)
} }
if args.SyncRequested &&
args.VideoFlowId != "" &&
args.AudioFlowId != "" &&
args.VideoDomain != args.AudioDomain {
fmt.Fprintln(
os.Stderr,
"--sync currently requires video and audio to use the same MXL domain",
)
os.Exit(2)
}
// path selection // path selection
useLegacySync := args.SyncRequested && useLegacySync := args.SyncRequested &&
args.VideoFlowId != "" && args.VideoFlowId != "" &&
@@ -292,7 +317,7 @@ func main() {
switch { switch {
case useLegacySync: case useLegacySync:
syncSrc, err = source.OpenSameDomainSync( syncSrc, err = source.OpenSameDomainSync(
args.Domain, args.VideoDomain,
args.VideoFlowId, args.VideoFlowId,
args.AudioFlowId, args.AudioFlowId,
) )
@@ -378,7 +403,8 @@ func main() {
// GUI state (accessible from doReconnect + goroutine) // GUI state (accessible from doReconnect + goroutine)
var ( var (
domainStr string = args.Domain videoDomainStr string = args.VideoDomain
audioDomainStr string = args.AudioDomain
videoStr string = args.VideoFlowId videoStr string = args.VideoFlowId
audioStr string = args.AudioFlowId audioStr string = args.AudioFlowId
showStats bool = true showStats bool = true
@@ -552,7 +578,7 @@ func main() {
videoConfig := playback.FeedConfig{} videoConfig := playback.FeedConfig{}
if videoStr != "" { if videoStr != "" {
videoConfig = playback.FeedConfig{ videoConfig = playback.FeedConfig{
Domain: domainStr, Domain: videoDomainStr,
UUID: videoStr, UUID: videoStr,
Active: true, Active: true,
} }
@@ -561,7 +587,7 @@ func main() {
audioConfig := playback.FeedConfig{} audioConfig := playback.FeedConfig{}
if audioStr != "" { if audioStr != "" {
audioConfig = playback.FeedConfig{ audioConfig = playback.FeedConfig{
Domain: domainStr, Domain: audioDomainStr,
UUID: audioStr, UUID: audioStr,
Active: true, Active: true,
} }
@@ -572,11 +598,19 @@ func main() {
return return
} }
// legacy // legacy
if videoDomainStr != audioDomainStr {
log.Printf(
"sync reconnect rejected: video domain %q differs from audio domain %q",
videoDomainStr,
audioDomainStr,
)
return
}
select { select {
case <-control: case <-control:
default: default:
} }
control <- reconnectParams{domain: domainStr, video: videoStr, audio: audioStr} control <- reconnectParams{domain: videoDomainStr, video: videoStr, audio: audioStr}
} }
playbackDone := make(chan struct{}) playbackDone := make(chan struct{})
@@ -593,7 +627,7 @@ func main() {
err := videoSlot.Run( err := videoSlot.Run(
ctx, ctx,
playback.FeedConfig{ playback.FeedConfig{
Domain: args.Domain, Domain: args.VideoDomain,
UUID: args.VideoFlowId, UUID: args.VideoFlowId,
Active: args.VideoFlowId != "", Active: args.VideoFlowId != "",
}, },
@@ -610,7 +644,7 @@ func main() {
err := audioSlot.Run( err := audioSlot.Run(
ctx, ctx,
playback.FeedConfig{ playback.FeedConfig{
Domain: args.Domain, Domain: args.AudioDomain,
UUID: args.AudioFlowId, UUID: args.AudioFlowId,
Active: args.AudioFlowId != "", Active: args.AudioFlowId != "",
}, },
@@ -669,7 +703,7 @@ func main() {
return return
} }
log.Printf("source: %v", err) log.Printf("source: %v", err)
params := reconnectParams{domain: domainStr, video: videoStr, audio: audioStr} params := reconnectParams{domain: videoDomainStr, video: videoStr, audio: audioStr}
select { select {
case <-control: case <-control:
default: default:
@@ -731,7 +765,7 @@ func main() {
log.Printf("source: %v", err) log.Printf("source: %v", err)
// Request a reconnect after the read failure. // Request a reconnect after the read failure.
params := reconnectParams{ params := reconnectParams{
domain: domainStr, domain: videoDomainStr,
video: videoStr, video: videoStr,
audio: audioStr, audio: audioStr,
} }
@@ -763,7 +797,7 @@ func main() {
} }
log.Printf("source: %v", err) log.Printf("source: %v", err)
params := reconnectParams{ params := reconnectParams{
domain: domainStr, domain: videoDomainStr,
video: videoStr, video: videoStr,
audio: audioStr, audio: audioStr,
} }
@@ -941,7 +975,8 @@ func main() {
cimgui.End() cimgui.End()
} }
cimgui.Begin("Connection") cimgui.Begin("Connection")
cimgui.InputTextWithHint("Domain", "/dev/shm/mxl", &domainStr, 0, nil) cimgui.InputTextWithHint("Video domain", "/dev/shm/mxl", &videoDomainStr, 0, nil)
cimgui.InputTextWithHint("Audio domain", "/dev/shm/mxl", &audioDomainStr, 0, nil)
cimgui.InputTextWithHint("Video UUID", "", &videoStr, 0, nil) cimgui.InputTextWithHint("Video UUID", "", &videoStr, 0, nil)
cimgui.InputTextWithHint("Audio UUID", "", &audioStr, 0, nil) cimgui.InputTextWithHint("Audio UUID", "", &audioStr, 0, nil)
if cimgui.Button("Connect") { if cimgui.Button("Connect") {
@@ -954,7 +989,7 @@ func main() {
videoActive = false videoActive = false
enqueueVideoConfig( enqueueVideoConfig(
playback.FeedConfig{ playback.FeedConfig{
Domain: domainStr, Domain: videoDomainStr,
UUID: videoStr, UUID: videoStr,
Active: false, Active: false,
}) })
@@ -965,7 +1000,7 @@ func main() {
if cimgui.Button("Resume video") { if cimgui.Button("Resume video") {
videoActive = true videoActive = true
enqueueVideoConfig(playback.FeedConfig{ enqueueVideoConfig(playback.FeedConfig{
Domain: domainStr, Domain: videoDomainStr,
UUID: videoStr, UUID: videoStr,
Active: true, Active: true,
}) })
@@ -1016,7 +1051,7 @@ func main() {
if cimgui.Button("Stop audio") { if cimgui.Button("Stop audio") {
audioActive = false audioActive = false
enqueueAudioConfig(playback.FeedConfig{ enqueueAudioConfig(playback.FeedConfig{
Domain: domainStr, Domain: audioDomainStr,
UUID: audioStr, UUID: audioStr,
Active: false, Active: false,
}) })
@@ -1027,7 +1062,7 @@ func main() {
if cimgui.Button("Resume audio") { if cimgui.Button("Resume audio") {
audioActive = true audioActive = true
enqueueAudioConfig(playback.FeedConfig{ enqueueAudioConfig(playback.FeedConfig{
Domain: domainStr, Domain: audioDomainStr,
UUID: audioStr, UUID: audioStr,
Active: true, Active: true,
}) })
+1 -1
View File
@@ -14,7 +14,7 @@ Size=200,200
Collapsed=0 Collapsed=0
[Window][Connection] [Window][Connection]
Pos=185,295 Pos=427,302
Size=640,354 Size=640,354
Collapsed=0 Collapsed=0