Skip to content

Instantly share code, notes, and snippets.

@MattDemers
Last active January 7, 2026 07:00
Show Gist options
  • Select an option

  • Save MattDemers/e73ad08255be2cf033b7562a02a778a9 to your computer and use it in GitHub Desktop.

Select an option

Save MattDemers/e73ad08255be2cf033b7562a02a778a9 to your computer and use it in GitHub Desktop.

Using Apollo for Multiple Monitors

This is a tutorial for using Apollo to stream different monitors to different Moonlight windows.

My usecase for this is streaming my multi-monitor desktop to a different multi-monitor setup within my home network. For outside networks, UPnP needs to be checked inside Network tab of the Configuration menu in the Apollo web UI. I would still recommend pairing with additional Apollo instances inside your home network for ease of use.

This tutorial assumes that you are installing Apollo to Windows.

Installing Apollo and Duplicating Files

Install Apollo as normal to Windows. Run Apollo at least once, as this will make sure some config files we need are generated. Note the path to the installation folder. For example, C:\Program Files\Apollo.

The main files we'll need to pay attention to are in the config folder. You'll need to pay attention to:

  • /config/sunshine.conf
  • /config/apollo.log
  • /config/apollo_state.json

You will need to duplicate each file and rename it appropriately for each separate video stream you want to have. For instance, I want to stream all three monitors I have, which means I will need to duplicate each file twice each, and rename them appropriately.

- /config/sunshine.conf
- /config/apollo.log
- /config/apollo_state.json
- /config/sunshine_2.conf
- /config/apollo2.log
- /config/apollo_state2.json
- /config/sunshine_3.conf
- /config/apollo3.log
- /config/apollo_state3.json

Modifying sunshine.conf

Open /config/sunshine.conf in a text editor. My basic sunshine.conf looks like this (this may not be the default):

sunshine_name = Apollo1
server_cmd = []
enable_pairing = enabled
port = 48999
log_path = apollo.log
file_state = apollo_state.json

In the other versions of sunshine.conf (for example, sunshine_2.conf), I've made the following changes.

sunshine_name = Apollo2
server_cmd = []
enable_pairing = enabled
port = 44999
log_path = apollo2.log
file_state = apollo_state2.json
virtual_sink = null
stream_audio = disabled

Change explanations:

  1. Change the sunshine_name to another name. This will be what shows up in Moonlight, so you'd likely like to differentiate that. In this case, I've just changed it to Apollo2.
  2. Change the port. For instance, my default port is 48999 in sunshine.conf for Apollo1; this will generate the web interface on 49000. You'll need to change the port to something else in order to generate a second web interface. I've changed my "Apollo2" port to 44999. If you were to make a third duplicate, you'd need to change it to something unique.
    • Keep in mind that Sunshine and Apollo use a range of ports for each configuration. Because of this, I will choose ports several hundred (or thousand) ports in number away from the original (44999, 43999, etc).
  3. Adding stream_audio to disabled means that Apollo2 won't generate sound. This keeps from doubling up your sound when you have both streams open. I also added virtual_sink = null as a backup, or alternative, so Apollo 2 won't have an audio device to capture.
  4. Changing log_path and file_state to the matching files we duplicated earlier. log_path is where an Apollo instance logs, and file_state is where things like paired PCs and other options are stored.

Running Your Additional Apollo Instances

For convenience' sake, I don't keep my second/third Apollo instances running at all times. I have created two shortcuts on my desktop that allow me to start them up.

  • In the Target field, I've put the following: "C:\Program Files\Apollo\sunshine.exe" "C:\Program Files\Apollo\config\sunshine_2.conf"
  • In the Start In field, I've put the following: "C:\Program Files\Apollo\"

Keep in mind this may be different for you depending on where Apollo is installed. The important thing is that the first path in the Target field point to your sunshine.exe, and the second points to your duplicated sunshine.conf.

When I double-click these shortcuts, it will open a console window; when I'm done using them, I can close the console window.

Apollo defaults to using a port "one-higher" than the one you put in your conf files. For sunshine_2.conf above, I decided to use 44999 as my port, which would create the web UI on 45000. I would access this by going to http://localhost:45000 (or your PC's local IP, followed by :45000).

When you visit this page, it'll treat the setup as a new instance of Apollo; you'll have to set up another admin password, and re-pair your devices. However, as long as the console window is running and there's no issues (like port conflicts, for example) you should now have two separate devices to access in Moonlight.

Using Your Additional Displays

Each Display will need its own Moonlight window.

In Windows, you can use Ctrl+Alt+Shift and F1 through F12 to change which Display is being shown in Moonlight.

When running multiple Moonlight displays, they may, upon connecting, default to fullscreening on your main monitor. You can use Ctrl+Alt+Shift+X to change Moonlight to Windowed mode, and then Ctrl+Alt+Shift+Z to stop controlling the mouse of the window.

