49 lines
1.3 KiB
QML
49 lines
1.3 KiB
QML
// Long-lived `cliamp visstream` Process that parses one NDJSON frame per
|
|
// line and exposes the latest bands + visualizer mode as reactive properties.
|
|
//
|
|
// Uses imperative running control (not binding) so the respawn timer can
|
|
// flip the process back on after cliamp restarts.
|
|
|
|
import Quickshell.Io
|
|
import QtQuick
|
|
|
|
Item {
|
|
id: root
|
|
property int fps: 30
|
|
property bool enabled: true
|
|
|
|
property var bands: []
|
|
property string mode: ""
|
|
|
|
function _parseLine(line) {
|
|
if (!line) return;
|
|
try {
|
|
const resp = JSON.parse(line);
|
|
if (!resp || !resp.ok) return;
|
|
if (resp.bands) root.bands = resp.bands;
|
|
if (resp.visualizer) root.mode = resp.visualizer;
|
|
} catch (e) { /* ignore parse errors */ }
|
|
}
|
|
|
|
Process {
|
|
id: proc
|
|
command: ["cliamp", "visstream", "--fps", String(root.fps)]
|
|
running: false
|
|
stdout: SplitParser {
|
|
splitMarker: "\n"
|
|
onRead: (line) => root._parseLine(line)
|
|
}
|
|
}
|
|
|
|
Component.onCompleted: if (root.enabled) proc.running = true
|
|
onEnabledChanged: proc.running = root.enabled
|
|
|
|
// Respawn loop: if cliamp wasn't up yet (or restarted), keep retrying.
|
|
Timer {
|
|
interval: 2000
|
|
running: root.enabled && !proc.running
|
|
repeat: true
|
|
onTriggered: proc.running = true
|
|
}
|
|
}
|