mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-26 22:42:50 -05:00
audio: un-dumbify audio service
This commit is contained in:
@@ -11,142 +11,10 @@ Singleton {
|
||||
readonly property PwNode sink: Pipewire.defaultAudioSink
|
||||
readonly property PwNode source: Pipewire.defaultAudioSource
|
||||
|
||||
readonly property bool sinkMuted: sink?.audio?.muted ?? false
|
||||
readonly property bool sourceMuted: source?.audio?.muted ?? false
|
||||
readonly property real volumeLevel: (sink?.audio?.volume ?? 0) * 100
|
||||
readonly property real micLevel: (source?.audio?.volume ?? 0) * 100
|
||||
|
||||
property ListModel audioSinksModel: ListModel {}
|
||||
property ListModel audioSourcesModel: ListModel {}
|
||||
|
||||
property var audioSinks: []
|
||||
property var audioSources: []
|
||||
|
||||
Component.onCompleted: _rebuildModels()
|
||||
|
||||
Connections {
|
||||
target: Pipewire
|
||||
function onReadyChanged() { _rebuildModels() }
|
||||
function onDefaultAudioSinkChanged() { _rebuildModels() }
|
||||
function onDefaultAudioSourceChanged() { _rebuildModels() }
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 2000
|
||||
running: Pipewire.ready
|
||||
repeat: true
|
||||
onTriggered: _checkForNodeChanges()
|
||||
}
|
||||
|
||||
property int _lastNodeCount: 0
|
||||
|
||||
function _checkForNodeChanges() {
|
||||
if (Pipewire.nodes?.values) {
|
||||
let currentCount = Pipewire.nodes.values.length
|
||||
if (currentCount !== _lastNodeCount) {
|
||||
_lastNodeCount = currentCount
|
||||
_rebuildModels()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
readonly property string currentAudioSink: sink?.name ?? ""
|
||||
readonly property string currentAudioSource: source?.name ?? ""
|
||||
|
||||
readonly property string currentSinkDisplayName: {
|
||||
if (!sink) return ""
|
||||
for (let i = 0; i < audioSinksModel.count; i++) {
|
||||
let item = audioSinksModel.get(i)
|
||||
if (item.node === sink) {
|
||||
return item.displayName
|
||||
}
|
||||
}
|
||||
return _displayName(sink)
|
||||
}
|
||||
|
||||
readonly property string currentSourceDisplayName: {
|
||||
if (!source) return ""
|
||||
for (let i = 0; i < audioSourcesModel.count; i++) {
|
||||
let item = audioSourcesModel.get(i)
|
||||
if (item.node === source) {
|
||||
return item.displayName
|
||||
}
|
||||
}
|
||||
return _displayName(source)
|
||||
}
|
||||
|
||||
function setVolume(percentage) {
|
||||
if (sink?.audio) {
|
||||
sink.audio.muted = false
|
||||
sink.audio.volume = percentage / 100
|
||||
}
|
||||
}
|
||||
|
||||
function setMicLevel(percentage) {
|
||||
if (source?.audio) {
|
||||
source.audio.muted = false
|
||||
source.audio.volume = percentage / 100
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMute() {
|
||||
if (sink?.audio) {
|
||||
sink.audio.muted = !sink.audio.muted
|
||||
}
|
||||
}
|
||||
|
||||
function toggleMicMute() {
|
||||
if (source?.audio) {
|
||||
source.audio.muted = !source.audio.muted
|
||||
}
|
||||
}
|
||||
|
||||
function setAudioSink(sinkName) {
|
||||
_setPreferred(sinkName, PwNodeType.AudioSink)
|
||||
}
|
||||
|
||||
function setAudioSource(sourceName) {
|
||||
_setPreferred(sourceName, PwNodeType.AudioSource)
|
||||
}
|
||||
|
||||
function _rebuildModels() {
|
||||
audioSinksModel.clear()
|
||||
audioSourcesModel.clear()
|
||||
function displayName(node) {
|
||||
if (!node) return ""
|
||||
|
||||
let sinks = []
|
||||
let sources = []
|
||||
|
||||
if (!Pipewire.ready || !Pipewire.nodes?.values) return
|
||||
|
||||
for (let i = 0; i < Pipewire.nodes.values.length; i++) {
|
||||
let node = Pipewire.nodes.values[i]
|
||||
if (!node || node.isStream) continue
|
||||
|
||||
let entry = {
|
||||
id: node.id.toString(),
|
||||
name: node.name,
|
||||
displayName: _displayName(node),
|
||||
subtitle: _subtitle(node.name),
|
||||
active: node === sink || node === source,
|
||||
node: node
|
||||
}
|
||||
|
||||
if ((node.type & PwNodeType.AudioSink) === PwNodeType.AudioSink) {
|
||||
audioSinksModel.append(entry)
|
||||
sinks.push(entry)
|
||||
}
|
||||
if ((node.type & PwNodeType.AudioSource) === PwNodeType.AudioSource && !node.name.includes(".monitor")) {
|
||||
audioSourcesModel.append(entry)
|
||||
sources.push(entry)
|
||||
}
|
||||
}
|
||||
|
||||
audioSinks = sinks
|
||||
audioSources = sources
|
||||
}
|
||||
|
||||
function _displayName(node) {
|
||||
if (node.properties?.["device.description"]) {
|
||||
if (node.properties && node.properties["device.description"]) {
|
||||
return node.properties["device.description"]
|
||||
}
|
||||
|
||||
@@ -166,7 +34,7 @@ Singleton {
|
||||
return node.name
|
||||
}
|
||||
|
||||
function _subtitle(name) {
|
||||
function subtitle(name) {
|
||||
if (!name) return ""
|
||||
|
||||
if (name.includes('usb-')) {
|
||||
@@ -192,22 +60,6 @@ Singleton {
|
||||
return ""
|
||||
}
|
||||
|
||||
function _setPreferred(name, kind) {
|
||||
if (!Pipewire.nodes?.values) return
|
||||
|
||||
for (let i = 0; i < Pipewire.nodes.values.length; i++) {
|
||||
let node = Pipewire.nodes.values[i]
|
||||
if (node && node.name === name && !node.isStream && ((node.type & kind) === kind)) {
|
||||
if (kind === PwNodeType.AudioSink) {
|
||||
Pipewire.preferredDefaultAudioSink = node
|
||||
} else if (kind === PwNodeType.AudioSource) {
|
||||
Pipewire.preferredDefaultAudioSource = node
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PwObjectTracker {
|
||||
objects: [Pipewire.defaultAudioSink, Pipewire.defaultAudioSource]
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ Singleton {
|
||||
return [];
|
||||
|
||||
return adapter.devices.values.filter((dev) => {
|
||||
return dev && dev.paired && isValidDevice(dev);
|
||||
return dev && dev.paired;
|
||||
});
|
||||
}
|
||||
readonly property var allDevicesWithBattery: {
|
||||
@@ -47,20 +47,6 @@ Singleton {
|
||||
});
|
||||
}
|
||||
|
||||
function isValidDevice(device) {
|
||||
if (!device)
|
||||
return false;
|
||||
|
||||
var displayName = device.name || device.deviceName;
|
||||
if (!displayName || displayName.length < 2)
|
||||
return false;
|
||||
|
||||
if (displayName.startsWith('/org/bluez') || displayName.includes('hci0'))
|
||||
return false;
|
||||
|
||||
return displayName.length >= 3;
|
||||
}
|
||||
|
||||
function getDeviceIcon(device) {
|
||||
if (!device)
|
||||
return "bluetooth";
|
||||
|
||||
Reference in New Issue
Block a user