moonlight-stream / moonlight-qt

GameStream client for PCs (Windows, Mac, Linux, and Steam Link)
GNU General Public License v3.0
10.98k stars 640 forks source link

compile moonlight-qt to webassembly? #508

Closed m-bers closed 3 years ago

m-bers commented 3 years ago

Has anyone ever tried porting moonlight-qt over to wasm since the release of Qt 5.12/5.13? https://doc.qt.io/qt-5/wasm.html

There's some old issues in the moonlight-chrome repo that discuss this (here and here), but that was back in April of 2018 before the release of 5.12, when beta support for emscripten as a compilation target was introduced, and 5.13, when it became stable and fully supported.

I might have a go at this but if anyone more experienced has any tips or has tried this before let me know!

m-bers commented 3 years ago

ChaineJoueur542 on Discord responded with this:

This is currently impossible because Moonlight requires the use of native sockets, but WebAssembly only supports Web Sockets. There was talks to add native sockets to WA, but nothing that has shipped in any browser for now

Here's what I've dug up around this limitation:

From the Qt for WebAssembly wiki:

  • Network access: The web sandbox limits network access to a subset of what is available for native apps.
    • QNetworkAccessManager http requests to the web page origin server, or to a server which supports CORS.
    • QWebSocket connections to any host.
    • TCP and UDP socked tunneling using over WebSockets using a websockify server [3].
    • Websockify v0.8.0 can be used to tunnel TCP connections with QT5.12 but it is MANDATORY to specify the base64 or binary subprotocols before calling QWebSocket::open(). For example:
      QWebSocket socket;
      QUrl url{QString("ws://server:port")};
      QNetworkRequest request{url};
      request.setRawHeader("Sec-WebSocket-Protocol", "binary");
      socket.open(request);

Qt provides a list of network classes in which QNetworkAccessManager and QNetworkRequest are included, but I do not know if those are the ONLY classes compatible with emscripten as a compilation target.

moonlight-qt uses several of these network classes including at least :

The Qt wiki also refers to a couple other unsupported modules, including qtmultimedia, which moonlight-qt invokes by including the QAudioOutput class (but no other classes that I could tell).

The lack of QAudioOutput might end up being a bigger issue than the lack of direct support for POSIX & TCP/IP sockets if websockify can run on the GameStream host and wrap the exposed TCP/UDP ports that moonlight attaches to. I'm not aware of any fundamental limitations of wasm/emscripten that would preclude QAudioOutput from functioning, so we might just have to wait for an update from the Qt folks. There's some activity on that here.

To wrap up, my main questions around this potential feature are:

  1. Which network classes in moonlight-qt listed above are supported in Qt for WebAssembly--and how difficult would it be to retool for QWebSocket instead of QTcpSocket/QUdpSocket/etc?
  2. Are there any other libraries/modules/classes/functions that either won't compile or need to be significantly reworked for compatibility?
  3. Even if the code could be massaged into successfully compiling AND the websocket connection to websockify-wrapped gamestream ports on the host could be established, would the performance overhead be too great to be practical?

I am not the most skilled at Qt development but I am interested enough in this feature to invest time in trying to make this work, so long as it's not a complete non-starter.

cgutman commented 3 years ago

Moonlight doesn't use QAudioOutput. We use libsoundio and SDL for audio output. I think SDL does have an Emscripten backend, but I'm not sure how complete it is.

We need video decoding APIs that can accept unpackaged elementary stream data. I'm pretty sure most common browsers (Edge, Chrome) don't support HEVC, so we'd lose that feature too. You might be able to make it work with software decoding but performance won't be bood.

GeorgeDeac commented 3 years ago

For audio on emscripten there is also sokol, however it is very basic featurewise compared to SDL and I'm not sure how does it compare with the ported SDL backend.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

iamdroppy commented 3 years ago

Might be on the wrong track, but can't the ffmpeg.wasm be used to decode and on moonlight to encode to a rmtp stream?

Or am I on the wrong track?

meponderR commented 2 years ago

Now that DirectSockets has been Implemented as an experimental feature in Chrome, would this be possible?

devshgraphicsprogramming commented 2 years ago

everything is possible, its just a question of man-hours

Question is, is it wise to use the Qt version as a starting point for the WASM port, maybe Android, iOS or the old Chrome NaCL would be better starting blocks.

devshgraphicsprogramming commented 1 year ago

btw Samsung have been doing this for Tizen... https://developer.samsung.com/smarttv/develop/extension-libraries/webassembly/game-streaming-with-wasm.html

You need access to direct TCP/UDP sockets and HW accelerated video decode from within Emscripten.

axodox commented 3 months ago

Do not use WebSocket, it is based on TCP, instead use the data stream of WebRTC which is UDP based.