mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-07 14:05:38 -05:00
make cava a singleton
This commit is contained in:
@@ -1,6 +1,4 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
import Quickshell.Services.Mpris
|
import Quickshell.Services.Mpris
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
@@ -8,69 +6,33 @@ import qs.Services
|
|||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var audioLevels: [0, 0, 0, 0, 0, 0]
|
|
||||||
readonly property MprisPlayer activePlayer: MprisController.activePlayer
|
readonly property MprisPlayer activePlayer: MprisController.activePlayer
|
||||||
readonly property bool hasActiveMedia: activePlayer !== null
|
readonly property bool hasActiveMedia: activePlayer !== null
|
||||||
property bool cavaAvailable: false
|
readonly property bool isPlaying: hasActiveMedia && activePlayer && activePlayer.playbackState === MprisPlaybackState.Playing
|
||||||
|
|
||||||
width: 20
|
width: 20
|
||||||
height: Theme.iconSize
|
height: Theme.iconSize
|
||||||
|
|
||||||
Process {
|
Ref {
|
||||||
id: cavaCheck
|
service: CavaService
|
||||||
|
|
||||||
command: ["which", "cava"]
|
|
||||||
running: true
|
|
||||||
onExited: (exitCode) => {
|
|
||||||
root.cavaAvailable = exitCode === 0;
|
|
||||||
if (root.cavaAvailable)
|
|
||||||
cavaProcess.running = Qt.binding(() => {
|
|
||||||
return root.hasActiveMedia && root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing;
|
|
||||||
});
|
|
||||||
else
|
|
||||||
fallbackTimer.running = Qt.binding(() => {
|
|
||||||
return root.hasActiveMedia && root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: cavaProcess
|
|
||||||
|
|
||||||
running: false
|
|
||||||
command: ["sh", "-c", `printf '[general]\nmode=normal\nframerate=25\nautosens=0\nsensitivity=30\nbars=6\nlower_cutoff_freq=50\nhigher_cutoff_freq=12000\n[output]\nmethod=raw\nraw_target=/dev/stdout\ndata_format=ascii\nchannels=mono\nmono_option=average\n[smoothing]\nnoise_reduction=35\nintegral=90\ngravity=95\nignore=2\nmonstercat=1.5' | cava -p /dev/stdin`]
|
|
||||||
onRunningChanged: {
|
|
||||||
if (!running)
|
|
||||||
root.audioLevels = [0, 0, 0, 0, 0, 0];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
stdout: SplitParser {
|
|
||||||
splitMarker: "\n"
|
|
||||||
onRead: (data) => {
|
|
||||||
if (data.trim()) {
|
|
||||||
let points = data.split(";").map((p) => {
|
|
||||||
return parseFloat(p.trim());
|
|
||||||
}).filter((p) => {
|
|
||||||
return !isNaN(p);
|
|
||||||
});
|
|
||||||
if (points.length >= 6)
|
|
||||||
root.audioLevels = [points[0], points[1], points[2], points[3], points[4], points[5]];
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: fallbackTimer
|
id: fallbackTimer
|
||||||
|
|
||||||
running: false
|
running: !CavaService.cavaAvailable && isPlaying
|
||||||
interval: 256
|
interval: 256
|
||||||
repeat: true
|
repeat: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.audioLevels = [Math.random() * 40 + 10, Math.random() * 60 + 20, Math.random() * 50 + 15, Math.random() * 35 + 20, Math.random() * 45 + 15, Math.random() * 55 + 25];
|
// Generate fake audio levels when cava is unavailable
|
||||||
|
CavaService.values = [
|
||||||
|
Math.random() * 40 + 10,
|
||||||
|
Math.random() * 60 + 20,
|
||||||
|
Math.random() * 50 + 15,
|
||||||
|
Math.random() * 35 + 20,
|
||||||
|
Math.random() * 45 + 15,
|
||||||
|
Math.random() * 55 + 25
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,8 +46,8 @@ Item {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
width: 2
|
width: 2
|
||||||
height: {
|
height: {
|
||||||
if (root.activePlayer && root.activePlayer.playbackState === MprisPlaybackState.Playing && root.audioLevels.length > index) {
|
if (root.isPlaying && CavaService.values.length > index) {
|
||||||
const rawLevel = root.audioLevels[index] || 0;
|
const rawLevel = CavaService.values[index] || 0;
|
||||||
const scaledLevel = Math.sqrt(Math.min(Math.max(rawLevel, 0), 100) / 100) * 100;
|
const scaledLevel = Math.sqrt(Math.min(Math.max(rawLevel, 0), 100) / 100) * 100;
|
||||||
const maxHeight = Theme.iconSize - 2;
|
const maxHeight = Theme.iconSize - 2;
|
||||||
const minHeight = 3;
|
const minHeight = 3;
|
||||||
|
|||||||
53
Services/CavaService.qml
Normal file
53
Services/CavaService.qml
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
pragma Singleton
|
||||||
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
|
||||||
|
Singleton {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property list<int> values: Array(6)
|
||||||
|
property int refCount: 0
|
||||||
|
property bool cavaAvailable: false
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: cavaCheck
|
||||||
|
|
||||||
|
command: ["which", "cava"]
|
||||||
|
running: true
|
||||||
|
onExited: (exitCode) => {
|
||||||
|
root.cavaAvailable = exitCode === 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: cavaProcess
|
||||||
|
|
||||||
|
running: root.cavaAvailable && root.refCount > 0
|
||||||
|
command: ["sh", "-c", `printf '[general]\\nmode=normal\\nframerate=25\\nautosens=0\\nsensitivity=30\\nbars=6\\nlower_cutoff_freq=50\\nhigher_cutoff_freq=12000\\n[output]\\nmethod=raw\\nraw_target=/dev/stdout\\ndata_format=ascii\\nchannels=mono\\nmono_option=average\\n[smoothing]\\nnoise_reduction=35\\nintegral=90\\ngravity=95\\nignore=2\\nmonstercat=1.5' | cava -p /dev/stdin`]
|
||||||
|
|
||||||
|
onRunningChanged: {
|
||||||
|
if (!running) {
|
||||||
|
root.values = Array(6).fill(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout: SplitParser {
|
||||||
|
splitMarker: "\n"
|
||||||
|
onRead: (data) => {
|
||||||
|
if (root.refCount > 0 && data.trim()) {
|
||||||
|
let points = data.split(";").map((p) => {
|
||||||
|
return parseInt(p.trim(), 10);
|
||||||
|
}).filter((p) => {
|
||||||
|
return !isNaN(p);
|
||||||
|
});
|
||||||
|
if (points.length >= 6) {
|
||||||
|
root.values = points.slice(0, 6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user