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.
The simplest method is to install through the AUR:
$ git clone https://aur.archlinux.org/moonshine-bin
$ cd moonshine
$ makepkg -si
Or, simply yay -S moonshine-bin
if yay
is installed.
You can start the server by starting the user service:
$ systemctl --user start moonshine
Alternatively, you can also compile directly from source. The following dependencies are required:
avahi
cuda
ffmpeg
gcc-libs
glibc
libpulse
nvidia-utils
openssl
opus
On systems with pacman
these can be installed with the following command:
$ sudo pacman -S \
avahi \
cuda \
ffmpeg \
gcc-libs \
glibc \
libpulse \
nvidia-utils \
openssl \
opus
Then compile and run:
$ cargo run --release -- /path/to/config.toml
A 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).
There is also a resolution script provided which automatically changes the resolution to the requested resolution. Note that this file should be modified to refer to the correct display and standard resolution.
The default configuration assumes this resolution
script is placed in $HOME/.local/bin
.
If you want to use this functionality, you should copy this script in that location:
$ mkdir ~/.local/bin
$ curl -Lo ~/.local/bin/resolution https://github.com/hgaiser/moonshine/raw/main/scripts/resolution
And modify the values to match your setup.
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.
It is important to note that each application that is defined in the config simply starts streaming the entire desktop.
It is the run_before
part of an applications configuration that defines what to do when an application is started.
Most commonly this will be used to first change the resolution and then launch a game or application.
If no run_before
is provided, then Moonshine will simply start to stream the desktop without changing resolution or launching anything.
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.
run_before
(optional). A list of commands to execute before starting the stream for this application. Each command is itself a list. The first entry in the list is the executable to run, the remaining entries are the arguments. For example this will simply print "Hello World"
:
[[application]]
title = "Test"
run_before = [["/usr/bin/echo", "Hello", "World"]]
run_after
(optional). Similar to run_before
, but these commands are run after a stream has ended.
The following values are replaced in the commands, before they are executed:
{width}
is replaced with the requested stream width in pixels.{height}
is replaced with the requested stream height in pixels.$HOME
.By combining the run_before
and run_after
configuration fields, we can change resolution and launch a game when the application starts and reset to the default resolution when the application ends.
A simple example is given below:
[[application]]
title = "Steam"
run_before = [
["$HOME/.local/bin/resolution", "{width}", "{height}"],
["/usr/bin/steam", "steam://open/bigpicture"],
]
run_after = [["$HOME/.local/bin/resolution"]]
This will first call the scripts/resolution
script in $HOME/.local/bin/resolution
with the requested width and height as arguments.
This will cause the resolution to be changed to the resolution requested by the client.
The next command will open Steam in big picture mode.
When the stream has ended, the resolution is returned to the standard resolution by calling the resolution
script without any arguments.
In 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 run_before
and run_after
commands.
These commands have 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 first change resolution, then open steam, then run a game. After running the application, the resolution is restored to its default value.
[[application_scanner]]
type = "steam"
library = "$HOME/.local/share/Steam"
run_before = [
["$HOME/.local/bin/resolution", "{width}", "{height}"],
["/usr/bin/steam", "steam://open/bigpicture"],
["/usr/bin/steam", "steam://rungameid/{game_id}"],
]
run_after = [
["$HOME/.local/bin/resolution"],
]
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.
Below are improvements intended for Moonshine. If you are interesting in contributing, feel free to create an issue or send a message on the Moonlight Discord server.