Then, you can drag your additional Moonlight windows to another monitor (or arrange them how you'd like). If you're putting Moonlight 2 on Monitor 2, you can then use Ctrl+Alt+Shift+X again to fullscreen the window.

Automatically Assigning a Monitor to an Additional Apollo Instance

Virtual Displays

If you'd like your additional Apollo instance to always start a Virtual Display, check Headless Mode in the Audio/Video section of the Configuration screen. This can be found in the WebUI.

Physical Displays

If I want Apollo2 to always display a specific monitor on my Home PC, I can configure that.

In the Apollo web config, you can go to Configuration and then Audio/Video. There is a Display Device Id section.

Instructions from the section:

Manually specify a display device id to use for capture. If unset, the primary display is captured. Note: If you specified a GPU above, this display must be connected to that GPU. During Apollo startup, you should see the list of detected displays. Below is an example; the actual output can be found in the Troubleshooting tab.
  {
    "device_id": "{de9bb7e2-186e-505b-9e93-f48793333810}"
    "display_name": "\\\\.\\DISPLAY1"
    "friendly_name": "ROG PG279Q"
    ...
  }

You can go to Troubleshooting (at the top of the Web UI) and view the log.

In the log, near the top, there will be a line that says Info: Currently available display devices: your physical displays on your host PC will be listed below it.

Copy the device_id value (including the {}) and paste it into the Display Device Id field in the Audio/Video section. When you connect to this Apollo instance, you will automatically see the specified display.

Usage Examples

Scenario: Two Monitors to Two Monitors

As an example:

  • I have a PC with two monitors in my office. We'll call this the Main PC.
  • Elsewhere in my house, I have a treadmill with two monitors, using a Raspberry Pi or spare laptop to run Moonlight windows. We'll call this Secondary PC.

On the Main PC, I will run Apollo, and I will run my second Apollo configuration alongside it, using my Desktop shortcuts above.

On my Secondary PC, I will need to run two Moonlight windows. Both Apollo1 and Apollo2 have been paired and configured beforehand.

On my Secondary PC, I will run Moonlight Window 1, and start streaming from Apollo1. It defaults to fullscreening, so I will hit Ctrl+Alt+Shift+X to change to Windowed mode. I will then hit Ctrl+Alt+Shift+Z to take mouse control back.

I will then run Moonlight Window 2, and start streaming from Apollo2. Again, I will hit Ctrl+Alt+Shift+X to change to Windowed mode. I will then hit Ctrl+Alt+Shift+Z to take mouse control back.

I can then move Moonlight Window 2 to my second monitor on my Secondary PC, and then hit Ctrl+Alt+Shift+X to change to fullscreen mode, and Ctrl+Alt+Shift+Z to take mouse control back.

I then will go to Moonlight Window 1, fullscreen it, and use my system from there; in this case, Moonlight Window 2 is merely displaying what is being seen.

If my mouse does not travel between monitors as expected, I may need to use Ctrl+Alt+Shift+M to change the Mouse settings to enable my cursor to move between remote monitors.

Scenario: One Monitor to Two Monitors

If your Main PC only has one monitor and your Secondary PC has two, the setup is largely identical. However, when connecting to Apollo2 from Moonlight Window 2, you will need to select Virtual Display.

image

This will create a virtual display on your Main PC. You will need to open your Display Settings to arrange your physical monitor + virtual monitor on your Main PC to reflect the layout of your Secondary PC.

Main PC:
[Monitor 1][Virtual Monitor Running Apollo 2]

Secondary PC:
[Monitor 1][Monitor 2]

Arranging them properly will allow you to have your cursor move between monitors as expected.

Scenario: Spare Devices That Can Run Moonlight (iPad as Windows Extra Monitor/Windows Sidecar)

iPads can be used as separate monitors with MacOS with Sidecar, but it is significantly more difficult to do in Windows.

With the Virtual Display option above, you can turn devices that can run Moonlight into additional displays.

Since you are controlling the mouse and keyboard of your Main PC through Moonlight Window 1, every other Moonlight Window is just "displaying" what's on the monitor.

Example:

  • My main PC has two monitors
  • My remote PC has two monitors
  • I would like to create an additional virtual display
  • I have a spare iPad or device that can run Moonlight (a smartphone, or Raspberry Pi or Steam Link connected to a display, etc)

To use my iPad as a spare monitor, I would use it to connect to Apollo3 (if I created it), using a Virtual Display. The iPad would sit on my desk and just "display" what was running on the Virtual Display. It does not need to interact with it at all.

This means that each additional Virtual Display will also need its own Apollo configuration (sunshine_2.conf, sunshine_3.conf, sunshine_4.conf, etc and their associated log and state files, as outlined above).

As long as the Virtual Displays are arranged properly in Windows to reflect the physical layout in real life, you can add additional monitors as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment