Compare commits

..

1 Commits

Author SHA1 Message Date
Malte Jürgens
bdabf68c9b add chromium flags for hardware acceleration 2022-10-15 20:28:38 +02:00
12 changed files with 117 additions and 196 deletions

View File

@@ -13,9 +13,10 @@ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DDEBUG")
string(TIMESTAMP TIMESTAMP %s)
# set(CMAKE_AUTOUIC ON)
find_package(Qt5 COMPONENTS Widgets)
if (Qt5_FOUND)
find_package(Qt5 CONFIG REQUIRED COMPONENTS Widgets WebEngineWidgets)
find_package(Qt5 CONFIG REQUIRED COMPONENTS
Widgets
WebEngineWidgets
)
find_package(KF5Notifications)
if(KF5Notifications_FOUND)
@@ -31,10 +32,6 @@ if (Qt5_FOUND)
if(KF5GlobalAccel_FOUND)
add_definitions( -DKGLOBALACCEL )
endif()
else()
message(WARNING "Qt 5 was not found on your system and Qt 6 will be used. You will not be able to use any features using KDE Frameworks.")
find_package(Qt6 CONFIG REQUIRED COMPONENTS Widgets WebEngineWidgets)
endif()
set(discord-screenaudio_SRC
src/main.cpp
@@ -69,7 +66,7 @@ add_subdirectory(submodules/rohrkabel)
add_executable(discord-screenaudio ${discord-screenaudio_SRC})
target_link_libraries(discord-screenaudio Qt::Widgets Qt::WebEngineWidgets rohrkabel)
target_link_libraries(discord-screenaudio Qt5::Widgets Qt5::WebEngineWidgets rohrkabel)
if(KF5Notifications_FOUND)
target_link_libraries(discord-screenaudio KF5::Notifications)

View File

@@ -11,7 +11,7 @@ Unlike a lot of other solutions, the audio here is directly fed into the
screenshare and not passed to the user microphone
([see explanation](#how-it-works)).
![Screenshot_20221211_185028](https://user-images.githubusercontent.com/48161361/206920213-58a8091a-d8f9-4bb7-ae3d-3f8581b84d24.png)
![Screenshot_20220925_112945](https://user-images.githubusercontent.com/48161361/192137080-33466cf7-8c56-4373-90c6-01ea74b6fb83.png)
The purpose of this project is **not** to provide an alternative to the original
Discord client. Rather, it should be used in addition to the original client in
@@ -50,8 +50,6 @@ You have multiple options:
### Requirements
- Basic building tools
- An up-to-date system (I can't guarantee that it works on Debian or Ubuntu
20/21)
- CMake
- Qt5 and QtWebEngine
- **PipeWire** (it currently doesn't work with PulseAudio)
@@ -59,7 +57,7 @@ You have multiple options:
- _Kf5Notifications (optional, for better notifications)_
- _KXMLGui and KGlobalAccel (optional, for keybinds)_
With apt:
On Debian:
`apt install -y build-essential cmake qtbase5-dev qtwebengine5-dev libkf5notifications-dev libkf5xmlgui-dev libkf5globalaccel-dev pkg-config libpipewire-0.3-dev git`
### Building

View File

@@ -4,7 +4,6 @@
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
<name>discord-screenaudio</name>
<developer_name>Malte Jürgens</developer_name>
<releases>
<release version="${DISCORD_SCEENAUDIO_VERSION_FULL}" timestamp="${TIMESTAMP}" />
</releases>

View File

@@ -25,7 +25,7 @@ const getAudioDevice = async (nameOfAudioDevice) => {
return audioDevice;
};
function setGetDisplayMedia(video = true, overrideArgs = undefined) {
function setGetDisplayMedia(overrideArgs = undefined) {
const getDisplayMedia = async (...args) => {
var id;
try {
@@ -63,7 +63,6 @@ function setGetDisplayMedia(video = true, overrideArgs = undefined) {
: args || [{ video: true, audio: true }])
);
gdm.addTrack(track);
if (!video) for (const track of gdm.getVideoTracks()) track.enabled = false;
return gdm;
};
navigator.mediaDevices.getDisplayMedia = getDisplayMedia;
@@ -112,16 +111,9 @@ setInterval(() => {
const initialDisplay = el.style.display;
window.discordScreenaudioStartStream = (
video,
width,
height,
frameRate
) => {
window.discordScreenaudioResolutionString = video
? `${height}p ${frameRate}FPS`
: "Audio Only";
setGetDisplayMedia(video, {
window.discordScreenaudioStartStream = (width, height, frameRate) => {
window.discordScreenaudioResolutionString = `${height}p ${frameRate}FPS`;
setGetDisplayMedia({
audio: true,
video: { width, height, frameRate },
});
@@ -171,7 +163,7 @@ setInterval(() => {
document
.getElementById("keybinds-tab")
?.getElementsByClassName(
"container-3jbRo5 info-1hMolH browserNotice-1u-Y5o"
"container-3jbRo5 info-1hMolH fontSize16-3zr6Io browserNotice-1u-Y5o"
).length
) {
const el = document
@@ -191,28 +183,14 @@ setInterval(() => {
el.appendChild(div);
}
const buttonContainer =
document.getElementsByClassName("container-YkUktl")[0];
if (!buttonContainer) {
console.log(
"dsa: Cannot locate Mute/Deafen/Settings button container, please report this on GitHub"
);
}
const muteBtn = buttonContainer
? buttonContainer.getElementsByClassName(
const muteBtn = document.getElementsByClassName(
"button-12Fmur enabled-9OeuTA button-f2h6uQ lookBlank-21BCro colorBrand-I6CyqQ grow-2sR_-F"
)[0]
: null;
window.discordScreenaudioToggleMute = () => muteBtn && muteBtn.click();
const deafenBtn = buttonContainer
? buttonContainer.getElementsByClassName(
)[0];
window.discordScreenaudioToggleMute = () => muteBtn.click();
const deafenBtn = document.getElementsByClassName(
"button-12Fmur enabled-9OeuTA button-f2h6uQ lookBlank-21BCro colorBrand-I6CyqQ grow-2sR_-F"
)[1]
: null;
window.discordScreenaudioToggleDeafen = () => deafenBtn && deafenBtn.click();
)[1];
window.discordScreenaudioToggleDeafen = () => deafenBtn.click();
if (window.discordScreenaudioResolutionString) {
for (const el of document.getElementsByClassName(

View File

@@ -186,9 +186,11 @@ void DiscordPage::stopVirtmic() {
}
void DiscordPage::startVirtmic(QString target) {
if (target != "None") {
qDebug(virtmicLog) << "Starting Virtmic with target" << target;
m_virtmicProcess.start(QApplication::arguments()[0], {"--virtmic", target});
}
}
void DiscordPage::javaScriptConsoleMessage(
QWebEnginePage::JavaScriptConsoleMessageLevel level, const QString &message,
@@ -228,18 +230,16 @@ void DiscordPage::javaScriptConsoleMessage(
}
}
void DiscordPage::startStream(bool video, bool audio, uint width, uint height,
uint frameRate, QString target) {
void DiscordPage::startStream(QString target, uint width, uint height,
uint frameRate) {
stopVirtmic();
startVirtmic(audio ? target : "[None]");
startVirtmic(target);
// Wait a bit for the virtmic to start
QTimer::singleShot(200, [=]() {
runJavaScript(
QString("window.discordScreenaudioStartStream(%1, %2, %3, %4);")
.arg(video)
.arg(video ? width : 32)
.arg(video ? height : 16)
.arg(video ? frameRate : 1));
QTimer::singleShot(target == "None" ? 0 : 200, [=]() {
runJavaScript(QString("window.discordScreenaudioStartStream(%1, %2, %3);")
.arg(width)
.arg(height)
.arg(frameRate));
});
}

View File

@@ -47,8 +47,7 @@ private:
private Q_SLOTS:
void featurePermissionRequested(const QUrl &securityOrigin,
QWebEnginePage::Feature feature);
void startStream(bool video, bool audio, uint width, uint height,
uint frameRate, QString target);
void startStream(QString target, uint width, uint height, uint frameRate);
};
// Will immediately get destroyed again but is needed for navigation to

View File

@@ -30,9 +30,6 @@ int main(int argc, char *argv[]) {
QCommandLineOption degubOption("remote-debugging",
"Open Chromium Remote Debugging on port 9222");
parser.addOption(degubOption);
QCommandLineOption notifySendOption(
"notify-send", "Use notify-send instead of QT/KF5 notifications");
parser.addOption(notifySendOption);
parser.process(app);
@@ -41,6 +38,8 @@ int main(int argc, char *argv[]) {
}
qputenv("QTWEBENGINE_CHROMIUM_FLAGS",
"--ignore-gpu-blacklist --enable-gpu-rasterization "
"--enable-native-gpu-memory-buffers --num-raster-threads=4 "
"--enable-features=WebRTCPipeWireCapturer " +
qgetenv("QTWEBENGINE_CHROMIUM_FLAGS"));
@@ -49,7 +48,7 @@ int main(int argc, char *argv[]) {
"--remote-debugging-port=9222 " +
qgetenv("QTWEBENGINE_CHROMIUM_FLAGS"));
MainWindow w(parser.isSet(notifySendOption));
MainWindow w;
w.show();
return app.exec();

View File

@@ -24,11 +24,9 @@
MainWindow *MainWindow::m_instance = nullptr;
MainWindow::MainWindow(bool useNotifySend, QWidget *parent)
: QMainWindow(parent) {
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
assert(MainWindow::m_instance == nullptr);
MainWindow::m_instance = this;
m_useNotifySend = useNotifySend;
setupWebView();
resize(1000, 700);
showMaximized();
@@ -42,26 +40,13 @@ void MainWindow::setupWebView() {
m_webView = new QWebEngineView(this);
m_webView->setPage(page);
if (m_useKF5Notifications || m_useNotifySend)
#ifdef KNOTIFICATIONS
QWebEngineProfile::defaultProfile()->setNotificationPresenter(
[&](std::unique_ptr<QWebEngineNotification> notificationInfo) {
if (m_useNotifySend) {
auto title = notificationInfo->title();
auto message = notificationInfo->message();
auto image_path =
QString("/tmp/discord-screenaudio-%1.png").arg(title);
notificationInfo->icon().save(image_path);
QProcess::execute("notify-send",
{"--icon", image_path, "--app-name",
"discord-screenaudio", title, message});
} else if (m_useKF5Notifications) {
#ifdef KNOTIFICATIONS
KNotification *notification =
new KNotification("discordNotification");
KNotification *notification = new KNotification("discordNotification");
notification->setTitle(notificationInfo->title());
notification->setText(notificationInfo->message());
notification->setPixmap(
QPixmap::fromImage(notificationInfo->icon()));
notification->setPixmap(QPixmap::fromImage(notificationInfo->icon()));
notification->setDefaultAction("View");
connect(notification, &KNotification::defaultActivated,
[&, notificationInfo = std::move(notificationInfo)]() {
@@ -69,9 +54,8 @@ void MainWindow::setupWebView() {
activateWindow();
});
notification->sendEvent();
#endif
}
});
#endif
setCentralWidget(m_webView);
}

View File

@@ -14,7 +14,7 @@ class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(bool useNotifySend = false, QWidget *parent = nullptr);
explicit MainWindow(QWidget *parent = nullptr);
static MainWindow *instance();
private:
@@ -25,12 +25,6 @@ private:
void closeEvent(QCloseEvent *event) override;
bool m_wasMaximized;
static MainWindow *m_instance;
bool m_useNotifySend;
#ifdef KNOTIFICATIONS
bool m_useKF5Notifications = true;
#else
bool m_useKF5Notifications = false;
#endif
private Q_SLOTS:
void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest);

View File

@@ -12,77 +12,53 @@
StreamDialog::StreamDialog() : QWidget() {
setAttribute(Qt::WA_QuitOnClose, false);
{
auto layout = new QVBoxLayout(this);
layout->setSizeConstraint(QLayout::SetFixedSize);
m_videoGroupBox = new QGroupBox(this);
m_videoGroupBox->setTitle("Video");
m_videoGroupBox->setCheckable(true);
layout->addWidget(m_videoGroupBox);
{
auto videoLayout = new QVBoxLayout(this);
m_videoGroupBox->setLayout(videoLayout);
auto resolutionLabel = new QLabel(this);
resolutionLabel->setText("Resolution");
videoLayout->addWidget(resolutionLabel);
m_resolutionComboBox = new QComboBox(this);
m_resolutionComboBox->addItem("2160p", "3840x2160");
m_resolutionComboBox->addItem("1440p", "2560x1440");
m_resolutionComboBox->addItem("1080p", "1920x1080");
m_resolutionComboBox->addItem("720p", "1280x720");
m_resolutionComboBox->addItem("480p", "854x480");
m_resolutionComboBox->addItem("360p", "640x360");
m_resolutionComboBox->addItem("240p", "426x240");
m_resolutionComboBox->setCurrentText("720p");
videoLayout->addWidget(m_resolutionComboBox);
auto framerateLabel = new QLabel(this);
framerateLabel->setText("Framerate");
videoLayout->addWidget(framerateLabel);
m_framerateComboBox = new QComboBox(this);
m_framerateComboBox->addItem("144 FPS", 144);
m_framerateComboBox->addItem("60 FPS", 60);
m_framerateComboBox->addItem("30 FPS", 30);
m_framerateComboBox->addItem("15 FPS", 15);
m_framerateComboBox->addItem("5 FPS", 5);
m_framerateComboBox->setCurrentText("30 FPS");
videoLayout->addWidget(m_framerateComboBox);
}
m_audioGroupBox = new QGroupBox(this);
m_audioGroupBox->setCheckable(true);
m_audioGroupBox->setTitle("Audio");
layout->addWidget(m_audioGroupBox);
{
auto audioLayout = new QVBoxLayout(this);
m_audioGroupBox->setLayout(audioLayout);
auto targetLabel = new QLabel(this);
targetLabel->setText("Audio Source");
audioLayout->addWidget(targetLabel);
targetLabel->setText("Which app do you want to stream sound from?");
layout->addWidget(targetLabel);
{
auto targetLayout = new QHBoxLayout(this);
audioLayout->addLayout(targetLayout);
auto targetHBox = new QHBoxLayout(this);
layout->addLayout(targetHBox);
m_targetComboBox = new QComboBox(this);
updateTargets();
targetLayout->addWidget(m_targetComboBox);
targetHBox->addWidget(m_targetComboBox);
auto refreshTargetsButton = new QPushButton(this);
refreshTargetsButton->setFixedSize(30, 30);
refreshTargetsButton->setIcon(QIcon::fromTheme("view-refresh"));
connect(refreshTargetsButton, &QPushButton::clicked, this,
&StreamDialog::updateTargets);
targetLayout->addWidget(refreshTargetsButton);
}
}
targetHBox->addWidget(refreshTargetsButton);
auto qualityLabel = new QLabel(this);
qualityLabel->setText("Stream Quality");
layout->addWidget(qualityLabel);
auto qualityHBox = new QHBoxLayout(this);
layout->addLayout(qualityHBox);
m_qualityResolutionComboBox = new QComboBox(this);
m_qualityResolutionComboBox->addItem("2160p", "3840x2160");
m_qualityResolutionComboBox->addItem("1440p", "2560x1440");
m_qualityResolutionComboBox->addItem("1080p", "1920x1080");
m_qualityResolutionComboBox->addItem("720p", "1280x720");
m_qualityResolutionComboBox->addItem("480p", "854x480");
m_qualityResolutionComboBox->addItem("360p", "640x360");
m_qualityResolutionComboBox->addItem("240p", "426x240");
m_qualityResolutionComboBox->setCurrentText("720p");
qualityHBox->addWidget(m_qualityResolutionComboBox);
m_qualityFPSComboBox = new QComboBox(this);
m_qualityFPSComboBox->addItem("144 FPS", 144);
m_qualityFPSComboBox->addItem("60 FPS", 60);
m_qualityFPSComboBox->addItem("30 FPS", 30);
m_qualityFPSComboBox->addItem("15 FPS", 15);
m_qualityFPSComboBox->addItem("5 FPS", 5);
m_qualityFPSComboBox->setCurrentText("30 FPS");
qualityHBox->addWidget(m_qualityFPSComboBox);
auto button = new QPushButton(this);
button->setText("Start Stream");
@@ -90,18 +66,16 @@ StreamDialog::StreamDialog() : QWidget() {
layout->addWidget(button, Qt::AlignRight | Qt::AlignBottom);
setLayout(layout);
}
setWindowTitle("discord-screenaudio Stream Dialog");
}
void StreamDialog::startStream() {
auto resolution = m_resolutionComboBox->currentData().toString().split('x');
emit requestedStreamStart(m_videoGroupBox->isChecked(),
m_audioGroupBox->isChecked(),
auto resolution =
m_qualityResolutionComboBox->currentData().toString().split('x');
emit requestedStreamStart(m_targetComboBox->currentText(),
resolution[0].toUInt(), resolution[1].toUInt(),
m_framerateComboBox->currentData().toUInt(),
m_targetComboBox->currentText());
m_qualityFPSComboBox->currentData().toUInt());
setHidden(true);
}
@@ -109,6 +83,7 @@ void StreamDialog::updateTargets() {
auto lastTarget = m_targetComboBox->currentText();
m_targetComboBox->clear();
m_targetComboBox->addItem("[None]");
m_targetComboBox->addItem("[All Desktop Audio]");
for (auto target : Virtmic::getTargets()) {
m_targetComboBox->addItem(target);

View File

@@ -2,7 +2,6 @@
#include <QComboBox>
#include <QDialog>
#include <QGroupBox>
#include <QWidget>
class StreamDialog : public QWidget {
@@ -13,14 +12,12 @@ public:
private:
QComboBox *m_targetComboBox;
QComboBox *m_resolutionComboBox;
QComboBox *m_framerateComboBox;
QGroupBox *m_videoGroupBox;
QGroupBox *m_audioGroupBox;
QComboBox *m_qualityResolutionComboBox;
QComboBox *m_qualityFPSComboBox;
Q_SIGNALS:
void requestedStreamStart(bool video, bool audio, uint width, uint height,
uint frameRate, QString target);
void requestedStreamStart(QString target, uint width, uint height,
uint frameRate);
public Q_SLOTS:
void updateTargets();

1
submodules/Vencord Submodule

Submodule submodules/Vencord added at 0d996633f2