Moonshine is a streaming server which implements the protocol used by Moonlight. It is primarily intended for streaming games from the server to a client, while receiving input (mouse, keyboard, controller) from the client. This means you can play games on the client device, while rendering takes place on the server.
- NVIDIA GPU. Moonshine currently assumes an NVIDIA GPU for its encoding pipeline. Ideally in the future this pipeline is adjusted to use Vulkan Video Extensions so that more hardware can be supported. In theory it should be easy to adjust the pipeline for other hardware encoders, but this is not implemented at the time of writing.
- GStreamer. Moonshine uses GStreamer for encoding video streams. To reduce latency, a fix is required in GStreamer, which is available in this fork.
- Gamescope. Moonshine uses Gamescope in headless mode to run and stream content. This means that Moonshine is independent from whatever runs on the host system (X11, Wayland, etc). This also means you can run Moonshine and stream games, while using the host system for other tasks. Currently this requires a few fixes in Gamescope, which are available in this fork.
- (Arch) Linux. Although this software should theoretically run on any Linux distribution, it is only tested on Arch Linux. Windows is currently not supported.
- Moonlight v6.0.0 or higher. Older versions are untested and might not work.
The simplest method is to install through the AUR:
$ git clone https://aur.archlinux.org/moonshine
$ cd moonshine
$ makepkg -siOr, simply yay -S moonshine if yay is installed.
You can start the server by starting the user service:
$ systemctl --user start moonshineAlternatively, you can also compile directly from source. The following dependencies are required:
avahi
clang
cmake
gcc-libs
glib2
glibc
gstreamer
gst-plugins-base-libs
jq
libc++
libevdev
libpulse
openssl
opus
rust
On systems with pacman these can be installed with the following command:
$ sudo pacman -S \
avahi \
clang \
cmake \
gcc-libs \
glib2 \
glibc \
gstreamer \
gst-plugins-base-libs \
jq \
libc++ \
libevdev \
libpulse \
openssl \
opus \
rustThen compile and run:
$ cargo run --release -- /path/to/config.tomlA configuration file is generated if the provided path does not exist.
By default it will be created in $XDG_CONFIG_HOME/moonshine/config.toml if you are using the AUR package.
It is possible to add applications that you want to run (more on that below).
When a client attempts to pair through Moonlight, they are presented with a PIN number. A notification will appear on the host (assuming your desktop environment supports notifications) that you can use to automatically go to the page where your PIN number can be filled in. Alternatively you can navigate to the following URL on the host:
http://localhost:47989/pin
Or, you can also do this in commandline:
$ curl "http://localhost:47989/submit-pin?uniqueid=0123456789ABCDEF&pin=<PIN>"Where <PIN> should be replaced with the actual PIN number.
Each application defined in the configuration is executed within a gamescope session. This ensures that the application runs in a headless environment, independent of the host's desktop session.
In the config.toml file, each application has the following information:
title. The title as reported in Moonlight.boxart(optional). A path to the boxart (image) for this title.command. A list of strings representing the command to run. The first entry is the executable, the remaining entries are the arguments. This command is executed within agamescopesession.enable_steam_integration(optional). Whether to enable Steam integration for this application. Defaults tofalse.
Example:
[[application]]
title = "Steam"
command = ["/usr/bin/steam", "steam://open/bigpicture"]
enable_steam_integration = trueIn addition to defining specific applications, it is also possible to define application scanners.
These scanners scan for applications on startup.
Currently, only a steam scanner is implemented.
This scanner searches for a Steam library, checks which games are installed in that library and adds applications with the configured command.
The command has an additional template value that gets substituted when executed, the {game_id}.
This is replaced with the Steam game id.
The following application scanner will run the game through Steam:
[[application_scanner]]
type = "steam"
library = "$HOME/.local/share/Steam"
command = ["/usr/bin/steam", "-bigpicture", "steam://rungameid/{game_id}"]-
How does this compare to Sunshine? Both Moonshine and Sunshine fulfill the same goal. However, Moonshine has a much narrower focus on supported software and hardware, whereas Sunshine attempts to support many different combinations. Sunshine supports everything that Moonshine supports and much more.
-
So why should I use Moonshine? Realistically, you shouldn't. If you're interested in how these applications work from a technical perspective, then I can recommend looking into the code. Or if you think Sunshine has too many features and you want something simpler, give Moonshine a go ;).
This wouldn't have been possible without the incredible work by the people behind both Moonlight and Sunshine.
A special shoutout to @ABeltramo for implementing inputtino and helping with the controller input implementation!
Below are improvements intended for Moonshine. If you are interested in contributing, feel free to create an issue or send a message on the Moonlight Discord server.
- Investigate replacing input handling with inputtino for better support.
- Replace openssl with rustls.
- Investigate replacing ffmpeg with gstreamer as it seems to have better Rust support.
- Replace
xdg-desktop-portalwith some hardware agnostic frame capture (at the time of writing it seems this does not exist). - Replace NVENC with Vulkan Video Extensions.
- AV1 support.
- HDR support.
- 5.1 / 7.1 audio support.
- Gyro support for controllers that support it.
- Change controller ID based on what the client registers (this should correctly show Xbox buttons in some games when using Xbox controllers, for example).
- Web interface #4 .
- Reject clients based on provided certificate.