mixer: add example

This commit is contained in:
outfoxxed 2024-05-19 05:52:18 -07:00
parent b9e744b506
commit 7d0bfb6b61
Signed by: outfoxxed
GPG Key ID: 4C88A185FB89301E
4 changed files with 107 additions and 0 deletions

51
mixer/MixerEntry.qml Normal file
View File

@ -0,0 +1,51 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell.Services.Pipewire
ColumnLayout {
required property PwNode node;
// bind the node so we can read its properties
PwObjectTracker { objects: [ node ] }
RowLayout {
Image {
visible: source != ""
source: {
const icon = node.properties["application.icon-name"] ?? "audio-volume-high-symbolic";
return `image://icon/${icon}`;
}
sourceSize.width: 20
sourceSize.height: 20
}
Label {
text: {
// application.name -> description -> name
const app = node.properties["application.name"] ?? (node.description != "" ? node.description : node.name);
const media = node.properties["media.name"];
return media != undefined ? `${app} - ${media}` : app;
}
}
Button {
text: node.audio.muted ? "unmute" : "mute"
onClicked: node.audio.muted = !node.audio.muted
}
}
RowLayout {
Label {
Layout.preferredWidth: 50
text: `${Math.floor(node.audio.volume * 100)}%`
}
Slider {
Layout.fillWidth: true
value: node.audio.volume
onValueChanged: node.audio.volume = value
}
}
}

7
mixer/README.md Normal file
View File

@ -0,0 +1,7 @@
# Audio mixer
This is a simple audio mixer built with the pipewire API.
You can run the mixer with `quickshell -p shell.qml`.
![](./image.png)

BIN
mixer/image.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

49
mixer/shell.qml Normal file
View File

@ -0,0 +1,49 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import Quickshell.Services.Pipewire
ShellRoot {
FloatingWindow {
// match the system theme background color
color: contentItem.palette.active.window
ScrollView {
anchors.fill: parent
contentWidth: availableWidth
ColumnLayout {
anchors.fill: parent
anchors.margins: 10
// get a list of nodes that output to the default sink
PwNodeLinkTracker {
id: linkTracker
node: Pipewire.defaultAudioSink
}
MixerEntry {
node: Pipewire.defaultAudioSink
}
Rectangle {
Layout.fillWidth: true
color: palette.active.text
implicitHeight: 1
}
Repeater {
model: linkTracker.linkGroups
MixerEntry {
required property PwLinkGroup modelData
// Each link group contains a source and a target.
// Since the target is the default sink, we want the source.
node: modelData.source
}
}
}
}
}
}