Compare commits
17 Commits
dependency
...
58c3ac0b71
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
58c3ac0b71 | ||
|
|
2858eb3854 | ||
|
|
94b27f5b6a | ||
|
|
8a6f49b949 | ||
|
|
47fd620876 | ||
|
|
c15250498b | ||
|
|
6f0303206e | ||
|
|
6e86647c95 | ||
|
|
798fb3d5e4 | ||
|
|
6c9b76ed90 | ||
|
|
b582584c69 | ||
|
|
7b6e8fc473 | ||
|
|
8f0a810539 | ||
|
|
a6eb82948f | ||
|
|
24727f398a | ||
|
|
c43e9953a5 | ||
|
|
08cb713e8c |
23
.gitignore
vendored
23
.gitignore
vendored
@@ -1,3 +1,20 @@
|
||||
/build
|
||||
.vscode
|
||||
/submodules/arrpc
|
||||
# Ignore build and output directories
|
||||
/build/
|
||||
/.flatpak-builder/
|
||||
|
||||
# Ignore flatpak-builder cache
|
||||
/.flatpak-builder-cache/
|
||||
|
||||
# Ignore flatpak-builder log files
|
||||
/*.log
|
||||
|
||||
# Ignore flatpak-builder generated files
|
||||
/*.flatpak
|
||||
/*.flatpak-builder
|
||||
/*.flatpak-origin
|
||||
|
||||
# Ignore specific files or directories
|
||||
/override.json
|
||||
/metadata/
|
||||
/manifest.json
|
||||
/CMakeLists.txt.user
|
||||
|
||||
@@ -45,7 +45,7 @@ set(discord-screenaudio_SRC
|
||||
src/log.cpp
|
||||
src/userscript.cpp
|
||||
src/centralwidget.cpp
|
||||
src/dependencycheck.cpp
|
||||
src/localserver.cpp
|
||||
resources.qrc
|
||||
)
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ You have multiple options:
|
||||
With apt:
|
||||
`apt install -y build-essential cmake qtbase5-dev qtwebengine5-dev libkf5notifications-dev libkf5xmlgui-dev libkf5globalaccel-dev pkg-config libpipewire-0.3-dev git`
|
||||
|
||||
With dnf:
|
||||
`dnf install @development-tools cmake qt5-qtbase-devel qt5-qtwebengine-devel kf5-knotifications-devel kf5-kxmlgui-devel kf5-kglobalaccel-devel pkgconfig pipewire-devel git`
|
||||
|
||||
### Building
|
||||
|
||||
First, clone the repository:
|
||||
|
||||
BIN
de.shorsh.discord-screenaudio.png
Normal file
BIN
de.shorsh.discord-screenaudio.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
28
install.sh
Executable file
28
install.sh
Executable file
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Build Flatpak package
|
||||
flatpak-builder build-dir lol.deadzone.discord-awesomeaudio.json --install --user --force-clean
|
||||
|
||||
# Create wrapper script
|
||||
echo '#!/bin/bash
|
||||
RUNNING=$(pgrep -f "discord-screenaudio")
|
||||
if [[ -n $RUNNING ]]; then
|
||||
WM_CLASS="discord-screenaudio"
|
||||
else
|
||||
WM_CLASS=""
|
||||
fi
|
||||
flatpak run --env=WM_CLASS="$WM_CLASS" lol.deadzone.discord-awesomeaudio' > ~/.local/bin/discord-awesomeaudio.sh
|
||||
|
||||
# Make the wrapper script executable
|
||||
chmod +x ~/.local/bin/discord-awesomeaudio.sh
|
||||
|
||||
# Create .desktop file
|
||||
echo "[Desktop Entry]
|
||||
Name=Discord Awesome Audio
|
||||
Exec=flatpak run lol.deadzone.discord-awesomeaudio
|
||||
Icon=/path/to/application/icon.png
|
||||
Type=Application
|
||||
Categories=AudioVideo;Network;" > ~/.local/share/applications/discord-awesomeaudio.desktop
|
||||
|
||||
# Make the .desktop file executable (if necessary)
|
||||
chmod +x ~/.local/share/applications/discord-awesomeaudio.desktop
|
||||
44
lol.deadzone.discord-awesomeaudio.json
Normal file
44
lol.deadzone.discord-awesomeaudio.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"app-id": "lol.deadzone.discord-awesomeaudio",
|
||||
"runtime": "org.kde.Platform",
|
||||
"runtime-version": "5.15-22.08",
|
||||
"sdk": "org.kde.Sdk",
|
||||
"base": "io.qt.qtwebengine.BaseApp",
|
||||
"base-version": "5.15-22.08",
|
||||
"command": "discord-screenaudio",
|
||||
"finish-args": [
|
||||
"--share=ipc",
|
||||
"--share=network",
|
||||
"--socket=wayland",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=pulseaudio",
|
||||
"--filesystem=xdg-videos:ro",
|
||||
"--filesystem=xdg-pictures:ro",
|
||||
"--filesystem=xdg-download",
|
||||
"--filesystem=xdg-run/pipewire-0",
|
||||
"--device=all",
|
||||
"--talk-name=org.kde.StatusNotifierWatcher",
|
||||
"--env=QTWEBENGINEPROCESS_PATH=/app/bin/QtWebEngineProcess",
|
||||
"--talk-name=org.freedesktop.Notifications",
|
||||
"--talk-name=org.kde.kglobalaccel"
|
||||
],
|
||||
"modules": [
|
||||
{
|
||||
"name": "discord-screenaudio",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"config-opts": [
|
||||
"-DCMAKE_BUILD_TYPE=RelWithDebInfo",
|
||||
"-DGIT_SUBMODULE=OFF"
|
||||
],
|
||||
"sources": [
|
||||
{
|
||||
"type": "dir",
|
||||
"path": "."
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"finish-install": {
|
||||
"desktop-file": "[Desktop Entry]\nName=Discord Awesome Audio\nExec=flatpak run lol.deadzone.discord-awesomeaudio\nIcon=/path/to/application/icon.png\nType=Application\nCategories=AudioVideo;Network;"
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
#include "dependencycheck.h"
|
||||
#include "pipewire-0.3/pipewire/version.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
void checkDependencies() {
|
||||
QString versionPipewire(pw_get_library_version());
|
||||
QMessageBox::information(nullptr, "Dependency Check",
|
||||
QString("Pipewire: v%1").arg(versionPipewire));
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
void checkDependencies();
|
||||
@@ -282,6 +282,7 @@ void DiscordPage::javaScriptConsoleMessage(
|
||||
ansi += "\033[" + cssAnsiColorMap[color] + "m";
|
||||
}
|
||||
}
|
||||
if (endOfStyles < lines.length())
|
||||
qDebug(discordLog) << (ansi + lines[0].trimmed() + "\033[0m " +
|
||||
lines[endOfStyles].trimmed())
|
||||
.toUtf8()
|
||||
|
||||
22
src/localserver.cpp
Normal file
22
src/localserver.cpp
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "localserver.h"
|
||||
|
||||
bool isProgramRunning(const QString &program_name) {
|
||||
QLocalSocket socket;
|
||||
socket.connectToServer(program_name);
|
||||
if (socket.waitForConnected()) {
|
||||
return true; // program is already running
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void showErrorMessage(const char *text) {
|
||||
QMessageBox msgBox;
|
||||
|
||||
msgBox.setIcon(QMessageBox::Critical);
|
||||
msgBox.setText(text);
|
||||
msgBox.setStandardButtons(QMessageBox::Ok);
|
||||
msgBox.setDefaultButton(QMessageBox::Ok);
|
||||
msgBox.setWindowIcon(QIcon(":assets/de.shorsh.discord-screenaudio.png"));
|
||||
|
||||
msgBox.exec();
|
||||
}
|
||||
9
src/localserver.h
Normal file
9
src/localserver.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
#include "mainwindow.h"
|
||||
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QMessageBox>
|
||||
|
||||
bool isProgramRunning(const QString &program_name);
|
||||
void showErrorMessage(const char *text);
|
||||
22
src/main.cpp
22
src/main.cpp
@@ -1,4 +1,4 @@
|
||||
#include "dependencycheck.h"
|
||||
#include "localserver.h"
|
||||
#include "mainwindow.h"
|
||||
#include "virtmic.h"
|
||||
|
||||
@@ -8,10 +8,14 @@
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineParser>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
#include <QLoggingCategory>
|
||||
#include <QMessageBox>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
QApplication app(argc, argv);
|
||||
|
||||
QApplication::setApplicationName("discord-screenaudio");
|
||||
QApplication::setWindowIcon(
|
||||
QIcon(":assets/de.shorsh.discord-screenaudio.png"));
|
||||
@@ -50,9 +54,21 @@ int main(int argc, char *argv[]) {
|
||||
"--remote-debugging-port=9222 " +
|
||||
qgetenv("QTWEBENGINE_CHROMIUM_FLAGS"));
|
||||
|
||||
checkDependencies();
|
||||
|
||||
MainWindow w(parser.isSet(notifySendOption));
|
||||
|
||||
// Check if discord is already running
|
||||
QString program_name = "discord-screenaudio";
|
||||
if (isProgramRunning(program_name)) {
|
||||
// if running show error message
|
||||
showErrorMessage("discord-screenaudio is already running");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// open server so we can check if discord is running
|
||||
QLocalServer server;
|
||||
server.listen(program_name);
|
||||
QObject::connect(&server, &QLocalServer::newConnection, []() {});
|
||||
|
||||
w.show();
|
||||
|
||||
return app.exec();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QShortcut>
|
||||
#include <QSpacerItem>
|
||||
#include <QThread>
|
||||
#include <QTimer>
|
||||
@@ -31,6 +32,8 @@ MainWindow::MainWindow(bool useNotifySend, QWidget *parent)
|
||||
setCentralWidget(m_centralWidget);
|
||||
setupTrayIcon();
|
||||
setMinimumSize(800, 300);
|
||||
connect(new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this),
|
||||
&QShortcut::activated, this, &MainWindow::toggleOrCloseWindow);
|
||||
if (m_settings->contains("geometry")) {
|
||||
restoreGeometry(m_settings->value("geometry").toByteArray());
|
||||
} else {
|
||||
@@ -79,12 +82,7 @@ void MainWindow::setupTrayIcon() {
|
||||
|
||||
connect(m_trayIcon, &QSystemTrayIcon::activated, [this](auto reason) {
|
||||
if (reason == QSystemTrayIcon::Trigger) {
|
||||
if (isVisible()) {
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
activateWindow();
|
||||
}
|
||||
toggleOrCloseWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -131,3 +129,15 @@ MainWindow *MainWindow::instance() { return m_instance; }
|
||||
CentralWidget *MainWindow::centralWidget() {
|
||||
return instance()->m_centralWidget;
|
||||
};
|
||||
|
||||
void MainWindow::toggleOrCloseWindow() {
|
||||
if (isVisible()) {
|
||||
if (m_trayIcon == nullptr)
|
||||
QApplication::quit();
|
||||
else
|
||||
hide();
|
||||
} else {
|
||||
show();
|
||||
activateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,4 +36,5 @@ private:
|
||||
public Q_SLOTS:
|
||||
void setTrayIcon(bool enabled);
|
||||
void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest);
|
||||
void toggleOrCloseWindow();
|
||||
};
|
||||
|
||||
@@ -44,6 +44,10 @@ void UserScript::setupHelpMenu() {
|
||||
QString(), "https://github.com/Curve");
|
||||
aboutData.addComponent("Rohrkabel", "A C++ RAII Pipewire-API Wrapper", "1.3",
|
||||
"https://github.com/Soundux/rohrkabel");
|
||||
aboutData.addComponent("arRPC",
|
||||
"An open implementation of Discord's local RPC "
|
||||
"servers<br>Copyright (c) 2022 OpenAsar",
|
||||
nullptr, "https://github.com/OpenAsar/arrpc");
|
||||
m_helpMenu = new KHelpMenu(MainWindow::instance(), aboutData);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -8,6 +8,25 @@ namespace Virtmic {
|
||||
|
||||
const QStringList EXCLUDE_TARGETS{"Chromium input", "discord-screenaudio"};
|
||||
|
||||
const std::string nullstr = "";
|
||||
const std::string &getTarget(const pipewire::spa::dict &props) {
|
||||
if (props.count("media.class") &&
|
||||
props.at("media.class") == "Stream/Output/Audio") {
|
||||
if (props.count("application.name") && props.at("application.name") != "")
|
||||
return props.at("application.name");
|
||||
else if (props.count("application.process.binary") &&
|
||||
props.at("application.process.binary") != "")
|
||||
return props.at("application.process.binary");
|
||||
else
|
||||
return props.at("node.name");
|
||||
} else
|
||||
return nullstr;
|
||||
}
|
||||
|
||||
QString qGetTarget(const pipewire::spa::dict &props) {
|
||||
return QString::fromStdString(getTarget(props));
|
||||
}
|
||||
|
||||
QVector<QString> getTargets() {
|
||||
auto main_loop = pipewire::main_loop();
|
||||
auto context = pipewire::context(main_loop);
|
||||
@@ -22,14 +41,7 @@ QVector<QString> getTargets() {
|
||||
if (global.type == pipewire::node::type) {
|
||||
auto node = reg.bind<pipewire::node>(global.id);
|
||||
auto info = node.info();
|
||||
QString name;
|
||||
if (info.props.count("application.name") &&
|
||||
info.props["application.name"] != "")
|
||||
name = QString::fromStdString(info.props["application.name"]);
|
||||
else
|
||||
name = QString::fromStdString(
|
||||
info.props["application.process.binary"]);
|
||||
|
||||
QString name = qGetTarget(info.props);
|
||||
if (name != "" && !EXCLUDE_TARGETS.contains(name) &&
|
||||
!targets.contains(name)) {
|
||||
targets.append(name);
|
||||
@@ -73,13 +85,7 @@ void start(QString _target) {
|
||||
continue;
|
||||
|
||||
auto &parent = nodes.at(parent_id);
|
||||
std::string name;
|
||||
if (parent.props.count("application.name") &&
|
||||
parent.props["application.name"] != "")
|
||||
name = parent.props["application.name"];
|
||||
else
|
||||
name = parent.props["application.process.binary"];
|
||||
|
||||
std::string name = getTarget(parent.props);
|
||||
if (name == target ||
|
||||
(target == "[All Desktop Audio]" &&
|
||||
!EXCLUDE_TARGETS.contains(QString::fromStdString(name)))) {
|
||||
@@ -99,7 +105,7 @@ void start(QString _target) {
|
||||
}
|
||||
};
|
||||
|
||||
std::string target = _target.toLatin1().toStdString();
|
||||
std::string target = _target.toUtf8().toStdString();
|
||||
|
||||
auto virtual_mic = core.create("adapter",
|
||||
{{"node.name", "discord-screenaudio-virtmic"},
|
||||
@@ -123,13 +129,8 @@ void start(QString _target) {
|
||||
if (global.type == pipewire::node::type) {
|
||||
auto node = reg.bind<pipewire::node>(global.id);
|
||||
auto info = node.info();
|
||||
std::string name;
|
||||
if (info.props.count("application.name") &&
|
||||
info.props["application.name"] != "")
|
||||
name = info.props["application.name"];
|
||||
else if (info.props.count("application.process.binary")) {
|
||||
name = info.props["application.process.binary"];
|
||||
} else
|
||||
std::string name = getTarget(info.props);
|
||||
if (name == nullstr)
|
||||
return;
|
||||
qDebug(virtmicLog) << QString("Added: %1")
|
||||
.arg(QString::fromStdString(name))
|
||||
@@ -168,12 +169,9 @@ void start(QString _target) {
|
||||
[&](const std::uint32_t id) {
|
||||
if (nodes.count(id)) {
|
||||
auto info = nodes.at(id);
|
||||
std::string name;
|
||||
if (info.props.count("application.name") &&
|
||||
info.props["application.name"] != "")
|
||||
name = info.props["application.name"];
|
||||
else
|
||||
name = info.props["application.process.binary"];
|
||||
std::string name = getTarget(info.props);
|
||||
if (name == nullstr)
|
||||
return;
|
||||
qDebug(virtmicLog) << QString("Removed: %1")
|
||||
.arg(QString::fromStdString(name))
|
||||
.toUtf8()
|
||||
|
||||
2
uninstall.sh
Executable file
2
uninstall.sh
Executable file
@@ -0,0 +1,2 @@
|
||||
flatpak remove lol.deadzone.discord-awesomeaudio
|
||||
rm ~/.local/share/applications/discord-awesomeaudio.desktop
|
||||
Reference in New Issue
Block a user