Compare commits
	
		
			27 Commits
		
	
	
		
			v1.0.0-rc.
			...
			v1.0.0-rc.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 8fc529102c | ||
|  | a7a8346b63 | ||
|  | 88b129f863 | ||
|  | f4fc2e1f19 | ||
|  | e1b35e3ca8 | ||
|  | a773795e38 | ||
|  | c8695ca5ff | ||
|  | bc23d3423a | ||
|  | f5217dfdfa | ||
|  | 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,18 +22,32 @@ set(discord-screenaudio_SRC | ||||
|   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( | ||||
|   rohrkabel  | ||||
|   GIT_REPOSITORY "https://github.com/Soundux/rohrkabel"  | ||||
|   GIT_TAG "d87403f48d3a95aa4bcf4cd60112d9e4bb090d5d" | ||||
| ) | ||||
| FetchContent_MakeAvailable(rohrkabel) | ||||
| if(NOT EXISTS "${PROJECT_SOURCE_DIR}/submodules/rohrkabel/CMakeLists.txt") | ||||
|   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`.") | ||||
| endif() | ||||
|  | ||||
| add_subdirectory(submodules/rohrkabel) | ||||
|  | ||||
| add_executable(discord-screenaudio ${discord-screenaudio_SRC}) | ||||
|  | ||||
| target_link_libraries(discord-screenaudio Qt5::Widgets Qt5::WebEngineWidgets rohrkabel) | ||||
|  | ||||
| install(TARGETS discord-screenaudio DESTINATION bin) | ||||
| install(PROGRAMS assets/discord-screenaudio.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) | ||||
| install(PROGRAMS assets/de.shorsh.discord-screenaudio.png DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/256x256/apps) | ||||
| install(PROGRAMS assets/de.shorsh.discord-screenaudio.desktop DESTINATION ${CMAKE_INSTALL_PREFIX}/share/applications) | ||||
| install(PROGRAMS assets/de.shorsh.discord-screenaudio.metainfo.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/metainfo) | ||||
|   | ||||
							
								
								
									
										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 | ||||
|  | ||||
| If you are using Arch, you can build and install | ||||
| @@ -30,7 +43,14 @@ On Debian: | ||||
|  | ||||
| ### 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 | ||||
| cmake -B build | ||||
|   | ||||
| @@ -2,5 +2,5 @@ | ||||
| Type=Application | ||||
| Name=discord-screenaudio | ||||
| Exec=discord-screenaudio | ||||
| Icon=discord | ||||
| Icon=de.shorsh.discord-screenaudio | ||||
| Terminal=false | ||||
							
								
								
									
										38
									
								
								assets/de.shorsh.discord-screenaudio.metainfo.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								assets/de.shorsh.discord-screenaudio.metainfo.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <component type="desktop-application"> | ||||
|   <id>de.shorsh.discord-screenaudio</id> | ||||
|   <metadata_license>CC0-1.0</metadata_license> | ||||
|   <project_license>GPL-3.0+</project_license> | ||||
|   <name>discord-screenaudio</name> | ||||
|   <releases> | ||||
|     <release version="v1.0.0-rc.11" /> | ||||
|   </releases> | ||||
|  | ||||
|   <summary> | ||||
|     A very WIP custom discord client that supports streaming with audio on | ||||
|     Linux. | ||||
|   </summary> | ||||
|  | ||||
|   <description> | ||||
|     <p>A very WIP custom discord client that supports streaming with audio on Linux, made possible by the great work of @edisionnano and the Rohrkabel library by @Curve.</p> | ||||
|     <p>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.</p> | ||||
|   </description> | ||||
|  | ||||
|   <launchable type="desktop-id"> | ||||
|     discord-screenaudio.desktop | ||||
|   </launchable> | ||||
|  | ||||
|   <screenshots> | ||||
|     <screenshot type="default"> | ||||
|       <image> | ||||
|         https://user-images.githubusercontent.com/48161361/179571245-11ea05f3-fb5e-4aef-9132-2736e122ef04.png | ||||
|       </image> | ||||
|     </screenshot> | ||||
|   </screenshots> | ||||
|  | ||||
|   <url type="homepage">https://github.com/maltejur/discord-screenaudio</url> | ||||
|  | ||||
|   <provides> | ||||
|     <binary>discord-screenaudio</binary> | ||||
|   </provides> | ||||
| </component> | ||||
							
								
								
									
										
											BIN
										
									
								
								assets/de.shorsh.discord-screenaudio.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/de.shorsh.discord-screenaudio.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 48 KiB | 
| @@ -81,11 +81,16 @@ setInterval(() => { | ||||
|     }); | ||||
|     hiddenElements.length = 0; | ||||
|   } else { | ||||
|     for (const el of document.querySelectorAll( | ||||
|       '[aria-label="Share Your Screen"]' | ||||
|     )) { | ||||
|     for (const el of [ | ||||
|       document.getElementsByClassName("actionButtons-2vEOUh")?.[0]?.children[1], | ||||
|       document.querySelector( | ||||
|         ".wrapper-3t3Yqv > div > div > div > div > .controlButton-2PMNom" | ||||
|       ), | ||||
|     ]) { | ||||
|       if (!el) continue; | ||||
|       if (el.classList.contains("discord-screenaudio-cloned")) continue; | ||||
|       el.classList.add("discord-screenaudio-cloned"); | ||||
|       elClone = el.cloneNode(true); | ||||
|       elClone.ariaLabel = "Share Your Screen with Audio"; | ||||
|       elClone.title = "Share Your Screen with Audio"; | ||||
|       elClone.addEventListener("click", () => { | ||||
|         console.log("!discord-screenaudio-start-stream"); | ||||
| @@ -117,7 +122,7 @@ setInterval(() => { | ||||
|   ) { | ||||
|     for (const el of document.getElementsByClassName("info-3pQQBb")) { | ||||
|       const aboutEl = document.createElement("div"); | ||||
|       aboutEl.innerText = "discord-screenaudio v1.0.0-rc.5"; | ||||
|       aboutEl.innerText = "discord-screenaudio v1.0.0-rc.11"; | ||||
|       aboutEl.style.fontSize = "12px"; | ||||
|       aboutEl.style.color = "var(--text-muted)"; | ||||
|       aboutEl.classList.add("dirscordScreenaudioAboutText"); | ||||
| @@ -128,4 +133,8 @@ setInterval(() => { | ||||
|   // Remove stream settings if stream is active | ||||
|   document.getElementById("manage-streams-change-windows")?.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::PlaybackRequiresUserGesture, | ||||
|                            false); | ||||
|   settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, false); | ||||
|  | ||||
|   setUrl(QUrl("https://discord.com/app")); | ||||
|  | ||||
| @@ -63,6 +64,15 @@ void DiscordPage::featurePermissionRequested(const QUrl &securityOrigin, | ||||
|   // Allow every permission asked | ||||
|   setFeaturePermission(securityOrigin, feature, | ||||
|                        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, | ||||
| @@ -76,10 +86,23 @@ bool DiscordPage::acceptNavigationRequest(const QUrl &url, | ||||
|   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() { | ||||
|   if (m_virtmicProcess.state() == QProcess::Running) { | ||||
|     qDebug() << "[virtmic] Stopping Virtmic"; | ||||
|     m_virtmicProcess.kill(); | ||||
|     m_virtmicProcess.waitForFinished(); | ||||
|   } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
| #include "virtmic.h" | ||||
|  | ||||
| #include <QProcess> | ||||
| #include <QWebEngineFullScreenRequest> | ||||
| #include <QWebEnginePage> | ||||
|  | ||||
| class DiscordPage : public QWebEnginePage { | ||||
| @@ -18,6 +19,7 @@ private: | ||||
|   bool acceptNavigationRequest(const QUrl &url, | ||||
|                                QWebEnginePage::NavigationType type, | ||||
|                                bool isMainFrame) override; | ||||
|   QWebEnginePage *createWindow(QWebEnginePage::WebWindowType type) override; | ||||
|   void | ||||
|   javaScriptConsoleMessage(QWebEnginePage::JavaScriptConsoleMessageLevel level, | ||||
|                            const QString &message, int lineNumber, | ||||
| @@ -31,3 +33,15 @@ private Q_SLOTS: | ||||
|                                   QWebEnginePage::Feature feature); | ||||
|   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[]) { | ||||
|   QApplication app(argc, argv); | ||||
|   QApplication::setApplicationName("discord-screenaudio"); | ||||
|   QApplication::setApplicationVersion("1.0.0-rc.5"); | ||||
|   QApplication::setApplicationVersion("1.0.0-rc.11"); | ||||
|  | ||||
|   QCommandLineParser parser; | ||||
|   parser.setApplicationDescription( | ||||
|   | ||||
| @@ -23,8 +23,25 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { | ||||
| } | ||||
|  | ||||
| void MainWindow::setupWebView() { | ||||
|   m_webView = new QWebEngineView(this); | ||||
|   auto page = new DiscordPage(this); | ||||
|   connect(page, &QWebEnginePage::fullScreenRequested, this, | ||||
|           &MainWindow::fullScreenRequested); | ||||
|  | ||||
|   m_webView = new QWebEngineView(this); | ||||
|   m_webView->setPage(page); | ||||
|  | ||||
|   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; | ||||
|   QWebEngineProfile *prepareProfile(); | ||||
|   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 <rohrkabel/loop/main.hpp> | ||||
| #include <rohrkabel/registry/registry.hpp> | ||||
|  | ||||
| namespace Virtmic { | ||||
|  | ||||
| QVector<QString> getTargets() { | ||||
| @@ -24,7 +27,7 @@ QVector<QString> getTargets() { | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|   core.sync(); | ||||
|   core.update(); | ||||
|  | ||||
|   return targets; | ||||
| } | ||||
| @@ -81,14 +84,21 @@ void start(QString _target) { | ||||
|  | ||||
|   std::string target = _target.toLatin1().toStdString(); | ||||
|  | ||||
|   auto virtual_mic = | ||||
|       core.create("adapter", | ||||
|                   {{"node.name", "discord-screenaudio-virtmic"}, | ||||
|                    {"media.class", "Audio/Source/Virtual"}, | ||||
|                    {"factory.name", "support.null-audio-sink"}, | ||||
|                    {"audio.channels", "2"}, | ||||
|                    {"audio.position", "FL,FR"}}, | ||||
|                   pipewire::node::type, pipewire::node::version, false); | ||||
|   auto virtual_mic = core.create("adapter", | ||||
|                                  {{"node.name", "discord-screenaudio-virtmic"}, | ||||
|                                   {"media.class", "Audio/Source/Virtual"}, | ||||
|                                   {"factory.name", "support.null-audio-sink"}, | ||||
|                                   {"audio.channels", "2"}, | ||||
|                                   {"audio.position", "FL,FR"}}, | ||||
|                                  pipewire::node::type, pipewire::node::version, | ||||
|                                  pipewire::update_strategy::none); | ||||
|  | ||||
|   if (target == "None") { | ||||
|     while (true) { | ||||
|       main_loop.run(); | ||||
|     } | ||||
|     return; | ||||
|   } | ||||
|  | ||||
|   auto reg_events = reg.listen<pipewire::registry_listener>(); | ||||
|   reg_events.on<pipewire::registry_event::global>( | ||||
|   | ||||
| @@ -3,7 +3,6 @@ | ||||
| #include <QString> | ||||
| #include <QVector> | ||||
| #include <iostream> | ||||
| #include <rohrkabel/registry/registry.hpp> | ||||
|  | ||||
| namespace Virtmic { | ||||
|  | ||||
|   | ||||
							
								
								
									
										1
									
								
								submodules/rohrkabel
									
									
									
									
									
										Submodule
									
								
							
							
								
								
								
								
								
							
						
						
									
										1
									
								
								submodules/rohrkabel
									
									
									
									
									
										Submodule
									
								
							 Submodule submodules/rohrkabel added at 04bfb921c4
									
								
							
		Reference in New Issue
	
	Block a user