Compare commits
	
		
			18 Commits
		
	
	
		
			v1.0.0-rc.
			...
			v1.0.0-rc.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 6ef16b9625 | ||
|  | b62f1bab1f | ||
|  | 5f9211f98f | ||
|  | cfbb4152c3 | ||
|  | fa83e2d9a8 | ||
|  | 58ecbbc6f4 | ||
|  | 77300ed178 | ||
|  | 99df18ef89 | ||
|  | 6fc6140ce2 | ||
|  | 84c12a752e | ||
|  | 1199381803 | ||
|  | bce32e2ba1 | ||
|  | bc59458e19 | ||
|  | 6492cb9a35 | ||
|  | a814d9cc1b | ||
|  | dd107c6767 | ||
|  | 50be25d7db | ||
|  | fd894fb63e | 
							
								
								
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | [submodule "submodules/rohrkabel"] | ||||||
|  | 	path = submodules/rohrkabel | ||||||
|  | 	url = https://github.com/Soundux/rohrkabel | ||||||
| @@ -22,14 +22,26 @@ set(discord-screenaudio_SRC | |||||||
|   resources.qrc |   resources.qrc | ||||||
| ) | ) | ||||||
|  |  | ||||||
| include(FetchContent) | # Adapted from https://cliutils.gitlab.io/modern-cmake/chapters/projects/submodule.html | ||||||
|  | find_package(Git QUIET) | ||||||
|  | if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") | ||||||
|  |   option(GIT_SUBMODULE "Check submodules during build" ON) | ||||||
|  |   if(GIT_SUBMODULE) | ||||||
|  |     message(STATUS "Updating submodules") | ||||||
|  |     execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive --checkout | ||||||
|  |                     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|  |                     RESULT_VARIABLE GIT_SUBMOD_RESULT) | ||||||
|  |     if(NOT GIT_SUBMOD_RESULT EQUAL "0") | ||||||
|  |       message(FATAL_ERROR "`git submodule update --init --recursive --checkout` failed with ${GIT_SUBMOD_RESULT}, please provide the submodules manually") | ||||||
|  |     endif() | ||||||
|  |   endif() | ||||||
|  | endif() | ||||||
|  |  | ||||||
| FetchContent_Declare( | if(NOT EXISTS "${PROJECT_SOURCE_DIR}/submodules/rohrkabel/CMakeLists.txt") | ||||||
|   rohrkabel  |   message(FATAL_ERROR "Rohrkabel was not found since you are not in a Git checkout or have GIT_SUBMODULE disabled. Please provide rohrkabel manually to `./submodules/rohrkabel`.") | ||||||
|   GIT_REPOSITORY "https://github.com/Soundux/rohrkabel"  | endif() | ||||||
|   GIT_TAG "d87403f48d3a95aa4bcf4cd60112d9e4bb090d5d" |  | ||||||
| ) | add_subdirectory(submodules/rohrkabel) | ||||||
| FetchContent_MakeAvailable(rohrkabel) |  | ||||||
|  |  | ||||||
| add_executable(discord-screenaudio ${discord-screenaudio_SRC}) | add_executable(discord-screenaudio ${discord-screenaudio_SRC}) | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								README.md
									
									
									
									
									
								
							| @@ -9,6 +9,19 @@ of [@edisionnano](https://github.com/edisionnano) and the | |||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 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 | ||||||
|  | case you want to stream something, maybe used with a second account. For | ||||||
|  | anything else, this client has way too many things that work less well than in | ||||||
|  | the original client. | ||||||
|  |  | ||||||
|  | ## Known Issues | ||||||
|  |  | ||||||
|  | - Only works with **PipeWire** | ||||||
|  | - Only works on **X11** | ||||||
|  | - Can only share primary screen (no other screens or specific applications) (see | ||||||
|  |   [#1](https://github.com/maltejur/discord-screenaudio/issues/1)) | ||||||
|  |  | ||||||
| ## Installation | ## Installation | ||||||
|  |  | ||||||
| If you are using Arch, you can build and install | If you are using Arch, you can build and install | ||||||
| @@ -30,7 +43,14 @@ On Debian: | |||||||
|  |  | ||||||
| ### Building | ### Building | ||||||
|  |  | ||||||
| To build the program, run this in the source directory: | First, clone the repository: | ||||||
|  |  | ||||||
|  | ```bash | ||||||
|  | git clone https://github.com/maltejur/discord-screenaudio.git | ||||||
|  | cd discord-screenaudio | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | Then, to build the program, run this in the source directory: | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| cmake -B build | cmake -B build | ||||||
|   | |||||||
| @@ -117,7 +117,7 @@ setInterval(() => { | |||||||
|   ) { |   ) { | ||||||
|     for (const el of document.getElementsByClassName("info-3pQQBb")) { |     for (const el of document.getElementsByClassName("info-3pQQBb")) { | ||||||
|       const aboutEl = document.createElement("div"); |       const aboutEl = document.createElement("div"); | ||||||
|       aboutEl.innerText = "discord-screenaudio v1.0.0-rc.5"; |       aboutEl.innerText = "discord-screenaudio v1.0.0-rc.7"; | ||||||
|       aboutEl.style.fontSize = "12px"; |       aboutEl.style.fontSize = "12px"; | ||||||
|       aboutEl.style.color = "var(--text-muted)"; |       aboutEl.style.color = "var(--text-muted)"; | ||||||
|       aboutEl.classList.add("dirscordScreenaudioAboutText"); |       aboutEl.classList.add("dirscordScreenaudioAboutText"); | ||||||
| @@ -128,4 +128,8 @@ setInterval(() => { | |||||||
|   // Remove stream settings if stream is active |   // Remove stream settings if stream is active | ||||||
|   document.getElementById("manage-streams-change-windows")?.remove(); |   document.getElementById("manage-streams-change-windows")?.remove(); | ||||||
|   document.querySelector(`[aria-label="Stream Settings"]`)?.remove(); |   document.querySelector(`[aria-label="Stream Settings"]`)?.remove(); | ||||||
| }, 1000); | }, 500); | ||||||
|  |  | ||||||
|  | // Fix for broken discord notifications after restart | ||||||
|  | // (https://github.com/maltejur/discord-screenaudio/issues/17) | ||||||
|  | Notification.requestPermission(); | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ DiscordPage::DiscordPage(QWidget *parent) : QWebEnginePage(parent) { | |||||||
|   settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); |   settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); | ||||||
|   settings()->setAttribute(QWebEngineSettings::PlaybackRequiresUserGesture, |   settings()->setAttribute(QWebEngineSettings::PlaybackRequiresUserGesture, | ||||||
|                            false); |                            false); | ||||||
|  |   settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false); | ||||||
|  |  | ||||||
|   setUrl(QUrl("https://discord.com/app")); |   setUrl(QUrl("https://discord.com/app")); | ||||||
|  |  | ||||||
| @@ -63,6 +64,15 @@ void DiscordPage::featurePermissionRequested(const QUrl &securityOrigin, | |||||||
|   // Allow every permission asked |   // Allow every permission asked | ||||||
|   setFeaturePermission(securityOrigin, feature, |   setFeaturePermission(securityOrigin, feature, | ||||||
|                        QWebEnginePage::PermissionGrantedByUser); |                        QWebEnginePage::PermissionGrantedByUser); | ||||||
|  |  | ||||||
|  |   if (feature == QWebEnginePage::Feature::MediaAudioCapture) { | ||||||
|  |     if (m_virtmicProcess.state() == QProcess::NotRunning) { | ||||||
|  |       qDebug() << "[virtmic] Starting Virtmic with no target to make sure " | ||||||
|  |                   "Discord can find all the audio devices"; | ||||||
|  |       m_virtmicProcess.start(QApplication::arguments()[0], | ||||||
|  |                              {"--virtmic", "None"}); | ||||||
|  |     } | ||||||
|  |   } | ||||||
| } | } | ||||||
|  |  | ||||||
| bool DiscordPage::acceptNavigationRequest(const QUrl &url, | bool DiscordPage::acceptNavigationRequest(const QUrl &url, | ||||||
| @@ -76,10 +86,23 @@ bool DiscordPage::acceptNavigationRequest(const QUrl &url, | |||||||
|   return true; |   return true; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | bool ExternalPage::acceptNavigationRequest(const QUrl &url, | ||||||
|  |                                            QWebEnginePage::NavigationType type, | ||||||
|  |                                            bool isMainFrame) { | ||||||
|  |   QDesktopServices::openUrl(url); | ||||||
|  |   deleteLater(); | ||||||
|  |   return false; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | QWebEnginePage *DiscordPage::createWindow(QWebEnginePage::WebWindowType type) { | ||||||
|  |   return new ExternalPage; | ||||||
|  | } | ||||||
|  |  | ||||||
| void DiscordPage::stopVirtmic() { | void DiscordPage::stopVirtmic() { | ||||||
|   if (m_virtmicProcess.state() == QProcess::Running) { |   if (m_virtmicProcess.state() == QProcess::Running) { | ||||||
|     qDebug() << "[virtmic] Stopping Virtmic"; |     qDebug() << "[virtmic] Stopping Virtmic"; | ||||||
|     m_virtmicProcess.kill(); |     m_virtmicProcess.kill(); | ||||||
|  |     m_virtmicProcess.waitForFinished(); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,6 +4,7 @@ | |||||||
| #include "virtmic.h" | #include "virtmic.h" | ||||||
|  |  | ||||||
| #include <QProcess> | #include <QProcess> | ||||||
|  | #include <QWebEngineFullScreenRequest> | ||||||
| #include <QWebEnginePage> | #include <QWebEnginePage> | ||||||
|  |  | ||||||
| class DiscordPage : public QWebEnginePage { | class DiscordPage : public QWebEnginePage { | ||||||
| @@ -18,6 +19,7 @@ private: | |||||||
|   bool acceptNavigationRequest(const QUrl &url, |   bool acceptNavigationRequest(const QUrl &url, | ||||||
|                                QWebEnginePage::NavigationType type, |                                QWebEnginePage::NavigationType type, | ||||||
|                                bool isMainFrame) override; |                                bool isMainFrame) override; | ||||||
|  |   QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type) override; | ||||||
|   void |   void | ||||||
|   javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel level, |   javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel level, | ||||||
|                            const QString &message, int lineNumber, |                            const QString &message, int lineNumber, | ||||||
| @@ -31,3 +33,15 @@ private Q_SLOTS: | |||||||
|                                   QWebEnginePage::Feature feature); |                                   QWebEnginePage::Feature feature); | ||||||
|   void startStream(QString target, uint width, uint height, uint frameRate); |   void startStream(QString target, uint width, uint height, uint frameRate); | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | // Will immediately get destroyed again but is needed for navigation to | ||||||
|  | // target="_blank" links, since QWebEnginePage::newWindowRequested is | ||||||
|  | // only available sinec Qt 6.3. | ||||||
|  | class ExternalPage : public QWebEnginePage { | ||||||
|  |   Q_OBJECT | ||||||
|  |  | ||||||
|  | private: | ||||||
|  |   bool acceptNavigationRequest(const QUrl &url, | ||||||
|  |                                QWebEnginePage::NavigationType type, | ||||||
|  |                                bool isMainFrame) override; | ||||||
|  | }; | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ | |||||||
| int main(int argc, char *argv[]) { | int main(int argc, char *argv[]) { | ||||||
|   QApplication app(argc, argv); |   QApplication app(argc, argv); | ||||||
|   QApplication::setApplicationName("discord-screenaudio"); |   QApplication::setApplicationName("discord-screenaudio"); | ||||||
|   QApplication::setApplicationVersion("1.0.0-rc.5"); |   QApplication::setApplicationVersion("1.0.0-rc.7"); | ||||||
|  |  | ||||||
|   QCommandLineParser parser; |   QCommandLineParser parser; | ||||||
|   parser.setApplicationDescription( |   parser.setApplicationDescription( | ||||||
|   | |||||||
| @@ -23,8 +23,25 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { | |||||||
| } | } | ||||||
|  |  | ||||||
| void MainWindow::setupWebView() { | void MainWindow::setupWebView() { | ||||||
|   m_webView = new QWebEngineView(this); |  | ||||||
|   auto page = new DiscordPage(this); |   auto page = new DiscordPage(this); | ||||||
|  |   connect(page, &QWebEnginePage::fullScreenRequested, this, | ||||||
|  |           &MainWindow::fullScreenRequested); | ||||||
|  |  | ||||||
|  |   m_webView = new QWebEngineView(this); | ||||||
|   m_webView->setPage(page); |   m_webView->setPage(page); | ||||||
|  |  | ||||||
|   setCentralWidget(m_webView); |   setCentralWidget(m_webView); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void MainWindow::fullScreenRequested( | ||||||
|  |     QWebEngineFullScreenRequest fullScreenRequest) { | ||||||
|  |   fullScreenRequest.accept(); | ||||||
|  |   if (fullScreenRequest.toggleOn()) { | ||||||
|  |     m_wasMaximized = isMaximized(); | ||||||
|  |     showFullScreen(); | ||||||
|  |   } else { | ||||||
|  |     m_wasMaximized ? showMaximized() : showNormal(); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void MainWindow::closeEvent(QCloseEvent *event) { QApplication::quit(); } | ||||||
|   | |||||||
| @@ -21,4 +21,9 @@ private: | |||||||
|   QWebEngineView *m_webView; |   QWebEngineView *m_webView; | ||||||
|   QWebEngineProfile *prepareProfile(); |   QWebEngineProfile *prepareProfile(); | ||||||
|   DiscordPage *m_discordPage; |   DiscordPage *m_discordPage; | ||||||
|  |   void closeEvent(QCloseEvent *event) override; | ||||||
|  |   bool m_wasMaximized; | ||||||
|  |  | ||||||
|  | private Q_SLOTS: | ||||||
|  |   void fullScreenRequested(QWebEngineFullScreenRequest fullScreenRequest); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,5 +1,8 @@ | |||||||
| #include "virtmic.h" | #include "virtmic.h" | ||||||
|  |  | ||||||
|  | #include <rohrkabel/loop/main.hpp> | ||||||
|  | #include <rohrkabel/registry/registry.hpp> | ||||||
|  |  | ||||||
| namespace Virtmic { | namespace Virtmic { | ||||||
|  |  | ||||||
| QVector<QString> getTargets() { | QVector<QString> getTargets() { | ||||||
| @@ -24,7 +27,7 @@ QVector<QString> getTargets() { | |||||||
|           } |           } | ||||||
|         } |         } | ||||||
|       }); |       }); | ||||||
|   core.sync(); |   core.update(); | ||||||
|  |  | ||||||
|   return targets; |   return targets; | ||||||
| } | } | ||||||
| @@ -81,14 +84,21 @@ void start(QString _target) { | |||||||
|  |  | ||||||
|   std::string target = _target.toLatin1().toStdString(); |   std::string target = _target.toLatin1().toStdString(); | ||||||
|  |  | ||||||
|   auto virtual_mic = |   auto virtual_mic = core.create("adapter", | ||||||
|       core.create("adapter", |                                  {{"node.name", "discord-screenaudio-virtmic"}, | ||||||
|                   {{"node.name", "discord-screenaudio-virtmic"}, |                                   {"media.class", "Audio/Source/Virtual"}, | ||||||
|                    {"media.class", "Audio/Source/Virtual"}, |                                   {"factory.name", "support.null-audio-sink"}, | ||||||
|                    {"factory.name", "support.null-audio-sink"}, |                                   {"audio.channels", "2"}, | ||||||
|                    {"audio.channels", "2"}, |                                   {"audio.position", "FL,FR"}}, | ||||||
|                    {"audio.position", "FL,FR"}}, |                                  pipewire::node::type, pipewire::node::version, | ||||||
|                   pipewire::node::type, pipewire::node::version, false); |                                  pipewire::update_strategy::none); | ||||||
|  |  | ||||||
|  |   if (target == "None") { | ||||||
|  |     while (true) { | ||||||
|  |       main_loop.run(); | ||||||
|  |     } | ||||||
|  |     return; | ||||||
|  |   } | ||||||
|  |  | ||||||
|   auto reg_events = reg.listen<pipewire::registry_listener>(); |   auto reg_events = reg.listen<pipewire::registry_listener>(); | ||||||
|   reg_events.on<pipewire::registry_event::global>( |   reg_events.on<pipewire::registry_event::global>( | ||||||
|   | |||||||
| @@ -3,7 +3,6 @@ | |||||||
| #include <QString> | #include <QString> | ||||||
| #include <QVector> | #include <QVector> | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <rohrkabel/registry/registry.hpp> |  | ||||||
|  |  | ||||||
| namespace Virtmic { | namespace Virtmic { | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								submodules/rohrkabel
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								submodules/rohrkabel
									
									
									
									
									
										Submodule
									
								
							 Submodule submodules/rohrkabel added at 04bfb921c4
									
								
							
		Reference in New Issue
	
	Block a user