redesign settings
This commit is contained in:
+186
-140
@@ -99,6 +99,8 @@ func main() {
|
||||
// timelapse audio: 5fbec3b1-1b0f-417d-9059-8b94a47197ec
|
||||
// f1 video: 5fbec3b1-1b0f-417d-9059-8b94a47197ef
|
||||
// f1 audio: 5fbec3b1-1b0f-417d-9059-8b94a47197eb
|
||||
// sync video: 2618979d-76a5-45e0-83cb-0f192978d1cd
|
||||
// sync audio: 9d2a041b-01cf-4ee4-bffa-188fe093c99b
|
||||
var args appArgs
|
||||
flagSet := pflag.NewFlagSet(APP_NAME, pflag.ContinueOnError)
|
||||
flagSet.SortFlags = false
|
||||
@@ -200,6 +202,19 @@ func main() {
|
||||
// ImGui init
|
||||
gui := imgui.New()
|
||||
defer gui.Destroy()
|
||||
fontConfig := cimgui.NewFontConfig()
|
||||
font := gui.IO().Fonts().AddFontFromFileTTFV(
|
||||
"/home/itten/Downloads/JetBrainsMono/JetBrainsMonoNLNerdFontMono-Regular.ttf",
|
||||
18,
|
||||
fontConfig,
|
||||
nil,
|
||||
)
|
||||
fontConfig.Destroy()
|
||||
if font == nil || font.CData == nil {
|
||||
log.Fatal("failed to load ImGui font")
|
||||
}
|
||||
gui.IO().SetFontDefault(font)
|
||||
// sdl keys handler
|
||||
sdl.StartTextInput(windowHandler)
|
||||
defer sdl.StopTextInput(windowHandler)
|
||||
// fin on ImGui init
|
||||
@@ -421,6 +436,12 @@ func main() {
|
||||
)
|
||||
lastFrame = time.Now()
|
||||
|
||||
// ImGui
|
||||
var (
|
||||
settingWindowWidth float32 = 700
|
||||
settingsWindowState bool = true
|
||||
)
|
||||
|
||||
for running {
|
||||
frameStart := time.Now()
|
||||
var event [128]byte
|
||||
@@ -447,6 +468,8 @@ func main() {
|
||||
resized = true
|
||||
case sdl.KeyF1:
|
||||
showStats = !showStats
|
||||
case sdl.KeyF2:
|
||||
settingsWindowState = !settingsWindowState
|
||||
}
|
||||
}
|
||||
gui.ProcessEvent(&event)
|
||||
@@ -523,8 +546,6 @@ func main() {
|
||||
// end of stats
|
||||
if r != nil {
|
||||
gui.BeginFrame(time.Since(lastFrame), int32(r.Extent().Width), int32(r.Extent().Height))
|
||||
// test widget
|
||||
// cimgui.Begin("Test")
|
||||
if showStats {
|
||||
cimgui.SetNextWindowPos(cimgui.Vec2{X: 10, Y: 10})
|
||||
cimgui.SetNextWindowSize(cimgui.Vec2{X: 200, Y: 200})
|
||||
@@ -540,13 +561,9 @@ func main() {
|
||||
displayedVideoHeight,
|
||||
))
|
||||
}
|
||||
cimgui.Text("\nPress F1 to hide stats")
|
||||
cimgui.Text("Q or Esc to quit")
|
||||
cimgui.Text("F for fullscreen")
|
||||
cimgui.End()
|
||||
}
|
||||
cimgui.Begin("Connection")
|
||||
|
||||
// settings & info window
|
||||
snapshot, hasSnapshot := player.Controller.Snapshot()
|
||||
videoConfigured := videoStr != ""
|
||||
audioConfigured := audioStr != ""
|
||||
@@ -556,147 +573,176 @@ func main() {
|
||||
videoConfigured = snapshot.Desired.Video.IsConfigured()
|
||||
audioConfigured = snapshot.Desired.Audio.IsConfigured()
|
||||
syncRequested = snapshot.Desired.SyncRequested
|
||||
cimgui.Text(fmt.Sprintf(
|
||||
"Topology: %s (generation %d)",
|
||||
snapshot.Plan.Topology,
|
||||
snapshot.Generation,
|
||||
))
|
||||
} else {
|
||||
cimgui.Text("Topology: starting")
|
||||
}
|
||||
|
||||
cimgui.Separator()
|
||||
cimgui.InputTextWithHint("Video domain", "/dev/shm/mxl", &videoDomainStr, 0, nil)
|
||||
cimgui.InputTextWithHint("Video UUID", "", &videoStr, 0, nil)
|
||||
cimgui.InputTextWithHint("Audio domain", "/dev/shm/mxl", &audioDomainStr, 0, nil)
|
||||
cimgui.InputTextWithHint("Audio UUID", "", &audioStr, 0, nil)
|
||||
if cimgui.Button("Apply feeds") {
|
||||
doReconnect()
|
||||
}
|
||||
cimgui.SameLine()
|
||||
if videoActive || audioActive {
|
||||
if cimgui.Button("Stop all") {
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopAll})
|
||||
}
|
||||
}
|
||||
if (videoConfigured && !videoActive) || (audioConfigured && !audioActive) {
|
||||
if videoActive || audioActive {
|
||||
drawSettingsContents := func() {
|
||||
var collapsingHeaderFlags cimgui.TreeNodeFlags = cimgui.TreeNodeFlagsDefaultOpen
|
||||
drawFeedsSections := func() {
|
||||
cimgui.SeparatorText("Video")
|
||||
cimgui.InputTextWithHint("Video domain", "/dev/shm/mxl", &videoDomainStr, 0, nil)
|
||||
cimgui.InputTextWithHint("Video UUID", "", &videoStr, 0, nil)
|
||||
if videoActive {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Stop##video") {
|
||||
videoActive = false
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopVideo})
|
||||
}
|
||||
}
|
||||
if !videoActive && videoConfigured {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Resume##video") {
|
||||
videoActive = true
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeVideo})
|
||||
}
|
||||
}
|
||||
if videoConfigured {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Remove##video") {
|
||||
videoActive = false
|
||||
videoStr = ""
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandRemoveVideo})
|
||||
}
|
||||
}
|
||||
cimgui.SeparatorText("Audio")
|
||||
cimgui.InputTextWithHint("Audio domain", "/dev/shm/mxl", &audioDomainStr, 0, nil)
|
||||
cimgui.InputTextWithHint("Audio UUID", "", &audioStr, 0, nil)
|
||||
if audioActive {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Stop##audio") {
|
||||
audioActive = false
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopAudio})
|
||||
}
|
||||
}
|
||||
|
||||
if !audioActive && audioConfigured {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Resume##audio") {
|
||||
audioActive = true
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeAudio})
|
||||
}
|
||||
}
|
||||
if audioConfigured {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Remove##audio") {
|
||||
audioActive = false
|
||||
audioStr = ""
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandRemoveAudio})
|
||||
}
|
||||
}
|
||||
cimgui.SeparatorText("Controls")
|
||||
if cimgui.Button("Apply feeds") {
|
||||
doReconnect()
|
||||
}
|
||||
cimgui.SameLine()
|
||||
}
|
||||
if cimgui.Button("Resume all") {
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeAll})
|
||||
}
|
||||
}
|
||||
|
||||
if cimgui.Checkbox("Synchronize", &syncRequested) {
|
||||
kind := playback.CommandDisableSync
|
||||
if syncRequested {
|
||||
kind = playback.CommandEnableSync
|
||||
}
|
||||
enqueueCommand(playback.SessionCommand{Kind: kind})
|
||||
}
|
||||
if hasSnapshot && syncRequested && snapshot.Plan.Topology != playback.TopologySynchronized {
|
||||
switch {
|
||||
case !videoConfigured || !audioConfigured:
|
||||
cimgui.TextWrapped("Sync requested: waiting for both feeds to be configured.")
|
||||
case !videoActive || !audioActive:
|
||||
cimgui.TextWrapped("Sync requested: waiting for both feeds to be active.")
|
||||
case snapshot.Desired.Video.Domain != snapshot.Desired.Audio.Domain:
|
||||
cimgui.TextWrapped("Sync requested, but native MXL sync requires matching domains. Playing independently.")
|
||||
default:
|
||||
cimgui.TextWrapped("Sync requested but currently unavailable. Playing independently.")
|
||||
}
|
||||
}
|
||||
|
||||
cimgui.Separator()
|
||||
cimgui.Text("Video")
|
||||
if videoActive {
|
||||
if cimgui.Button("Stop video") {
|
||||
videoActive = false
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopVideo})
|
||||
}
|
||||
}
|
||||
if !videoActive && videoConfigured {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Resume video") {
|
||||
videoActive = true
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeVideo})
|
||||
}
|
||||
}
|
||||
if videoConfigured {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Remove video") {
|
||||
videoActive = false
|
||||
videoStr = ""
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandRemoveVideo})
|
||||
}
|
||||
}
|
||||
if videoActive {
|
||||
cimgui.Text("Video desired: active")
|
||||
} else if videoConfigured {
|
||||
cimgui.Text("Video desired: stopped")
|
||||
} else {
|
||||
cimgui.Text("Video desired: not configured")
|
||||
}
|
||||
|
||||
cimgui.Separator()
|
||||
cimgui.Text("Audio")
|
||||
if audioActive {
|
||||
if cimgui.Button("Stop audio") {
|
||||
audioActive = false
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopAudio})
|
||||
}
|
||||
}
|
||||
|
||||
if !audioActive && audioConfigured {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Resume audio") {
|
||||
audioActive = true
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeAudio})
|
||||
}
|
||||
}
|
||||
|
||||
if audioConfigured {
|
||||
cimgui.SameLine()
|
||||
if cimgui.Button("Remove audio") {
|
||||
audioActive = false
|
||||
audioStr = ""
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandRemoveAudio})
|
||||
}
|
||||
}
|
||||
|
||||
if audioActive {
|
||||
cimgui.Text("Audio desired: active")
|
||||
} else if audioConfigured {
|
||||
cimgui.Text("Audio desired: stopped")
|
||||
} else {
|
||||
cimgui.Text("Audio desired: not configured")
|
||||
}
|
||||
|
||||
cimgui.Separator()
|
||||
cimgui.Text("Current playback")
|
||||
if hasSnapshot {
|
||||
switch snapshot.Plan.Topology {
|
||||
case playback.TopologySynchronized:
|
||||
drawUnitStatus("Synchronized group", playback.UnitSync)
|
||||
case playback.TopologyIndependent:
|
||||
if snapshot.Plan.Video.Active {
|
||||
drawUnitStatus("Video", playback.UnitVideo)
|
||||
if videoActive || audioActive {
|
||||
if cimgui.Button("Stop all") {
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandStopAll})
|
||||
}
|
||||
}
|
||||
if snapshot.Plan.Audio.Active {
|
||||
drawUnitStatus("Audio", playback.UnitAudio)
|
||||
if (videoConfigured && !videoActive) || (audioConfigured && !audioActive) {
|
||||
if videoActive || audioActive {
|
||||
cimgui.SameLine()
|
||||
}
|
||||
if cimgui.Button("Resume all") {
|
||||
enqueueCommand(playback.SessionCommand{Kind: playback.CommandResumeAll})
|
||||
}
|
||||
}
|
||||
case playback.TopologyIdle:
|
||||
cimgui.Text("No active feeds")
|
||||
cimgui.SameLine()
|
||||
if cimgui.Checkbox("Synchronize", &syncRequested) {
|
||||
kind := playback.CommandDisableSync
|
||||
if syncRequested {
|
||||
kind = playback.CommandEnableSync
|
||||
}
|
||||
enqueueCommand(playback.SessionCommand{Kind: kind})
|
||||
}
|
||||
cimgui.SeparatorText("Feeds stats")
|
||||
cimgui.Checkbox("Show stats", &showStats)
|
||||
}
|
||||
if cimgui.CollapsingHeaderTreeNodeFlagsV("Feeds", collapsingHeaderFlags) {
|
||||
drawFeedsSections()
|
||||
}
|
||||
|
||||
drawHotkeysSection := func() {
|
||||
cimgui.Text("F1 - show/hide stats")
|
||||
cimgui.Text("F2 - show/hide settings")
|
||||
cimgui.Text("F - toggle fullscreen")
|
||||
cimgui.Text("Q or Esc - quit")
|
||||
}
|
||||
if cimgui.CollapsingHeaderTreeNodeFlagsV("Hotkeys", collapsingHeaderFlags) {
|
||||
drawHotkeysSection()
|
||||
}
|
||||
|
||||
drawDebugSection := func() {
|
||||
if hasSnapshot {
|
||||
cimgui.Text(fmt.Sprintf(
|
||||
"Topology: %s (generation %d)",
|
||||
snapshot.Plan.Topology,
|
||||
snapshot.Generation,
|
||||
))
|
||||
} else {
|
||||
cimgui.Text("Topology: starting")
|
||||
}
|
||||
if hasSnapshot && syncRequested && snapshot.Plan.Topology != playback.TopologySynchronized {
|
||||
switch {
|
||||
case !videoConfigured || !audioConfigured:
|
||||
cimgui.TextWrapped("Sync requested: waiting for both feeds to be configured.")
|
||||
case !videoActive || !audioActive:
|
||||
cimgui.TextWrapped("Sync requested: waiting for both feeds to be active.")
|
||||
case snapshot.Desired.Video.Domain != snapshot.Desired.Audio.Domain:
|
||||
cimgui.TextWrapped("Sync requested, but native MXL sync requires matching domains. Playing independently.")
|
||||
default:
|
||||
cimgui.TextWrapped("Sync requested but currently unavailable. Playing independently.")
|
||||
}
|
||||
}
|
||||
cimgui.Separator()
|
||||
cimgui.Text("Current playback")
|
||||
if hasSnapshot {
|
||||
switch snapshot.Plan.Topology {
|
||||
case playback.TopologySynchronized:
|
||||
drawUnitStatus("Synchronized group", playback.UnitSync)
|
||||
case playback.TopologyIndependent:
|
||||
if snapshot.Plan.Video.Active {
|
||||
drawUnitStatus("Video", playback.UnitVideo)
|
||||
}
|
||||
if snapshot.Plan.Audio.Active {
|
||||
drawUnitStatus("Audio", playback.UnitAudio)
|
||||
}
|
||||
case playback.TopologyIdle:
|
||||
cimgui.Text("No active feeds")
|
||||
}
|
||||
} else {
|
||||
cimgui.Text("Playback controller is starting")
|
||||
}
|
||||
cimgui.Separator()
|
||||
if videoActive {
|
||||
cimgui.Text("Video desired: active")
|
||||
} else if videoConfigured {
|
||||
cimgui.Text("Video desired: stopped")
|
||||
} else {
|
||||
cimgui.Text("Video desired: not configured")
|
||||
}
|
||||
if audioActive {
|
||||
cimgui.Text("Audio desired: active")
|
||||
} else if audioConfigured {
|
||||
cimgui.Text("Audio desired: stopped")
|
||||
} else {
|
||||
cimgui.Text("Audio desired: not configured")
|
||||
}
|
||||
|
||||
}
|
||||
if cimgui.CollapsingHeaderTreeNodeFlagsV("Debug Info", collapsingHeaderFlags) {
|
||||
drawDebugSection()
|
||||
}
|
||||
} else {
|
||||
cimgui.Text("Playback controller is starting")
|
||||
}
|
||||
|
||||
cimgui.Separator()
|
||||
cimgui.Checkbox("Show stats", &showStats)
|
||||
|
||||
cimgui.End()
|
||||
if settingsWindowState {
|
||||
cimgui.SetNextWindowPos(cimgui.Vec2{X: float32(r.Extent().Width) - settingWindowWidth, Y: 0})
|
||||
cimgui.SetNextWindowSize(cimgui.Vec2{X: settingWindowWidth, Y: float32(r.Extent().Height)})
|
||||
if cimgui.BeginV("Settings & Info", &settingsWindowState, cimgui.WindowFlagsNone) {
|
||||
drawSettingsContents()
|
||||
}
|
||||
cimgui.End()
|
||||
}
|
||||
gui.EndFrame()
|
||||
lastFrame = time.Now()
|
||||
// end of test widget
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[Window][Debug##Default]
|
||||
Pos=60,60
|
||||
Size=400,400
|
||||
Pos=519,181
|
||||
Size=400,398
|
||||
Collapsed=0
|
||||
|
||||
[Window][Test]
|
||||
@@ -14,7 +14,27 @@ Size=200,200
|
||||
Collapsed=0
|
||||
|
||||
[Window][Connection]
|
||||
Pos=322,130
|
||||
Size=661,444
|
||||
Pos=42,264
|
||||
Size=605,416
|
||||
Collapsed=0
|
||||
|
||||
[Window][Test slider]
|
||||
Pos=1370,0
|
||||
Size=550,1080
|
||||
Collapsed=0
|
||||
|
||||
[Window][Settings]
|
||||
Pos=730,0
|
||||
Size=550,720
|
||||
Collapsed=0
|
||||
|
||||
[Window][Settings & Info]
|
||||
Pos=1220,0
|
||||
Size=700,1080
|
||||
Collapsed=0
|
||||
|
||||
[Window][Seetings & Info]
|
||||
Pos=1220,0
|
||||
Size=700,1080
|
||||
Collapsed=0
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ const (
|
||||
KeyF uint32 = 0x66
|
||||
KeyQ uint32 = 0x71
|
||||
KeyF1 uint32 = 0x4000003A
|
||||
KeyF2 uint32 = 0x4000003B
|
||||
|
||||
InitAudio uint32 = 0x00000010
|
||||
AudioDeviceDefaultPlayback uint32 = 0xFFFFFFFF
|
||||
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
VIDEO_ID="2618979d-76a5-45e0-83cb-0f192978d1cd"
|
||||
AUDIO_ID="9d2a041b-01cf-4ee4-bffa-188fe093c99b"
|
||||
VIDEO_URI=$1
|
||||
if [[ -z "${VIDEO_URI}" ]] then
|
||||
VIDEO_URI="${HOME}/Videos/test-vid/motogp.ts"
|
||||
fi
|
||||
export GST_PLUGIN_PATH="${HOME}/.gst-plugin:${GST_PLUGIN_PATH}"
|
||||
mxl-gst-looping-filesrc -d /dev/shm/mxl -i "${VIDEO_URI}" --video-id "${VIDEO_ID}" --audio-id "${AUDIO_ID}" 2>/dev/null
|
||||
# sleep 5
|
||||
# kill -9 $(pidof "mxl-gst-looping-filesrc")
|
||||
# echo -e "\ngst-looping-filesrc killed"
|
||||
Reference in New Issue
Block a user