moonlight-web-stream

MrCreativ3001GPL-3.0活跃维护

把 Sunshine 游戏串流搬进浏览器,不用装客户端,打开网页就能远程玩 PC 游戏。

This is a web server which allows you to stream games with sunshine into a web browser.

v3.0.1发布于 2026-10-26 15:12 UTC747star +4 / 7 天116fork同步于 2026-11-10 23:54 UTC

怎么上手

由 README 提炼,执行前请确认
下载对应平台压缩包并解压后运行 ./web-server;如需配置文件先执行 ./web-server config generate
硬件要求按 README 说明

README 未说明具体硬件或显存要求;需先安装并运行 Sunshine 作为串流源,服务端为 Rust 编译的 web-server 可执行文件。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

把 Sunshine 串流通过 WebRTC 转发到浏览器,让 PC 游戏无需客户端即可在网页里玩

把 Sunshine 游戏串流搬进浏览器,不用装客户端,打开网页就能远程玩 PC 游戏。

核心能力

  • 用 WebRTC 将 Sunshine 串流转发到浏览器
  • 内置 STUN 并支持配置 TURN 中继
  • 支持 WebSocket 传输作为受限网络回退
  • 首个登录用户自动成为管理员
  • 可配置 HTTPS 证书与端口范围

容易踩的坑

首次启动不会自动生成 config.json,需手动执行 config generate;手柄、键盘锁定和 WebSocket 传输依赖 Secure Context(HTTPS);公网串流在严格 NAT 或防火墙下需自建 TURN 服务器或转发 UDP 端口

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v3.0.1
  1. v3.0.1最新正式版2026-10-26 · 2026-10-26 15:12 UTC
  2. v3.0.02026-10-22 · 2026-10-22 13:39 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/MrCreativ3001/moonlight-web-stream/compare/v2.10.0...v3.0.0

    See Migrating to v3 for upgrading to the new version.

  3. v3.0.0-prerelease.10pre-release2026-10-20 · 2026-10-20 09:16 UTC
    查看更新说明

    What's Changed

    New Contributors

    Full Changelog: https://github.com/MrCreativ3001/moonlight-web-stream/compare/v3.0.0-prerelease.9...v3.0.0-prerelease.10

  4. v3.0.0-prerelease.9pre-release2026-10-04 · 2026-10-04 08:12 UTC
    查看更新说明
  5. v3.0.0-prerelease.8pre-release2026-10-04 · 2026-10-04 07:44 UTC
    查看更新说明

    This release is broken

    What's Changed

    New Contributors

    Full Changelog: https://github.com/MrCreativ3001/moonlight-web-stream/compare/v3.0.0-prerelease.7...v3.0.0-prerelease.8

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Moonlight Web

    An unofficial Moonlight Client allowing you to stream your pc to the Web. It hosts a Web Server which will forward Sunshine traffic to a Browser using the WebRTC Api.

    An image displaying: PC with sunshine and moonlight web installed, a browser making requests to it

    Overview

    Limitations

    Installation

    You can install it manually or with docker

    Install Manually

    1. Install Sunshine

    2. Download the compressed archive for your platform and uncompress it or build it yourself

    3. Run the "web-server" executable

    4. Go to localhost:8080 and view the web interface. You can also the change bind address.

    NOTE A config.json file is not generated automatically on first startup. If you plan to follow the configuration guides below, you will need to create a config.json with ./web-server config generate

    Setup

    1. Add a new user by typing in your name and password. The first user to login will be created and will be the admin.

    2. Add a new pc () with the address as localhost and leave the port empty (if you've got the default port)

    3. Pair your pc by clicking on the host (). Then enter the code in sunshine

    4. Launch an app

    Streaming over the Internet

    1. Forward the web server port on your router (default is 8080; HTTP is 80, HTTPS is 443).
      You can configure this using the bind_address option.

    When running on a local network, WebRTC peers usually negotiate connections without any issues.

    When streaming over the Internet, the built-in STUN servers will attempt to establish a direct peer-to-peer WebRTC connection. This works for most home networks, but may fail in more restrictive environments (for example, corporate firewalls or strict NAT configurations).

    If a direct WebRTC connection cannot be established, you have a few options:

    1. Use a TURN server (recommended)
      Configure a TURN server to reliably relay WebRTC traffic when direct peer-to-peer connections are blocked.

    2. Forward ports directly
      You can forward the required ports on your router.
      Note that this may still fail if the firewall blocks UDP traffic.

    3. Use WebSocket transport as a fallback
      WebSockets use standard HTTP/HTTPS ports and are often allowed even in very restrictive networks, making them a good fallback option when WebRTC negotiation fails. See Using WebSocket Transport.

    Configure a turn server
    1. Host and configure a turn server like coturn or use other services to host one for you.

    2. Add your turn server to your WebRTC Ice Server list

    {
        "webrtc": {
            "ice_servers": [
                {
                    "urls": [
                        "stun:stun.l.google.com:19302",
                        "stun:stun1.l.google.com:3478",
                        "stun:stun.l.google.com:5349"
                    ]
                },
                {
                    "urls": [
                            "turn:yourip.com:3478?transport=udp",
                            "turn:yourip.com:3478?transport=tcp",
                            "turn:yourip.com:5349?transport=tcp"
                    ],
                    "username": "your username",
                    "credential": "your credential"
                }
            ]
        }
    }
    

    Some (business) firewalls might be very strict and only allow tcp on port 443 for turn connections if that's the case also bind the turn server on port 443 and add "turn:yourip.com:443?transport=tcp" to the url's list.

    Port forward
    1. Set the WebRTC Port Range to a fixed range
    {
        "webrtc": {
            "port_range": {
                "min": 40000,
                "max": 40010
            }
        }
    }
    
    1. Forward the port range specified in the previous step as udp. If you're using Windows Defender make sure to allow NAT Traversal. Important: If your firewall blocks udp connections this won't work and you need to host a turn server

    2. Configure WebRTC Nat 1 To 1 to advertise your public ip (Optional: WebRTC stun servers can usually automatically detect them):

    {
        "webrtc": {
            "nat_1to1": {
                "ice_candidate_type": "host",
                "ips": [
                    "74.125.224.72"
                ]
            }
        }
    }
    

    It might be helpful to look what kind of nat your pc is behind:

    Configuring https

    You can configure https directly with the Moonlight Web Server.

    1. You'll need a private key and a certificate.

    You can generate a self signed certificate with this python script generate_certificate.py:

    pip install pyOpenSSL
    python ./generate_certificate.py
    
    1. Copy the files server/key.pem and server/cert.pem into your server directory.

    2. Configure the private key and certificate https using the certificates

    {
        "web_server": {
            "certificate": {
                "private_key_pem": "./server/key.pem",
                "certificate_pem": "./server/cert.pem"
            }
        }
    }
    

    Proxying via Apache 2

    It's possible to proxy the Moonlight Website using Apache 2.

    Note: When you want to use https, the Moonlight Website should use http so that Apache 2 will handle all the https encryption.

    1. Enable the modules mod_proxy, mod_proxy_wstunnel
    sudo a2enmod mod_proxy mod_proxy_wstunnel
    
    1. Create a new file under /etc/apache2/conf-available/moonlight-web.conf with the content:
    # Example subpath "/moonlight" -> To connect you'd go to "http://yourip.com/moonlight/"
    Define MOONLIGHT_SUBPATH /moonlight
    # The address and port of your Moonlight Web server
    Define MOONLIGHT_STREAMER YOUR_LOCAL_IP:YOUR_PORT
    
    ProxyPreserveHost on
            
    # Important: This WebSocket will help negotiate the WebRTC Peers
    <Location ${MOONLIGHT_SUBPATH}/api/host/stream/web_socket>
            ProxyPass ws://${MOONLIGHT_STREAMER}${MOONLIGHT_SUBPATH}/api/host/stream/web_socket
            ProxyPassReverse ws://${MOONLIGHT_STREAMER}${MOONLIGHT_SUBPATH}/api/host/stream/web_socket
    </Location>
    
    ProxyPass ${MOONLIGHT_SUBPATH}/ http://${MOONLIGHT_STREAMER}${MOONLIGHT_SUBPATH}/
    ProxyPassReverse ${MOONLIGHT_SUBPATH}/ http://${MOONLIGHT_STREAMER}${MOONLIGHT_SUBPATH}/
    
    1. Enable the created config file
    sudo a2enconf moonlight-web
    
    1. Change config to include the prefixed path
    {
        "web_server": {
            "url_path_prefix": "/moonlight"
        }
    }
    
    1. Use https with a certificate (Optional)

    Authentication using a Reverse Proxy

    Authentication with a reverse proxy works by the proxy adding custom headers to the request of the user. In this example the username header is named X-Forwarded-User.

    Make sure that the header is not changeable by any external request and only the proxy can set this header.

    Enable proxy authentication by setting the forwarded header username option. By default the auto create missing user option is turned on even if it's not specified in the config.

    {
        "web_server": {
            "forwarded_header": {
                "username_header": "X-Forwarded-User",
                "auto_create_missing_user": true
            }
        }
    }
    

    If auto_create_missing_user is enabled, newly created users will be assigned the role configured as the default in the Admin Panel.

    Using WebSocket Transport

    In some networks (for example, corporate or highly restricted environments), establishing a WebRTC connection can be difficult or may not work at all. To support these cases, you can stream data over WebSockets using the same HTTP or HTTPS port that your server already exposes.

    You can force the Web Sockets by setting the Data Transport option to Web Sockets.

    There are a few important things to be aware of when using WebSockets for streaming:

    • The browser’s VideoDecoder API is only available when your site is served over HTTPS (a secure context).

    • If the application is not running in a secure context, it will fall back to an older video playback API, which may introduce noticeable latency.

    Config

    The config file is under server/config.json relative to the executable. Here are the most important settings for configuring Moonlight Web.

    Most options have command line arguments or environment variables associated with them.

    ./web-server help
    

    Generate the config with:

    ./web-server config generate
    

    For a full list of values look into the Rust Config module.

    Bind Address

    The address and port the website will run on

    Environment Variable: BIND_ADDRESS=0.0.0.0:8080

    {
        "web_server": {
            "bind_address": "0.0.0.0:8080"
        }
    }
    

    Default User

    The user id which is selected by default when providing no login. Go into the Admin Panel and look for the user id of the user you want to make the default.

    {
        "web_server": {
            "default_user_id": 1284358932
        }
    }
    

    Https Certificates

    If enabled the web server will use https with the provided certificate data

    Environment Variables:

    • SSL_PRIVATE_KEY=./server/key.pem
    • SSL_CERTIFICATE=./server/cert.pem
    {
        "web_server":{
            "certificate": {
                "private_key_pem": "./server/key.pem",
                "certificate_pem": "./server/cert.pem"
            }
        }
    }
    

    WebRTC Port Range

    This will set the port range on the web server used to communicate when using WebRTC

    Environment Variable: WEBRTC_PORT_RANGE=40000:40010

    {
        "webrtc": {
            "port_range": {
                "min": 40000,
                "max": 40010
            }
        }
    }
    

    WebRTC Ice Servers

    A list of ice servers for webrtc to use.

    {
        "webrtc": {
            "ice_servers": [
                {
                    "urls": [
                        "stun:stun.l.google.com:19302",
                        "stun:stun1.l.google.com:3478",
                        "stun:stun.l.google.com:5349"
                    ]
                }
            ]
        }
    }
    

    You can also set ice servers with environment variables:

    ENV WEBRTC_ICE_SERVER_0_URL=stun:stun.l.google.com:5349
    ENV WEBRTC_ICE_SERVER_0_USERNAME=name
    ENV WEBRTC_ICE_SERVER_0_CREDENTIAL=cred
    ENV WEBRTC_ICE_SERVER_1_URL=stun:stun1.l.google.com:5349
    

    will currespond to the ice server

    {
        "webrtc": {
            "ice_servers": [
                {
                    "urls": [
                        "stun:stun.l.google.com:19302",
                    ],
                    "username": "name",
                    "credential": "cred"
                },
                {
                    "urls": [
                        "stun:stun1.l.google.com:5349"
                    ]
                }
            ]
        }
    }
    

    You can disable all default ice servers with the cli argument --disable-default-webrtc-ice-servers or the environment variable DISABLE_DEFAULT_WEBRTC_ICE_SERVERS.

    WebRTC Ice Server Script

    The given script will be executed on every stream start to dynamically generate ice servers.

    {
        "webrtc": {
            "ice_server_script": "./server/ice_server_script.sh"
        }
    }
    

    The script must return a json list that follows the same structure as the WebRTC Ice Servers config option.

    Linux example using a bash script:

    #!/bin/bash
    
    # Assign arguments to variables
    username="user"
    credential="cred"
    
    # Output the json into stdout
    echo "[
        {
            \"urls\": [
                \"turn:example.com\"
            ],
            \"username\": \"$username\",
            \"credential\": \"$credential\"
        }
    ]"
    

    Windows example using a batch script:

    @echo off
    
    :: Assign arguments to variables
    set "username=user"
    set "credential=cred"
    
    :: Output the JSON with dynamic values
    echo [
    echo     {
    echo         "urls": [
    echo             "turn:example.com"
    echo         ],
    echo         "username": "%username%",
    echo         "credential": "%credential%"
    echo     }
    echo ]
    

    WebRTC Nat 1 to 1 ips

    This will advertise the ip as an ice candidate on the web server. It's recommended to set this but stun servers should figure out the public ip.

    ice_candidate_type:

    • host -> This is the ip address of the server and the client can connect to
    • srflx -> This is the public ip address of this server, like an ice candidate added from a stun server.
    {
        "webrtc": {
            "nat_1to1": {
                "ice_candidate_type": "host",
                "ips": [
                    "74.125.224.72"
                ]
            }
        }
    }
    

    You can also use the cli argument --webrtc-nat-1to1-host or environment variable WEBRTC_NAT_1TO1_HOST to use a ip as a host candidate type. This will do the same as the json above.

    ENV WEBRTC_NAT_1TO1_HOST=74.125.224.72
    

    Url Path Prefix

    This is useful when rerouting the web page using services like Apache 2. Will always append the prefix to all requests made by the website.

    Environment Variable: PATH_PREFIX=/moonlight

    {
        "web_server": {
            "url_path_prefix": "/moonlight"
        }
    }
    

    Forwarded Header Username

    The header that will give the authenticated username to this web server.

    {
        "web_server": {
            "forwarded_header": {
                "username_header": "X-Forwarded-User"
            }
        }
    }
    

    Forwarded Header Auto Create Missing User

    Automatically create a new user when the requested user specified in the username_header is not found.

    {
        "web_server": {
            "forwarded_header": {
                "auto_create_missing_user": true
            }
        }
    }
    

    Forwarded Header Ignore Case

    Perform a case-insensitive lookup for the user in the in the username_header. If multiple users match the given name, the request will fail.

    {
        "web_server": {
            "forwarded_header": {
                "ignore_case": true
            }
        }
    }
    

    Migrating to v2

    1. Some config options have changed so backup your old config by renaming it to something like old_config.json.

    2. Start the web server which will generate the new config.

    3. Move your configurations to the new config

    4. The first user to login will be created and will be an admin. All previously stored hosts will be moved to this user.

    Other changes:

    • Proxy path changed:
      • change all instances of ProxyPass ${MOONLIGHT_SUBPATH}/ http://${MOONLIGHT_STREAMER}/ to ProxyPass ${MOONLIGHT_SUBPATH}/ http://${MOONLIGHT_STREAMER}${MOONLIGHT_SUBPATH}/
      • Proxying via Apache 2

    Migrating to v3

    Changes:

    • replaced openssl by rustls
      • This makes older v1 and v2 server certificates incompatible
      • When using a self signed certificate, regenerate it using the updated generate_certificate.py
    • replaced moonlight-common-c by moonlight-common-rust
      • This could make older Nvidia GameStream and Sunshine Servers unsupported
    • moved web socket endpoint from /api/host/stream to /api/host/stream/web_socket
    • config.json is not generated at first startup and can optionally be used for more granular control
      • you can generate a config with ./web-server config generate, if required
    • moved default_user_id and default_role_id from the config.json into the data.json file
      • go into the admin panel and set the user or role you that you want to be the default to the default at the bottom of the page
    • removed old unused default_settings value in the config
    • removed webrtc.network_types setting in the config

    Contributors

    Thanks to everyone who contributed to make this software better :).

    Building

    Clone this repository:

    git clone https://github.com/MrCreativ3001/moonlight-web-stream.git
    

    A Rust installation is required.

    Moonlight Web consists the web server binary and a web frontend:

    Building the Web Server

    Run

    cargo build --release
    

    .

    You can use Cargo Cross for cross compilation:

    cross build --release --target YOUR_TARGET
    

    Note: windows only has the gnu target x86_64-pc-windows-gnu. macOS is built natively for aarch64-apple-darwin and x86_64-apple-darwin.

    Building the Frontend

    Build the web frontend with npm.

    To generate bindings to rust code it is using Uniffi Bindgen React Native. This has a dependency on wasm-bindgen.

    cargo install wasm-bindgen-cli
    npm install
    npm run build
    

    The build output will be in dist/.

    If you're compiling in:

    • debug mode -> the folder needs to be called dist/
    • release mode -> the folder needs to be called static/