diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 64fadc7a52..c96ec16de2 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,5 +1,8 @@ blank_issues_enabled: false contact_links: + - name: AUR Package Issue + url: https://aur.archlinux.org/packages/sunshine + about: AUR Package Issues should be discussed on the AUR - name: Github Discussions url: https://github.com/SunshineStream/Sunshine/discussions about: General discussion, support, feature requests and more! diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 60b8543201..32fce3f3d8 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,3 +6,10 @@ updates: interval: "daily" target-branch: "nightly" open-pull-requests-limit: 20 + + - package-ecosystem: "pip" + directory: "/scripts" + schedule: + interval: "daily" + target-branch: "nightly" + open-pull-requests-limit: 10 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index e3bcbfdce1..6c3bab87f2 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,26 +1,22 @@ ## Description - -Please include a summary of the changes. + ### Screenshot - -Include screenshots if the changes are UI-related. + ### Issues Fixed or Closed - + - Fixes #(issue) ## Type of Change - -Please delete options that are not relevant. - + - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) ## Checklist - + - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas -- [ ] I have added or updated the documentation blocks for new or existing components +- [ ] I have added or updated the docstring/documentation-blocks for new or existing methods/components diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 82bbc3438f..18d7e89cc1 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -3,7 +3,7 @@ name: CI on: pull_request: branches: [master, nightly] - types: [opened, synchronize, edited, reopened] + types: [opened, synchronize, reopened] push: branches: [master] workflow_dispatch: @@ -13,21 +13,21 @@ jobs: name: Check Changelog runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Verify Changelog - id: verify_changelog - if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }} - # base_ref for pull request check, ref for push - uses: SunshineStream/actions/verify_changelog@master - with: - token: ${{ secrets.GITHUB_TOKEN }} + - name: Checkout + uses: actions/checkout@v3 + + - name: Verify Changelog + id: verify_changelog + if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }} + # base_ref for pull request check, ref for push + uses: SunshineStream/actions/verify_changelog@master + with: + token: ${{ secrets.GITHUB_TOKEN }} outputs: next_version: ${{ steps.verify_changelog.outputs.changelog_parser_version }} next_version_bare: ${{ steps.verify_changelog.outputs.changelog_parser_version_bare }} last_version: ${{ steps.verify_changelog.outputs.latest_release_tag_name }} - release_body: ${{ steps.verify_changelog.outputs.changelog_parser_description }} + release_body: ${{ steps.verify_changelog.outputs.changelog_parser_description }} check_versions: name: Check Versions @@ -36,157 +36,207 @@ jobs: if: ${{ github.ref == 'refs/heads/master' || github.base_ref == 'master' }} # base_ref for pull request check, ref for push steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Check CMakeLists.txt Version - run: | - version=$(grep -o -E '^project\(Sunshine VERSION [0-9]+\.[0-9]+\.[0-9]+\)' CMakeLists.txt | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+') - echo "cmakelists_version=${version}" >> $GITHUB_ENV - - name: Compare CMakeList.txt Version - if: ${{ env.cmakelists_version != needs.check_changelog.outputs.next_version_bare }} - run: | - echo CMakeLists version: "$cmakelists_version" - echo Changelog version: "${{ needs.check_changelog.outputs.next_version_bare }}" - echo Within 'CMakeLists.txt' change "project(Sunshine VERSION $cmakelists_version)" to "project(Sunshine VERSION ${{ needs.check_changelog.outputs.next_version_bare }})" - exit 1 - - build_appimage: - name: AppImage - runs-on: ubuntu-20.04 - needs: check_changelog + - name: Checkout + uses: actions/checkout@v3 - steps: - - name: Checkout - uses: actions/checkout@v2 - with: - submodules: recursive - - - name: Setup Dependencies AppImage - run: | - mkdir -p artifacts - - sudo apt-get update -y && \ - sudo apt-get --reinstall install -y \ - git wget gcc-10 g++-10 build-essential cmake libssl-dev libavdevice-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libpulse-dev libopus-dev libxtst-dev libx11-dev libxrandr-dev libxfixes-dev libevdev-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev libdrm-dev libcap-dev libwayland-dev - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 - sudo wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O /root/cuda.run && sudo chmod a+x /root/cuda.run - sudo /root/cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && sudo rm /root/cuda.run - sudo add-apt-repository ppa:savoury1/graphics -y - sudo add-apt-repository ppa:savoury1/multimedia -y - sudo add-apt-repository ppa:savoury1/ffmpeg4 -y - sudo apt-get update -y - sudo apt-get upgrade -y && sudo apt-get dist-upgrade -y - sudo apt-get install ffmpeg -y - - name: Build AppImage - run: | - CMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE:-Release}" - SUNSHINE_EXECUTABLE_PATH="${SUNSHINE_EXECUTABLE_PATH:-/usr/bin/sunshine}" - SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR:-sunshine.AppImage.config}" - - SUNSHINE_ENABLE_WAYLAND=${SUNSHINE_ENABLE_WAYLAND:-ON} - SUNSHINE_ENABLE_X11=${SUNSHINE_ENABLE_X11:-ON} - SUNSHINE_ENABLE_DRM=${SUNSHINE_ENABLE_DRM:-ON} - SUNSHINE_ENABLE_CUDA=${SUNSHINE_ENABLE_CUDA:-ON} - - mkdir -p appimage-build && cd appimage-build - - cmake "-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE" "-DSUNSHINE_EXECUTABLE_PATH=$SUNSHINE_EXECUTABLE_PATH" "-DSUNSHINE_ASSETS_DIR=$SUNSHINE_ASSETS_DIR" "-DSUNSHINE_ENABLE_WAYLAND=$SUNSHINE_ENABLE_WAYLAND" "-DSUNSHINE_ENABLE_X11=$SUNSHINE_ENABLE_X11" "-DSUNSHINE_ENABLE_DRM=$SUNSHINE_ENABLE_DRM" "-DSUNSHINE_ENABLE_CUDA=$SUNSHINE_ENABLE_CUDA" "../" -DCMAKE_INSTALL_PREFIX=/usr - - make -j ${nproc} DESTDIR=AppDir - - name: Set AppImage Version - if: ${{ needs.check_changelog.outputs.next_version_bare != needs.check_changelog.outputs.latest_version }} - run: | - version=${{ needs.check_changelog.outputs.next_version_bare }} - echo "VERSION=${version}" >> $GITHUB_ENV - - name: Package AppImage - # https://docs.appimage.org/packaging-guide/index.html - run: | - mkdir -p appimage_temp && cd appimage_temp - - DESKTOP_FILE="${DESKTOP_FILE:-sunshine.desktop}" - ICON_FILE="${ICON_FILE:-sunshine.png}" - CONFIG_DIR="${CONFIG_DIR:-sunshine/sunshine.AppImage.config/}" - HOME_DIR="${HOME_DIR:-sunshine/sunshine.AppImage.home/}" - - wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage && chmod +x linuxdeploy-x86_64.AppImage - - ./linuxdeploy-x86_64.AppImage --appdir ../AppDir -e ../appimage-build/sunshine -i "../$ICON_FILE" -d "../appimage-build/$DESKTOP_FILE" --output appimage - - mv sunshine*.AppImage sunshine.AppImage - mkdir sunshine && mv sunshine.AppImage sunshine/ - ./sunshine/sunshine.AppImage --appimage-portable-config - ./sunshine/sunshine.AppImage --appimage-portable-home - cp -r ../assets/* "$CONFIG_DIR" - rm -f "$CONFIG_DIR"/apps_windows.json - mkdir -p ./"$HOME_DIR"/.config/"$CONFIG_DIR" - cp ./"$CONFIG_DIR"/apps_linux.json ./"$HOME_DIR"/.config/"$CONFIG_DIR" - zip -r ./sunshine_linux.zip ./sunshine/* - - mv sunshine_linux.zip ../artifacts/ - - name: Verify AppImage - run: | - cd appimage_temp - wget https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-x86_64.AppImage && chmod +x appimagelint-x86_64.AppImage && ./appimagelint-x86_64.AppImage ./sunshine/sunshine.AppImage - - name: Upload Artifacts - if: ${{ github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' }} - uses: actions/upload-artifact@v2 - with: - name: sunshine-AppImage - path: artifacts/ - - name: Create Release - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} - uses: SunshineStream/actions/create_release@master - with: - token: ${{ secrets.GITHUB_TOKEN }} - next_version: ${{ needs.check_changelog.outputs.next_version }} - last_version: ${{ needs.check_changelog.outputs.last_version }} - release_body: ${{ needs.check_changelog.outputs.release_body }} + - name: Check CMakeLists.txt Version + run: | + version=$(grep -o -E '^project\(Sunshine VERSION [0-9]+\.[0-9]+\.[0-9]+' CMakeLists.txt | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+') + echo "cmakelists_version=${version}" >> $GITHUB_ENV + + - name: Compare CMakeList.txt Version + if: ${{ env.cmakelists_version != needs.check_changelog.outputs.next_version_bare }} + run: | + echo CMakeLists version: "$cmakelists_version" + echo Changelog version: "${{ needs.check_changelog.outputs.next_version_bare }}" + echo Within 'CMakeLists.txt' change "project(Sunshine [VERSION $cmakelists_version]" to "project(Sunshine [VERSION ${{ needs.check_changelog.outputs.next_version_bare }}]" + exit 1 build_linux: name: Linux runs-on: ubuntu-20.04 needs: check_changelog strategy: - fail-fast: true # false to test all, true to fail entire job if any fail + fail-fast: false # false to test all, true to fail entire job if any fail matrix: - distro: [ debian, ubuntu_20_04, ubuntu_21_04, ubuntu_21_10 ] # removed ubuntu_18_04 for now - package: [ -p ] - include: # don't package these - - distro: fedora_33 - package: '' - - distro: fedora_35 - package: '' + include: # package these differently + - type: cpack + CMAKE_INSTALL_PREFIX: '' + SUNSHINE_ASSETS_DIR: '/usr/local/sunshine/assets' + SUNSHINE_CONFIG_DIR: '/usr/local/sunshine/config' + - type: appimage + CMAKE_INSTALL_PREFIX: '/usr' + SUNSHINE_ASSETS_DIR: 'sunshine.AppImage.config' + SUNSHINE_CONFIG_DIR: 'sunshine.AppImage.home' steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive + - name: Setup Dependencies Linux + run: | + sudo add-apt-repository ppa:savoury1/ffmpeg4 -y + # sudo add-apt-repository ppa:savoury1/boost-defaults-1.71 -y + sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y + + sudo apt-get update -y + sudo apt-get install -y \ + build-essential \ + cmake \ + gcc-10 \ + git \ + g++-10 \ + libavdevice-dev \ + libboost-filesystem-dev \ + libboost-log-dev \ + libboost-thread-dev \ + libcap-dev \ + libdrm-dev \ + libevdev-dev \ + libpulse-dev \ + libopus-dev \ + libssl-dev \ + libwayland-dev \ + libx11-dev \ + libxcb-shm0-dev \ + libxcb-xfixes0-dev \ + libxcb1-dev \ + libxfixes-dev \ + libxrandr-dev \ + libxtst-dev \ + wget + # # Ubuntu 20.04+ packages + # libboost-filesystem-dev + # libboost-log-dev + # libboost-thread-dev + + # # Ubuntu 18.04 packages + # libboost-filesystem1.71-dev \ + # libboost-log1.71-dev \ + # libboost-regex1.71-dev \ + # libboost-thread1.71-dev \ + + # clean apt cache + sudo apt-get clean + sudo rm -rf /var/lib/apt/lists/* + + # Update gcc alias + sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 + + # Install CuDA + sudo wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O /root/cuda.run + sudo chmod a+x /root/cuda.run + sudo /root/cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm + sudo rm /root/cuda.run + + # # Install cmake (necessary for 18.04) + # wget https://cmake.org/files/v3.22/cmake-3.22.2-linux-x86_64.sh + # chmod +x cmake-3.22.2-linux-x86_64.sh + # mkdir /opt/cmake + # ./cmake-3.22.2-linux-x86_64.sh --prefix=/opt/cmake --skip-license + # ln --force --symbolic /opt/cmake/bin/cmake /usr/local/bin/cmake + # cmake --version - - name: Setup Container + - name: Build Linux run: | + mkdir -p build mkdir -p artifacts + + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${{ matrix.CMAKE_INSTALL_PREFIX }} -DSUNSHINE_ASSETS_DIR=${{ matrix.SUNSHINE_ASSETS_DIR }} -DSUNSHINE_CONFIG_DIR=${{ matrix.SUNSHINE_CONFIG_DIR }} -DSUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine -DSUNSHINE_ENABLE_WAYLAND=ON -DSUNSHINE_ENABLE_X11=ON -DSUNSHINE_ENABLE_DRM=ON -DSUNSHINE_ENABLE_CUDA=ON .. + make -j ${nproc} - cd scripts - sudo ./build-container.sh -c build -f Dockerfile-${{ matrix.distro }} -n sunshine-${{ matrix.distro }} - - name: Build Linux + - name: Package Linux - CPACK + if: ${{ matrix.type == 'cpack' }} + working-directory: build + run: | + # package + cpack -G DEB + cpack -G RPM + + # move + mv ./cpack_artifacts/Sunshine.deb ../artifacts/sunshine.deb + mv ./cpack_artifacts/Sunshine.rpm ../artifacts/sunshine.rpm + + - name: Set AppImage Version + if: ${{ matrix.type == 'appimage' && ( needs.check_changelog.outputs.next_version_bare != needs.check_changelog.outputs.latest_version ) }} + run: | + version=${{ needs.check_changelog.outputs.next_version_bare }} + echo "VERSION=${version}" >> $GITHUB_ENV + + - name: Package Linux - AppImage + if: ${{ matrix.type == 'appimage' }} + working-directory: build run: | - cd scripts - sudo ./build-sunshine.sh ${{ matrix.package }} -u -n sunshine-${{ matrix.distro }} -s .. - - name: Package Linux - if: ${{ matrix.package == '-p' }} + # install sunshine to the DESTDIR + make install DESTDIR=AppDir + + # portable home and config + # todo - this is ugly... we should use a custom AppRun script to take care of this + mv ./AppDir${{ matrix.CMAKE_INSTALL_PREFIX }}/sunshine.AppImage.* ../artifacts/ + mkdir -p ../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/.config/sunshine/${{ matrix.SUNSHINE_CONFIG_DIR }} + cp ../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/apps.json ../artifacts/${{ matrix.SUNSHINE_CONFIG_DIR }}/.config/sunshine/${{ matrix.SUNSHINE_CONFIG_DIR }}/ + + # variables + DESKTOP_FILE="${DESKTOP_FILE:-sunshine.desktop}" + ICON_FILE="${ICON_FILE:-sunshine.png}" + + # AppImage + # https://docs.appimage.org/packaging-guide/index.html + wget https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage + chmod +x linuxdeploy-x86_64.AppImage + + # # https://github.com/linuxdeploy/linuxdeploy-plugin-gtk + # sudo apt-get install libgtk-3-dev librsvg2-dev -y + # wget https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh + # chmod +x linuxdeploy-plugin-gtk.sh + # export DEPLOY_GTK_VERSION=3 + + ./linuxdeploy-x86_64.AppImage \ + --appdir ./AppDir \ + --executable ./sunshine \ + --icon-file "../$ICON_FILE" \ + --desktop-file "./$DESKTOP_FILE" \ + --library /usr/lib/x86_64-linux-gnu/libpango-1.0.so.0 \ + --library /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 \ + --library /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.so.0 \ + --output appimage + # # add this argument back if using gtk plugin + # --plugin gtk \ + + # move + mv Sunshine*.AppImage ../artifacts/sunshine.AppImage + + # permissions + chmod +x ../artifacts/sunshine.AppImage + + - name: Verify AppImage + if: ${{ matrix.type == 'appimage' }} run: | - cd scripts - sudo mv ./sunshine-${{ matrix.distro }}-build/sunshine-${{ matrix.distro }}.deb ../artifacts/ + wget https://github.com/TheAssassin/appimagelint/releases/download/continuous/appimagelint-x86_64.AppImage + chmod +x appimagelint-x86_64.AppImage + + # rm -rf ~/.cache/appimagelint/ + + ./appimagelint-x86_64.AppImage ./artifacts/sunshine.AppImage + + - name: Archive AppImage + if: ${{ matrix.type == 'appimage' }} + working-directory: artifacts + run: | + chmod +x ./sunshine.AppImage + + zip --recurse-paths --move --test ./sunshine-appimage.zip ./* + - name: Upload Artifacts - if: ${{ matrix.package == '-p' && ( github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' ) }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: - name: sunshine-${{ matrix.distro }} + name: sunshine-linux-${{ matrix.type }} path: artifacts/ + - name: Create Release - if: ${{ matrix.package == '-p' && github.event_name == 'push' && github.ref == 'refs/heads/master' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} uses: SunshineStream/actions/create_release@master with: token: ${{ secrets.GITHUB_TOKEN }} @@ -194,6 +244,200 @@ jobs: last_version: ${{ needs.check_changelog.outputs.last_version }} release_body: ${{ needs.check_changelog.outputs.release_body }} + build_mac: + name: MacOS + runs-on: macos-11 + needs: check_changelog + + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: recursive + + # this is for the macports job + - name: Cache Artifacts + uses: actions/cache@v3 + with: + path: artifacts + key: ${{ runner.os }}-artifacts + + - name: Setup Dependencies MacOS + run: | + # install dependencies using homebrew + brew install boost cmake ffmpeg opus + + # fix openssl header not found + ln -sf /usr/local/opt/openssl/include/openssl /usr/local/include/openssl + + - name: Build MacOS + run: | + # variables for Portfile + owner=$(echo ${{ github.repository_owner }} | tr '[:upper:]' '[:lower:]' ) + repo=$(echo ${GITHUB_REPOSITORY#*/} | tr '[:upper:]' '[:lower:]' ) + branch=${GITHUB_HEAD_REF} + + # check the branch variable + if [ -z "$branch" ] + then + echo "This is a PUSH event" + branch=${GITHUB_BASE_REF} + else + echo "This is a PR event" + fi + echo "Owner: ${owner}" + echo "Repo: ${repo}" + echo "Branch: ${branch}" + + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DSUNSHINE_ASSETS_DIR=/usr/local/sunshine/assets -DSUNSHINE_CONFIG_DIR=/usr/local/sunshine/config -DGITHUB_OWNER=${owner} -DGITHUB_REPO=${repo} -DGITHUB_BRANCH=${branch} .. + make -j ${nproc} + + - name: Package MacOS + run: | + # remove cached artifacts + rm -r -f ./artifacts + mkdir artifacts + + mkdir -p artifacts + cd build + + # package + cpack -G DragNDrop + mv ./cpack_artifacts/Sunshine.dmg ../artifacts/sunshine-macos-experimental-dragndrop.dmg + + cpack -G Bundle + mv ./cpack_artifacts/Sunshine.dmg ../artifacts/sunshine-macos-experimental-bundle.dmg + + cpack -G ZIP + mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-macos-experimental-archive.zip + + # move + mv Portfile ../artifacts/Portfile + + - name: Upload Artifacts + uses: actions/upload-artifact@v3 + with: + name: sunshine-macos + path: artifacts/ + + # this step can be removed after packages are fixed + - name: Delete experimental packages + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} + working-directory: artifacts + run: | + rm -f ./sunshine-macos-experimental-dragndrop.dmg + rm -f ./sunshine-macos-experimental-bundle.dmg + rm -f ./sunshine-macos-experimental-archive.zip + + - name: Create Release + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} + uses: SunshineStream/actions/create_release@master + with: + token: ${{ secrets.GITHUB_TOKEN }} + next_version: ${{ needs.check_changelog.outputs.next_version }} + last_version: ${{ needs.check_changelog.outputs.last_version }} + release_body: ${{ needs.check_changelog.outputs.release_body }} + +# build_mac_port: +# name: Macports +# runs-on: macos-11 +# needs: [check_changelog, build_mac] +# +# steps: +# - name: Cache Artifacts +# uses: actions/cache@v3 +# with: +# path: artifacts +# key: ${{ runner.os }}-artifacts +# +# - name: Setup Macports +# run : | +# # update paths for macports +# echo "/opt/local/sbin" >> $GITHUB_PATH +# echo "/opt/local/bin" >> $GITHUB_PATH +# +# # Set OpenSSL 1.1 as default +# # rm -rf /usr/local/opt/openssl +# # rm -rf /usr/local/bin/openssl +# # ln -sf /usr/local/Cellar/openssl@1.1/1.1.1o/bin/openssl /usr/local/bin/openssl +# # ln -sf /usr/local/Cellar/openssl@1.1/1.1.1o /usr/local/opt/openssl +# +# # download and extract macports +# curl -O https://distfiles.macports.org/MacPorts/MacPorts-2.7.2.tar.bz2 +# tar xf MacPorts-2.7.2.tar.bz2 +# +# # build macports +# cd MacPorts-2.7.2 +# ./configure +# make +# sudo make install +# cd ../ +# rm -rf MacPorts-2.7.2* +# +# - name: Configure Macports +# run: | +# # update sources +# sudo port -v selfupdate +# +# # use custom sources +# sudo chmod 777 /opt/local/etc/macports/sources.conf +# echo file://$(echo ~)/ports > /opt/local/etc/macports/sources.conf +# echo rsync://rsync.macports.org/macports/release/tarballs/ports.tar [default] >> /opt/local/etc/macports/sources.conf +# sudo chmod 644 /opt/local/etc/macports/sources.conf +# +# # setup custom port +# mkdir -p ~/ports/multimedia/sunshine +# +# # copy configured Portfile +# mv ./artifacts/Portfile ~/ports/multimedia/sunshine/ +# +# # remove remaining cached artifacts +# rm -r -f ./artifacts +# mkdir artifacts +# +# # index the ports +# cd ~/ports +# portindex +# +# - name: Build +# run: | +# # build port +# sudo port install sunshine \ +# || cat /opt/local/var/macports/logs/_Users_runner_ports_multimedia_sunshine/Sunshine/main.log \ +# && exit 1 +# +# # create packages +# sudo port dmg sunshine +# sudo port pkg sunshine +# +# # move +# mv $(port work sunshine)/Sunshine*.dmg ./artifacts/sunshine.dmg +# mv $(port work sunshine)/Sunshine*.ppkg ./artifacts/sunshine.pkg +# +# # testing only +# # ls ~/ports/multimedia/sunshine +# # cat ~/ports/multimedia/sunshine/Portfile +# # cat /opt/local/etc/macports/sources.conf +# # cat ~/ports/Portindex +# # port search sunshine +# +# - name: Upload Artifacts +# uses: actions/upload-artifact@v3 +# with: +# name: sunshine-macports +# path: artifacts/ +# +# - name: Create Release +# if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} +# uses: SunshineStream/actions/create_release@master +# with: +# token: ${{ secrets.GITHUB_TOKEN }} +# next_version: ${{ needs.check_changelog.outputs.next_version }} +# last_version: ${{ needs.check_changelog.outputs.last_version }} +# release_body: ${{ needs.check_changelog.outputs.release_body }} + build_win: name: Windows runs-on: windows-2019 @@ -201,54 +445,58 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 with: submodules: recursive - - name: MSYS2 Setup + + - name: Setup Dependencies Windows uses: msys2/setup-msys2@v2 with: update: true install: >- base-devel + diffutils git + make mingw-w64-x86_64-binutils - mingw-w64-x86_64-openssl + mingw-w64-x86_64-boost mingw-w64-x86_64-cmake + mingw-w64-x86_64-nsis + mingw-w64-x86_64-openssl + mingw-w64-x86_64-opus mingw-w64-x86_64-toolchain - mingw-w64-x86_64-opus mingw-w64-x86_64-x265 - mingw-w64-x86_64-boost - git - yasm - nasm - diffutils - make + nasm + yasm + - name: Build Windows shell: msys2 {0} run: | - mkdir sunshine-windows-build && cd sunshine-windows-build - cmake -DCMAKE_BUILD_TYPE=Release -DSUNSHINE_ASSETS_DIR=assets -G "MinGW Makefiles" .. + mkdir build + cd build + cmake -DCMAKE_BUILD_TYPE=Release -DSUNSHINE_ASSETS_DIR=assets -DSUNSHINE_CONFIG_DIR=config -G "MinGW Makefiles" .. mingw32-make -j2 + - name: Package Windows + shell: msys2 {0} run: | - cd sunshine-windows-build - del ..\assets\apps_linux.json - 7z a Sunshine-Windows.zip ..\assets - 7z a Sunshine-Windows.zip sunshine.exe - 7z a Sunshine-Windows.zip tools\dxgi-info.exe - 7z a Sunshine-Windows.zip tools\audio-info.exe - 7z a Sunshine-Windows.zip tools\sunshinesvc.exe - 7z a Sunshine-Windows.zip ..\tools\install-service.bat - 7z a Sunshine-Windows.zip ..\tools\uninstall-service.bat - cd .. - mkdir artifacts - move "sunshine-windows-build\Sunshine-Windows.zip" "artifacts" + mkdir -p artifacts + cd build + + # package + cpack -G NSIS + cpack -G ZIP + + # move + mv ./cpack_artifacts/Sunshine.exe ../artifacts/sunshine-windows.exe + mv ./cpack_artifacts/Sunshine.zip ../artifacts/sunshine-windows.zip + - name: Upload Artifacts - if: ${{ github.event_name == 'pull_request' || github.event_name == 'workflow_dispatch' }} - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: - name: sunshine-${{ runner.os }} + name: sunshine-windows path: artifacts/ + - name: Create Release if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} uses: SunshineStream/actions/create_release@master diff --git a/.github/workflows/clang.yml b/.github/workflows/clang.yml index 9ac9d06a1d..3c0a70e6d5 100644 --- a/.github/workflows/clang.yml +++ b/.github/workflows/clang.yml @@ -3,33 +3,29 @@ name: clang-format-lint on: pull_request: branches: [master, nightly] - types: [opened, synchronize, edited, reopened] + types: [opened, synchronize, reopened] jobs: lint: name: Clang Format Lint runs-on: ubuntu-latest - strategy: - fail-fast: false # false to test all, true to fail entire job if any fail - matrix: - inplace: [ true, false ] # removed ubuntu_18_04 for now steps: - name: Checkout - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Clang format lint - uses: DoozyX/clang-format-lint-action@v0.13 + uses: DoozyX/clang-format-lint-action@v0.14 with: source: './sunshine' extensions: 'cpp,h,m,mm' clangFormatVersion: 13 style: file - inplace: ${{ matrix.inplace }} + inplace: false - name: Upload Artifacts - if: ${{ matrix.inplace == true }} - uses: actions/upload-artifact@v2 + if: failure() + uses: actions/upload-artifact@v3 with: name: sunshine path: sunshine/ diff --git a/.github/workflows/issues-stale.yml b/.github/workflows/issues-stale.yml index 02aa6ca820..233582bd47 100644 --- a/.github/workflows/issues-stale.yml +++ b/.github/workflows/issues-stale.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Stale - uses: actions/stale@v3 + uses: actions/stale@v5 with: stale-issue-message: > This issue is stale because it has been open for 30 days with no activity. @@ -26,25 +26,23 @@ jobs: This PR was closed because it has been stalled for 5 days with no activity. stale-pr-label: 'stale' exempt-pr-labels: 'status:in-progress' - days-before-stale: 30 - days-before-close: 5 + days-before-stale: 60 + days-before-close: 10 - name: Invalid Template - uses: actions/stale@v3 + uses: actions/stale@v5 with: stale-issue-message: > Invalid issues template. close-issue-message: > This issue was closed because the the template was not completed after 5 days. stale-issue-label: 'invalid:template-incomplete' - skip-stale-issue-message: true stale-pr-message: > Invalid PR template. close-pr-message: > This PR was closed because the the template was not completed after 5 days. stale-pr-label: 'invalid:template-incomplete' exempt-pr-labels: 'status:in-progress' - skip-stale-pr-message: true only-labels: 'invalid:template-incomplete' days-before-stale: 0 days-before-close: 5 diff --git a/.github/workflows/localize.yml b/.github/workflows/localize.yml new file mode 100644 index 0000000000..f4828e99cc --- /dev/null +++ b/.github/workflows/localize.yml @@ -0,0 +1,93 @@ +name: localize + +on: + push: + branches: [nightly] + paths: # prevents workflow from running unless these files change + - '.github/workflows/localize.yml' + - 'sunshine/**' + - 'locale/sunshine.po' + workflow_dispatch: + +env: + file: ./locale/sunshine.po + +jobs: + localize: + name: Update Localization + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Install Python 3.9 + uses: actions/setup-python@v4 # https://github.com/actions/setup-python + with: + python-version: '3.9' + + - name: Set up Python 3.9 Dependencies + run: | + cd ./scripts + python -m pip install --upgrade pip setuptools + python -m pip install -r requirements.txt + + - name: Set up xgettext + run: | + sudo apt-get update -y && \ + sudo apt-get --reinstall install -y \ + gettext + + - name: Update Strings + run: | + # first, try to remove existing file as xgettext does not remove unused translations + if [ -f "${{ env.file }}" ]; + then + rm ${{ env.file }} + echo "new_file=false" >> $GITHUB_ENV + else + echo "new_file=true" >> $GITHUB_ENV + fi + + # extract the new strings + python ./scripts/_locale.py --extract + + - name: git diff + if: ${{ env.new_file == 'false' }} + run: | + # disable the pager + git config --global pager.diff false + + # print the git diff + git diff locale/sunshine.po + + # set the variable with minimal output + OUTPUT=$(git diff --numstat locale/sunshine.po) + echo "git_diff=${OUTPUT}" >> $GITHUB_ENV + + - name: git reset + # only run if a single line changed (date/time) and file already existed + if: ${{ env.git_diff == '1 1 locale/sunshine.po' && env.new_file == 'false' }} + run: | + git reset --hard + + - name: Create/Update Pull Request + uses: peter-evans/create-pull-request@v4 + with: + add-paths: | + locale/*.po + token: ${{ secrets.GH_PAT }} # must trigger PR tests + commit-message: New localization template + branch: localize/update + delete-branch: true + base: nightly + title: New Babel Updates + body: | + Update report + - Updated with *today's* date + - Auto-generated by [create-pull-request][1] + + [1]: https://github.com/peter-evans/create-pull-request + labels: | + babel + l10n diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml index a322319e93..36f597b909 100644 --- a/.github/workflows/pull-requests.yml +++ b/.github/workflows/pull-requests.yml @@ -5,31 +5,17 @@ on: types: [opened, synchronize, edited, reopened] jobs: - check-branch: + check-pull-request: name: Check Pull Request runs-on: ubuntu-latest steps: - - name: Checkout Code - uses: actions/checkout@v2 - - - name: Branch check - if: ( github.head_ref == 'repo-sync/common-repo-files/default' && github.base_ref == 'master' ) || ( github.head_ref == 'nightly' && github.base_ref == 'master' ) - run: | - echo Base: "$GITHUB_BASE_REF" - echo Head: "$GITHUB_HEAD_REF" - echo "branch=True" >> $GITHUB_ENV - - - name: Comment on Pull Request - uses: mshick/add-pr-comment@v1 - if: github.base_ref != 'nightly' && env.branch != 'True' + - uses: Vankka/pr-target-branch-action@v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - message: Pull requests must be made to the `nightly` branch. Thanks. - repo-token: ${{ secrets.GITHUB_TOKEN }} - repo-token-user-login: 'github-actions[bot]' - - - name: Fail Workflow - if: github.base_ref != 'nightly' && env.branch != 'True' - run: | - echo Base: "$GITHUB_BASE_REF" - echo Head: "$GITHUB_HEAD_REF" - exit 1 + target: master + exclude: nightly # Don't prevent going from nightly -> master + change-to: nightly + comment: | + Your PR was set to `master`, PRs should be sent to `nightly` + The base branch of this PR has been automatically changed to `nightly`, please check that there are no merge conflicts diff --git a/.gitignore b/.gitignore index 6fb681e7f2..6c44c5bc23 100644 --- a/.gitignore +++ b/.gitignore @@ -10,11 +10,15 @@ cmake-build* .idea # Extra FontAwesome files -/assets/web/fonts/fontawesome-free-web/css/*.css -!/assets/web/fonts/fontawesome-free-web/css/*min.css -/assets/web/fonts/fontawesome-free-web/js/ -/assets/web/fonts/fontawesome-free-web/less/ -/assets/web/fonts/fontawesome-free-web/metadata/ -/assets/web/fonts/fontawesome-free-web/scss/ -/assets/web/fonts/fontawesome-free-web/sprites/ -/assets/web/fonts/fontawesome-free-web/svgs/ +/src_assets/common/assets/web/fonts/fontawesome-free-web/css/*.css +!/src_assets/common/assets/web/fonts/fontawesome-free-web/css/*min.css +/src_assets/common/assets/web/fonts/fontawesome-free-web/js/ +/src_assets/common/assets/web/fonts/fontawesome-free-web/less/ +/src_assets/common/assets/web/fonts/fontawesome-free-web/metadata/ +/src_assets/common/assets/web/fonts/fontawesome-free-web/scss/ +/src_assets/common/assets/web/fonts/fontawesome-free-web/sprites/ +/src_assets/common/assets/web/fonts/fontawesome-free-web/svgs/ + +# Translations +*.mo +*.pot diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000000..762371f85d --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,44 @@ +# .readthedocs.yaml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Set the version of Python +build: + os: ubuntu-20.04 + tools: + python: "3.9" + +## apt packages required packages to run cmake on sunshine, note that additional packages are required +# apt_packages: +# - cmake +# - ffmpeg +# - libboost-filesystem-dev +# - libboost-log-dev +# - libboost-thread-dev + +## run cmake +# jobs: +# pre_build: +# - cmake . + +## Include the submodules, required for cmake +#submodules: +# include: all +# recursive: true + +# Build documentation in the docs/ directory with Sphinx +sphinx: + builder: html + configuration: docs/source/conf.py + fail_on_warning: true + +# Using Sphinx, build docs in additional formats +formats: all + +python: + install: + - requirements: ./scripts/requirements.txt + system_packages: true diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a18ecbd74..1844e3559c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,23 @@ # Changelog +## [0.14.0] - 2022-06-15 +### Added +- (Documentation) Added Sphinx documentation available at https://sunshinestream.readthedocs.io/en/latest/ +- (Development) Initial support for Localization +- (Linux) Add rpm package as release asset +- (MacOS) Add Portfile as release asset +- (Windows) Add DwmFlush() call to improve capture +- (Windows) Add Windows installer +### Fixed +- (AMD) Fixed hwdevice being destroyed before context +- (Linux) Added missing dependencies to AppImage +- (Linux) Fixed rumble events causing game to freeze +- (Linux) Improved Pulse/Pipewire compatibility +- (Linux) Moved to single deb package +- (MacOS) Fixed missing TPCircularBuffer submodule +- (Stream) Properly catch exceptions in stream broadcast handlers +- (Stream/Video) AVPacket fix + ## [0.13.0] - 2022-02-27 ### Added - (MacOS) Initial support for MacOS (#40) diff --git a/CMakeLists.txt b/CMakeLists.txt index c3a1936e53..44f24e7d6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,12 @@ cmake_minimum_required(VERSION 3.0) -project(Sunshine VERSION 0.13.0) +project(Sunshine VERSION 0.14.0 + DESCRIPTION "Sunshine is a Gamestream host for Moonlight." + HOMEPAGE_URL "https://sunshinestream.github.io" + ) set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) +set(SUNSHINE_SOURCE_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src_assets") if(WIN32) # Ugly hack to compile with #include @@ -58,7 +62,7 @@ if(WIN32) INPUT "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pre-compiled) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static") - + if(NOT DEFINED SUNSHINE_PREPARED_BINARIES) set(SUNSHINE_PREPARED_BINARIES "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled/windows") endif() @@ -66,8 +70,6 @@ if(WIN32) add_compile_definitions(SUNSHINE_PLATFORM="windows") add_subdirectory(tools) #This is temporary, only tools for Windows are needed, for now - list(APPEND SUNSHINE_DEFINITIONS APPS_JSON="apps_windows.json") - include_directories(third-party/ViGEmClient/include) if(NOT DEFINED SUNSHINE_ICON_PATH) @@ -120,13 +122,13 @@ if(WIN32) ws2_32 d3d11 dxgi D3DCompiler setupapi + dwmapi ) set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp PROPERTIES COMPILE_DEFINITIONS "UNICODE=1;ERROR_INVALID_DEVICE_OBJECT_PARAMETER=650") set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp PROPERTIES COMPILE_FLAGS "-Wno-unknown-pragmas -Wno-misleading-indentation -Wno-class-memaccess") elseif(APPLE) add_compile_definitions(SUNSHINE_PLATFORM="macos") - list(APPEND SUNSHINE_DEFINITIONS APPS_JSON="apps_mac.json") link_directories(/opt/local/lib) link_directories(/usr/local/lib) ADD_DEFINITIONS(-DBOOST_LOG_DYN_LINK) @@ -147,6 +149,8 @@ elseif(APPLE) set(PLATFORM_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) + set(APPLE_PLIST_FILE ${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/Info.plist) + set(PLATFORM_TARGET_FILES sunshine/platform/macos/av_audio.h sunshine/platform/macos/av_audio.m @@ -163,10 +167,9 @@ elseif(APPLE) sunshine/platform/macos/publish.cpp sunshine/platform/macos/TPCircularBuffer/TPCircularBuffer.c sunshine/platform/macos/TPCircularBuffer/TPCircularBuffer.h - ${CMAKE_CURRENT_SOURCE_DIR}/assets/Info.plist) + ${APPLE_PLIST_FILE}) else() add_compile_definitions(SUNSHINE_PLATFORM="linux") - list(APPEND SUNSHINE_DEFINITIONS APPS_JSON="apps_linux.json") option(SUNSHINE_ENABLE_DRM "Enable KMS grab if available" ON) option(SUNSHINE_ENABLE_X11 "Enable X11 grab if available" ON) @@ -296,14 +299,14 @@ else() third-party/glad/include/KHR/khrplatform.h third-party/glad/include/glad/gl.h third-party/glad/include/glad/egl.h) - + list(APPEND PLATFORM_LIBRARIES dl evdev pulse pulse-simple ) - + include_directories( /usr/include/libevdev-1.0 third-party/nv-codec-headers/include @@ -312,8 +315,6 @@ else() if(NOT DEFINED SUNSHINE_EXECUTABLE_PATH) set(SUNSHINE_EXECUTABLE_PATH "sunshine") endif() - configure_file(gen-deb.in gen-deb @ONLY) - configure_file(sunshine.desktop.in sunshine.desktop @ONLY) configure_file(sunshine.service.in sunshine.service @ONLY) endif() @@ -393,15 +394,11 @@ else() endif() if(NOT SUNSHINE_ASSETS_DIR) - set(SUNSHINE_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets") + set(SUNSHINE_ASSETS_DIR "${CMAKE_CURRENT_BINARY_DIR}/assets") endif() if(NOT SUNSHINE_CONFIG_DIR) - set(SUNSHINE_CONFIG_DIR "${SUNSHINE_ASSETS_DIR}") -endif() - -if(NOT SUNSHINE_DEFAULT_DIR) - set(SUNSHINE_DEFAULT_DIR "${SUNSHINE_ASSETS_DIR}") + set(SUNSHINE_CONFIG_DIR "${CMAKE_CURRENT_BINARY_DIR}/config") endif() list(APPEND CBS_EXTERNAL_LIBRARIES @@ -424,7 +421,6 @@ endif() list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR}") list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_CONFIG_DIR="${SUNSHINE_CONFIG_DIR}") -list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_DEFAULT_DIR="${SUNSHINE_DEFAULT_DIR}") add_executable(sunshine ${SUNSHINE_TARGET_FILES}) target_link_libraries(sunshine ${SUNSHINE_EXTERNAL_LIBRARIES} ${EXTRA_LIBS}) target_compile_definitions(sunshine PUBLIC ${SUNSHINE_DEFINITIONS}) @@ -439,7 +435,7 @@ if(NOT DEFINED CMAKE_CUDA_STANDARD) endif() if(APPLE) - target_link_options(sunshine PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/assets/Info.plist) + target_link_options(sunshine PRIVATE LINKER:-sectcreate,__TEXT,__info_plist,${APPLE_PLIST_FILE}) endif() foreach(flag IN LISTS SUNSHINE_COMPILE_OPTIONS) @@ -447,3 +443,153 @@ foreach(flag IN LISTS SUNSHINE_COMPILE_OPTIONS) endforeach() target_compile_options(sunshine PRIVATE $<$:${SUNSHINE_COMPILE_OPTIONS}>;$<$:${SUNSHINE_COMPILE_OPTIONS_CUDA};-std=c++17>) + +# CPACK / Packaging + +# Common options +set(CPACK_PACKAGE_NAME "SunshineStream") +set(CPACK_PACKAGE_VENDOR "SunshineStream") +set(CPACK_PACKAGE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/cpack_artifacts) +set(CPACK_PACKAGE_CONTACT "https://github.com/SunshineStream/Sunshine") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER "https://github.com/SunshineStream/Sunshine") +set(CPACK_PACKAGE_DESCRIPTION ${CMAKE_PROJECT_DESCRIPTION}) +set(CPACK_PACKAGE_HOMEPAGE_URL ${CMAKE_PROJECT_HOMEPAGE_URL}) +set(CPACK_RESOURCE_FILE_LICENSE ${PROJECT_SOURCE_DIR}/LICENSE) +set(CPACK_PACKAGE_ICON ${PROJECT_SOURCE_DIR}/sunshine.png) +set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}") +set(CPACK_STRIP_FILES YES) + +# Platform specific options +if(WIN32) # see options at: https://cmake.org/cmake/help/latest/cpack_gen/nsis.html + install(TARGETS sunshine RUNTIME DESTINATION "." COMPONENT application) + + # Adding tools + install(TARGETS dxgi-info RUNTIME DESTINATION "tools" COMPONENT dxgi) + install(TARGETS audio-info RUNTIME DESTINATION "tools" COMPONENT audio) + install(TARGETS sunshinesvc RUNTIME DESTINATION "tools" COMPONENT sunshinesvc) + + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}" COMPONENT assets) + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}" COMPONENT assets) + + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}" COMPONENT config) + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/windows/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}" COMPONENT config) + + + # set(CPACK_NSIS_MUI_HEADERIMAGE "") # TODO: image should be 150x57 bmp + + set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}\\\\sunshine.ico") + set(CPACK_NSIS_INSTALLED_ICON_NAME "${PROJECT__DIR}\\\\${PROJECT_EXE}") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "${CPACK_PACKAGE_NAME}") # The name of the directory that will be created in C:/Program files/ + string(APPEND CPACK_NSIS_DEFINES "\n RequestExecutionLevel admin") # TODO: Not sure if this is needed but it took me a while to figure out where to put this option so I'm leaving it here + + # Sets permissions on the installed folder so that we can write in it + SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS + "${CPACK_NSIS_EXTRA_INSTALL_COMMANDS} + ExecWait 'icacls \\\"$INSTDIR\\\" /grant:r Users:\\\(OI\\\)\\\(CI\\\)\\\(F\\\)' + ") + + # Adding an option for the start menu and PATH + set(CPACK_NSIS_MODIFY_PATH "OFF") # TODO: it asks to add it to the PATH but is not working https://gitlab.kitware.com/cmake/cmake/-/issues/15635 + set(CPACK_NSIS_EXECUTABLES_DIRECTORY ".") + set(CPACK_NSIS_MUI_FINISHPAGE_RUN "${CMAKE_PROJECT_NAME}.exe") + set(CPACK_NSIS_INSTALLED_ICON_NAME "${CMAKE_PROJECT_NAME}.exe") # This will be shown on the installed apps Windows settings + set(CPACK_NSIS_CREATE_ICONS "CreateShortCut '\$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\${CMAKE_PROJECT_NAME}.lnk' '\$INSTDIR\\\\${CMAKE_PROJECT_NAME}.exe'") + + # Checking for previous installed versions + # set(CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL "ON") # TODO: doesn't work on my machine when Sunshine is already installed + + # Setting components groups and dependencies + # sunshine binary + set(CPACK_COMPONENT_APPLICATION_DISPLAY_NAME "${CMAKE_PROJECT_NAME}") + set(CPACK_COMPONENT_APPLICATION_DESCRIPTION "The main application.") + set(CPACK_COMPONENT_APPLICATION_GROUP "${CMAKE_PROJECT_NAME}") + set(CPACK_COMPONENT_APPLICATION_REQUIRED true) + set(CPACK_COMPONENT_APPLICATION_DEPENDS assets) + + # assets + set(CPACK_COMPONENT_ASSETS_DISPLAY_NAME "Assets") + set(CPACK_COMPONENT_ASSETS_DESCRIPTION "Shaders, default box art, and web ui.") + set(CPACK_COMPONENT_ASSETS_GROUP "${CMAKE_PROJECT_NAME}") + set(CPACK_COMPONENT_ASSETS_REQUIRED true) + + # config + set(CPACK_COMPONENT_CONFIG_DISPLAY_NAME "Config") + set(CPACK_COMPONENT_CONFIG_DESCRIPTION "Default config and apps.json files.") + set(CPACK_COMPONENT_CONFIG_GROUP "${CMAKE_PROJECT_NAME}") + set(CPACK_COMPONENT_CONFIG_REQUIRED true) + + # audio tool + set(CPACK_COMPONENT_AUDIO_DISPLAY_NAME "audio-info.exe") + set(CPACK_COMPONENT_AUDIO_DESCRIPTION "CLI tool that allows you to get information about sound devices.") + set(CPACK_COMPONENT_AUDIO_GROUP "Tools") + + # display tool + set(CPACK_COMPONENT_DXGI_DISPLAY_NAME "dxgi-info.exe") + set(CPACK_COMPONENT_DXGI_DESCRIPTION "CLI tool that allows you to get information about graphics cards and displays.") + set(CPACK_COMPONENT_DXGI_GROUP "Tools") + + # service tool + set(CPACK_COMPONENT_SUNSHINESVC_DISPLAY_NAME "sunshinesvc.exe") + set(CPACK_COMPONENT_SUNSHINESVC_DESCRIPTION "CLI tool that allows you to enable/disable the Sunshine service.") + set(CPACK_COMPONENT_SUNSHINESVC_GROUP "Tools") +endif() +if(UNIX) + # Installation destination dir + set(CPACK_SET_DESTDIR true) + if(NOT CMAKE_INSTALL_PREFIX) + set(CMAKE_INSTALL_PREFIX "/usr/local/sunshine") + endif() + + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}") + + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/common/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}") +endif() +if(APPLE) # TODO: test + + set(prefix "${CMAKE_PROJECT_NAME}.app/Contents") + set(INSTALL_RUNTIME_DIR "${prefix}/MacOS") + + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}") + + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/macos/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}") + + install(TARGETS sunshine + BUNDLE DESTINATION . COMPONENT Runtime + RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR} COMPONENT Runtime) + + # TODO: bundle doesn't produce a valid .app use cpack -G DragNDrop + set(CPACK_BUNDLE_NAME "${CMAKE_PROJECT_NAME}") + set(CPACK_BUNDLE_PLIST "${APPLE_PLIST_FILE}") + set(CPACK_BUNDLE_ICON "${PROJECT_SOURCE_DIR}/sunshine.icns") + # set(CPACK_BUNDLE_STARTUP_COMMAND "${INSTALL_RUNTIME_DIR}/sunshine") + + # Portfile + configure_file(Portfile.in Portfile @ONLY) +endif() +if(UNIX AND NOT APPLE) + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/assets/" DESTINATION "${SUNSHINE_ASSETS_DIR}") + + install(DIRECTORY "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/config/" DESTINATION "${SUNSHINE_CONFIG_DIR}") + + install(FILES "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/85-sunshine-rules.rules" DESTINATION "/etc/udev/rules.d") + + install(TARGETS sunshine RUNTIME DESTINATION "/usr/bin") + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/sunshine.service" DESTINATION "/usr/lib/systemd/user") + + # Pre and post install + set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/preinst;${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst;${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/conffiles") + set(CPACK_RPM_PRE_INSTALL_SCRIPT_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/preinst") + set(CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${SUNSHINE_SOURCE_ASSETS_DIR}/linux/misc/postinst") + + # Dependencies + set(CPACK_DEB_COMPONENT_INSTALL ON) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "openssl, libavdevice58, libboost-thread1.67.0 | libboost-thread1.71.0 | libboost-thread1.74.0, libboost-filesystem1.67.0 | libboost-filesystem1.71.0 | libboost-filesystem1.74.0, libboost-log1.67.0 | libboost-log1.71.0 | libboost-log1.74.0, libpulse0, libopus0, libxcb-shm0, libxcb-xfixes0, libxtst6, libevdev2, libdrm2, libcap2") + set(CPACK_RPM_PACKAGE_REQUIRES "openssl >= 1.1, libavdevice >= 4.3, boost-thread >= 1.67.0, boost-filesystem >= 1.67.0, boost-log >= 1.67.0, pulseaudio-libs >= 10.0, libopusenc >= 0.2.1, libxcb >= 1.13, libXtst >= 1.2.3, libevdev >= 1.5.6, libdrm >= 2.4.97, libcap >= 2.22") + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) # This should automatically figure out dependencies, doesn't work with the current config + + # AppImage desktop file + configure_file(sunshine.desktop.in sunshine.desktop @ONLY) +endif() + +include(CPack) diff --git a/DOCKER_README.md b/DOCKER_README.md new file mode 100644 index 0000000000..aa2f1017a6 --- /dev/null +++ b/DOCKER_README.md @@ -0,0 +1,113 @@ +# Docker + +## Using docker run +Create and run the container (substitute your ``): + +```bash +docker run -d \ + --name=sunshine \ + --restart=unless-stopped + -v :/config \ + -e PUID= \ + -e PGID= \ + -e TZ= \ + -p 47990:47990 \ + -p 47984:47984 \ + -p 47989:47989 \ + -p 48010:48010 \ + -p 47998:47998 \ + -p 47999:47999 \ + -p 48000:48000 \ + -p 48002:48002 \ + -p 48010:48010 \ + sunshinestream/sunshine +``` + +To update the container it must be removed and recreated: + +```bash +# Stop the container +docker stop sunshine +# Remove the container +docker rm sunshine +# Pull the latest update +docker pull sunshinestream/sunshine +# Run the container with the same parameters as before +docker run -d ... +``` + +## Using docker-compose + +Create a `docker-compose.yml` file with the following contents (substitute your ``): + +```yaml +version: '3' +services: + sunshine: + image: sunshinestream/sunshine + container_name: sunshine + restart: unless-stopped + volumes: + - :/config + environment: + - PUID= + - PGID= + - TZ= + ports: + - "47990:47990" + - "47984:47984" + - "47989:47989" + - "48010:48010" + - "47998:47998" + - "47999:47999" + - "48000:48000" + - "48002:48002" + - "48010:48010" +``` + +Create and start the container (run the command from the same folder as your `docker-compose.yml` file): + +```bash +docker-compose up -d +``` + +To update the container: +```bash +# Pull the latest update +docker-compose pull +# Update and restart the container +docker-compose up -d +``` + +## Parameters +You must substitute the `` with your own settings. + +Parameters are split into two halves separated by a colon. The left side represents the host and the right side the +container. + +**Example:** `-p external:internal` - This shows the port mapping from internal to external of the container. +Therefore `-p 47990:47990` would expose port `47990` from inside the container to be accessible from the host's IP on +port `47990` (e.g. `http://:47990`). The internal port must be `47990`, but the external port may be changed +(e.g. `-p 8080:47990`). + + +| Parameter | Function | Example Value | Required | +| --------------------------- | -------------------- | ------------------- | -------- | +| `-p :47990` | Web UI Port | `47990` | True | +| `-v :/config` | Volume mapping | `/home/sunshine` | True | +| `-e PUID=` | User ID | `1001` | False | +| `-e PGID=` | Group ID | `1001` | False | +| `-e TZ=` | Lookup TZ value [here](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) | `America/New_York` | True | + +### User / Group Identifiers: + +When using data volumes (-v flags) permissions issues can arise between the host OS and the container. To avoid this +issue you can specify the user PUID and group PGID. Ensure the data volume directory on the host is owned by the same +user you specify. + +In this instance `PUID=1001` and `PGID=1001`. To find yours use id user as below: + +```bash +$ id dockeruser +uid=1001(dockeruser) gid=1001(dockergroup) groups=1001(dockergroup) +``` diff --git a/Portfile b/Portfile deleted file mode 100644 index ea751ca8b3..0000000000 --- a/Portfile +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4 - -PortSystem 1.0 -PortGroup cmake 1.1 -PortGroup github 1.0 -PortGroup boost 1.0 - -github.setup abusse sunshine macos-dev -version 20220224 - -categories multimedia -platforms darwin -license GPL-2 -maintainers {outlook.com:anselm.busse} - -fetch.type git -post-fetch { - system -W ${worksrcpath} "${git.cmd} submodule update --init --recursive" -} - -description Sunshine is a Gamestream host for Moonlight -long_description Sunshine is a Gamestream host for Moonlight - -homepage https://github.com/SunshineStream/Sunshine - -depends_lib port:avahi port:ffmpeg port:libopus - - -boost.version 1.76 - -configure.args -DBOOST_ROOT=[boost::install_area] \ - -DSUNSHINE_ASSETS_DIR=${prefix}/etc/sunshine - -cmake.out_of_source yes - -destroot { - xinstall -d -m 755 ${destroot}${prefix}/etc/${name} - xinstall ${worksrcpath}/assets/apps_mac.json ${destroot}${prefix}/etc/${name} - xinstall ${worksrcpath}/assets/box.png ${destroot}${prefix}/etc/${name} - xinstall ${worksrcpath}/assets/sunshine.conf ${destroot}${prefix}/etc/${name} - - xinstall -d -m 755 ${destroot}${prefix}/etc/${name}/web - xinstall {*}[glob ${worksrcpath}/assets/web/*.html] ${destroot}${prefix}/etc/${name}/web - xinstall -d -m 755 ${destroot}${prefix}/etc/${name}/web/third_party - xinstall {*}[glob ${worksrcpath}/assets/web/third_party/*] ${destroot}${prefix}/etc/${name}/web/third_party - - xinstall ${workpath}/build/${name} ${destroot}${prefix}/bin -} diff --git a/Portfile.in b/Portfile.in new file mode 100644 index 0000000000..36a7d476a2 --- /dev/null +++ b/Portfile.in @@ -0,0 +1,75 @@ +# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4 + +PortSystem 1.0 +PortGroup cmake 1.1 +PortGroup github 1.0 +PortGroup boost 1.0 + +# bump revision when changes are made to this file +revision 1 + +github.setup @GITHUB_OWNER@ @GITHUB_REPO@ @GITHUB_BRANCH@ +name @PROJECT_NAME@ +version @PROJECT_VERSION@ +categories multimedia emulators games +platforms darwin +license GPL-3 +maintainers {@SunshineStream sunshinestream} +description @PROJECT_DESCRIPTION@ +long_description {*}${description} +homepage @PROJECT_HOMEPAGE_URL@ +master_sites https://github.com/@GITHUB_OWNER@/@GITHUB_REPO@/releases + +fetch.type git +post-fetch { + system -W ${worksrcpath} "${git.cmd} submodule update --init --recursive" +} + +depends_lib port:avahi \ + port:ffmpeg \ + port:libopus + +boost.version 1.76 + +configure.args -DBOOST_ROOT=[boost::install_area] \ + -DSUNSHINE_ASSETS_DIR=${prefix}/etc/sunshine/assets \ + -DSUNSHINE_CONFIG_DIR=${prefix}/etc/sunshine/config + +cmake.out_of_source yes + +startupitem.create yes +startupitem.executable "${prefix}/bin/{$name}" +startupitem.location LaunchDaemons +startupitem.name ${name} +startupitem.netchange yes + +# is this actually necessary? this should all be handled by CMakeLists +destroot { + # install assets + xinstall -d -m 755 ${destroot}${prefix}/etc/${name}/assets + xinstall {*}[glob ${worksrcpath}/src_assets/common/assets/*.*] ${destroot}${prefix}/etc/${name}/assets + xinstall {*}[glob ${worksrcpath}/src_assets/macos/assets/*.*] ${destroot}${prefix}/etc/${name}/assets + + # install web assets + xinstall -d -m 755 ${destroot}${prefix}/etc/${name}/assets/web/fonts/fontawesome-free-web/css + xinstall -d -m 755 ${destroot}${prefix}/etc/${name}/assets/web/fonts/fontawesome-free-web/webfonts + xinstall {*}[glob ${worksrcpath}/src_assets/common/assets/web/*.*] ${destroot}${prefix}/etc/${name}/assets/web + xinstall {*}[glob ${worksrcpath}/src_assets/common/assets/web/fonts/fontawesome-free-web/*.*] ${destroot}${prefix}/etc/${name}/assets/web/fonts/fontawesome-free-web + xinstall {*}[glob ${worksrcpath}/src_assets/common/assets/web/fonts/fontawesome-free-web/css/*.*] ${destroot}${prefix}/etc/${name}/assets/web/fonts/fontawesome-free-web/css + xinstall {*}[glob ${worksrcpath}/src_assets/common/assets/web/fonts/fontawesome-free-web/webfonts/*.*] ${destroot}${prefix}/etc/${name}/assets/web/fonts/fontawesome-free-web/webfonts + xinstall -d -m 755 ${destroot}${prefix}/etc/${name}/assets/web/images + xinstall -d -m 755 ${destroot}${prefix}/etc/${name}/assets/web/third_party + xinstall {*}[glob ${worksrcpath}/src_assets/common/assets/web/images/*.*] ${destroot}${prefix}/etc/${name}/assets/web/images + xinstall {*}[glob ${worksrcpath}/src_assets/common/assets/web/third_party/*.*] ${destroot}${prefix}/etc/${name}/assets/web/third_party + + xinstall -d -m 755 ${destroot}${prefix}/etc/${name}/config + + # install sunshine.conf + xinstall {*}[glob ${worksrcpath}/src_assets/common/config/*.*] ${destroot}${prefix}/etc/${name}/config + + # install apps.json + xinstall {*}[glob ${worksrcpath}/src_assets/macos/config/*.*] ${destroot}${prefix}/etc/${name}/config + + # install the binary + xinstall ${workpath}/build/${name} ${destroot}${prefix}/bin +} diff --git a/README.md b/README.md deleted file mode 100644 index 72674eac74..0000000000 --- a/README.md +++ /dev/null @@ -1,293 +0,0 @@ -![Sunshine icon](gamepad.png "Sunshine") -# Introduction -Sunshine is a Gamestream host for Moonlight - -[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/cgrtw2g3fq9b0b70/branch/master?svg=true)](https://ci.appveyor.com/project/loki-47-6F-64/sunshine/branch/master) -[![Downloads](https://img.shields.io/github/downloads/Loki-47-6F-64/sunshine/total)](https://github.com/Loki-47-6F-64/sunshine/releases) - -- [Building](README.md#building) -- [Credits](README.md#credits) - -# Building -- [Linux](README.md#linux) -- [MacOS](README.md#macos) -- [Windows](README.md#windows-10) - -## Linux - -If you do not wish to clutter your PC with development files, yet you want the very latest version... -You can use these [build scripts](scripts/README.md) -They make use of docker to handle building Sunshine automatically - -### Requirements: - -Ubuntu 20.04: -Install the following: - -#### Common -``` -sudo apt install cmake gcc-10 g++-10 libssl-dev libavdevice-dev libboost-thread-dev libboost-filesystem-dev libboost-log-dev libpulse-dev libopus-dev libevdev-dev -``` -#### X11 -``` -sudo apt install libxtst-dev libx11-dev libxrandr-dev libxfixes-dev libxcb1-dev libxcb-shm0-dev libxcb-xfixes0-dev -``` - -#### KMS -This requires additional [setup](README.md#Setup). -``` -sudo apt install libdrm-dev libcap-dev -``` - -#### Wayland -This is for wlroots based compositores, such as Sway -``` -sudo apt install libwayland-dev -``` - -#### Cuda + NvFBC -This requires proprietary software -On Ubuntu 20.04, the cuda compiler will fail since it's version is too old, it's recommended you compile the sources with the [build scripts](scripts/README.md) -``` -sudo apt install nvidia-cuda-dev nvidia-cuda-toolkit -``` - -#### Warning: -You might require ffmpeg version >= 4.3. Check the troubleshooting section for more information. - -### Compilation: -- `git clone https://github.com/loki-47-6F-64/sunshine.git --recurse-submodules` -- `cd sunshine && mkdir build && cd build` -- `cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 ..` -- `make -j ${nproc}` - -### Setup: -sunshine needs access to uinput to create mouse and gamepad events: - -- Add user to group 'input': - `usermod -a -G input $USER` -- Create udev rules: - - Run the following command: - `nano /etc/udev/rules.d/85-sunshine-input.rules` - - Input the following contents: - `KERNEL=="uinput", GROUP="input", MODE="0660"` - - Save the file and exit - 1. `CTRL+X` to start exit - 2. `Y` to save modifications -- `assets/sunshine.conf` is an example configuration file. Modify it as you see fit, then use it by running: - `sunshine path/to/sunshine.conf` -- Configure autostart service - `path/to/build/dir/sunshine.service` is used to start sunshine in the background. To use it, do the following: - 1. Copy it to the users systemd, `cp sunshine.service ~/.config/systemd/user/` - 2. Starting - - Onetime: - `systemctl --user start sunshine` - - Always on boot: - `systemctl --user enable sunshine` - -- `assets/apps.json` is an [example](README.md#application-list) of a list of applications that are started just before running a stream - -#### Additional Setup for KMS: -Please note that `cap_sys_admin` may as well be root, except you don't need to be root to run it. -It's necessary to allow Sunshine to use KMS -- `sudo setcap cap_sys_admin+p sunshine` - -### Trouleshooting: -- If you get "Could not create Sunshine Gamepad: Permission Denied", ensure you are part of the group "input": - - `groups $USER` - -- If Sunshine sends audio from the microphone instead of the speaker, try the following steps: - 1. Check whether you're using Pulseaudio or Pipewire - - Pulseaudio: Use `pacmd list-sources | grep "name:"` - - Pipewire: Use `pactl info | grep Source`. In some causes you'd need to use the `sink` device. Try `pactl info | grep Sink`, if _Source_ doesn't work. - 2. Copy the name to the configuration option "audio_sink" - 3. Restart sunshine - -- If you get "Error: Failed to create client: Daemon not running", ensure that your avahi-daemon is running: - - `systemctl status avahi-daemon` - -- If you use hardware acceleration on Linux using an Intel or an AMD GPU (with VAAPI), you will get tons of [graphical issues](https://github.com/loki-47-6F-64/sunshine/issues/228) if your ffmpeg version is < 4.3. If it is not available in your distribution's repositories, consider using a newer version of your distribution. - - Ubuntu started to ship ffmpeg 4.3 starting with groovy (20.10). If you're using an older version, you could use [this PPA](https://launchpad.net/%7Esavoury1/+archive/ubuntu/ffmpeg4) instead of upgrading. **Using PPAs is dangerous and may break your system. Use it at your own risk.** - -## macOS - -### Quickstart - -- Install [MacPorts](https://www.macports.org) -- Download the `Portfile` from this repository to `/tmp` -- In a Terminal run `cd /tmp && sudo port install` -- Sunshine configuration is in `/opt/local/etc` -- Run `sunshine` to start the Sunshine server -- You will be asked to grant access to screen recording and your microphone to be able to stream it - -### Manuel Build - -#### Requirements: -macOS Big Sur and Xcode 12.5+: - -Either, using [MacPorts](https://www.macports.org), install the following -``` -sudo port install cmake boost libopus ffmpeg -``` - -Or, using [Homebrew](https://brew.sh), install the follwoing: -``` -brew install boost cmake ffmpeg libopusenc -# if there are issues with an SSL header that is not found: -cd /usr/local/include -ln -s ../opt/openssl/include/openssl . -``` - -#### Compilation: -- `git clone https://github.com/SunshineStream/Sunshine.git --recurse-submodules` -- `cd sunshine && mkdir build && cd build` -- `cmake ..` -- `make -j ${nproc}` - -If cmake fails complaining to find Boost, try to set the path explicitly: `cmake -DBOOST_ROOT=[boost path] ..`, e.g., `cmake -DBOOST_ROOT=/opt/local/libexec/boost/1.76 ..` - -### Setup: -- Sunshine can only access microphones on macOS due to system limitations. To stream system audio use [Soundflower](https://github.com/mattingalls/Soundflower) or [BlackHole](https://github.com/ExistentialAudio/BlackHole) and select their sink as audio device in `sunshine.conf` -- `assets/sunshine.conf` is an example configuration file. Modify it as you see fit, then use it by running: - `sunshine path/to/sunshine.conf` -- `assets/apps.json` is an [example](README.md#application-list) of a list of applications that are started just before running a stream - -### Usage & Limitations: -- Command Keys are not forwarded by Moonlight. Right Option-Key is mapped to CMD-Key. -- Gamepads are not supported - -## Windows 10 - -### Requirements: - -First you need to install [MSYS2](https://www.msys2.org), then startup "MSYS2 MinGW 64-bit" and install the following packages using `pacman -S`: - - mingw-w64-x86_64-binutils mingw-w64-x86_64-openssl mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-opus mingw-w64-x86_64-x265 mingw-w64-x86_64-boost git mingw-w64-x86_64-make cmake make gcc - -### Compilation: -- `git clone https://github.com/loki-47-6F-64/sunshine.git --recursive` -- `cd sunshine && mkdir build && cd build` -- `cmake -G"Unix Makefiles" ..` -- `mingw32-make` - -### Setup: -- **OPTIONAL** Gamepad support: Download and run 'ViGEmBus_Setup_1.16.116.exe' from [https://github.com/ViGEm/ViGEmBus/releases] - - - -# Common - -## Usage: -- run "sunshine path/to/sunshine.conf" -- If running for the first time, make sure to note the username and password Sunshine showed to you, since you **cannot get back later**! -- In Moonlight: Add PC manually -- When Moonlight request you insert the correct pin on sunshine: - - Type in the URL bar of your browser: `https://xxx.xxx.xxx.xxx:47990` where `xxx.xxx.xxx.xxx` is the IP address of your computer - - Ignore any warning given by your browser about "insecure website" - - You should compile the next page with a new username and a password, needed to login into the next step - - Press "Save" and log in using the credentials given above - - Go to "PIN" in the Header - - Type in your PIN and press Enter, you should get a Success Message -- Click on one of the Applications listed -- Have fun :) - -## Shortcuts: - -All shortcuts start with CTRL + ALT + SHIFT, just like Moonlight -- CTRL + ALT + SHIFT + N --> Hide/Unhide the cursor (This may be usefull for Remote Desktop Mode for Moonlight) -- CTRL + ALT + SHIFT + F1/F13 --> Switch to different monitor for Streaming - -## Credits: -- [Simple-Web-Server](https://gitlab.com/eidheim/Simple-Web-Server) -- [Moonlight](https://github.com/moonlight-stream) -- [Looking-Glass](https://github.com/gnif/LookingGlass) (For showing me how to properly capture frames on Windows, saving me a lot of time :) -- [Eretik](http://eretik.omegahg.com/) (For creating PolicyConfig.h, allowing me to change the default audio device on Windows programmatically) -- [Twitter emoji](https://github.com/twitter/twemoji/blob/master/LICENSE-GRAPHICS) (Sunshine's icon is made of twemoji) - -## Application List: -**Note:** You can change the Application List in the "Apps" section of the User Interface `https://xxx.xxx.xxx.xxx:47990/` -- You can use Environment variables in place of values - - $(HOME) will be replaced by the value of $HOME - - $$ will be replaced by $ --> $$(HOME) will be replaced by $(HOME) -- env: Adds or overwrites Environment variables for the commands/applications run by Sunshine. - - "Variable name":"Variable value" -- apps: The list of applications - - Example: - ```json - { - "name":"An App", - "cmd":"command to open app", - "prep-cmd":[ - { - "do":"some-command", - "undo":"undo-that-command" - } - ], - "detached":[ - "some-command", - "another-command" - ] - } - ``` - - name: Self explanatory - - output : The file where the output of the command is stored - - If it is not specified, the output is ignored - - detached: A list of commands to be run and forgotten about - - prep-cmd: A list of commands to be run before/after the application - - If any of the prep-commands fail, starting the application is aborted - - do: Run before the application - - If it fails, all 'undo' commands of the previously succeeded 'do' commands are run - - undo : Run after the application has terminated - - This should not fail considering it is supposed to undo the 'do' commands. - - If it fails, Sunshine is terminated - - cmd : The main application - - If not specified, a processs is started that sleeps indefinitely - -1. When an application is started, if there is an application already running, it will be terminated. -2. When the application has been shutdown, the stream shuts down as well. -3. In addition to the apps listed, one app "Desktop" is hardcoded into Sunshine. It does not start an application, instead it simply starts a stream. - -Linux -```json -{ - "env":{ - "DISPLAY":":0", - "DRI_PRIME":"1", - "XAUTHORITY":"$(HOME)/.Xauthority", - "PATH":"$(PATH):$(HOME)/.local/bin" - }, - "apps":[ - { - "name":"Low Res Desktop", - "prep-cmd":[ - { "do":"xrandr --output HDMI-1 --mode 1920x1080", "undo":"xrandr --output HDMI-1 --mode 1920x1200" } - ] - }, - { - "name":"Steam BigPicture", - - "output":"steam.txt", - "cmd":"steam -bigpicture", - "prep-cmd":[] - } - ] -} -``` -Windows -```json -{ - "env":{ - "PATH":"$(PATH);C:\\Program Files (x86)\\Steam" - }, - "apps":[ - { - "name":"Steam BigPicture", - - "output":"steam.txt", - "prep-cmd":[ - {"do":"steam \"steam://open/bigpicture\""} - ] - } - ] -} -``` diff --git a/README.rst b/README.rst new file mode 100644 index 0000000000..8fb29b6b35 --- /dev/null +++ b/README.rst @@ -0,0 +1,65 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/README.rst + +Overview +======== + +About +----- +Sunshine is a Game stream host for Moonlight. It is an open source version of GeForce Experience (GFE). + +These are the advantages of Sunshine over GFE. + + - FOSS (Free and Open Source Software) + - Multi-platform + + - Linux (deb, rpm, and AppImage packages) + - MacOS (Portfile) + - Windows (portable binary) + + - Pair over web ui + - Supports AMD and Nvidia GPUs for encoding + - Supports software encoding + - Supports streaming to multiple clients + - Web UI for configuration + +Integrations +------------ + +.. image:: https://img.shields.io/github/workflow/status/sunshinestream/sunshine/CI/master?label=CI%20build&logo=github&style=for-the-badge + :alt: GitHub Workflow Status (CI) + :target: https://github.com/SunshineStream/Sunshine/actions/workflows/CI.yml?query=branch%3Amaster + +.. image:: https://img.shields.io/github/workflow/status/sunshinestream/sunshine/localize/nightly?label=localize%20build&logo=github&style=for-the-badge + :alt: GitHub Workflow Status (localize) + :target: https://github.com/SunshineStream/Sunshine/actions/workflows/localize.yml?query=branch%3Anightly + +.. image:: https://img.shields.io/readthedocs/sunshinestream?label=Docs&style=for-the-badge&logo=readthedocs + :alt: Read the Docs + :target: http://sunshinestream.readthedocs.io/ + +.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=localized&style=for-the-badge&query=%24.progress..data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json&logo=crowdin + :alt: CrowdIn + :target: https://crowdin.com/project/sunshinestream + +Support +--------- + +.. image:: https://img.shields.io/discord/938534566107418705?label=Discord&style=for-the-badge&color=blue&logo=discord + :alt: Discord + :target: https://sunshinestream.github.io/discord + +.. image:: https://img.shields.io/github/discussions/sunshinestream/sunshine?logo=github&style=for-the-badge + :alt: GitHub Discussions + :target: https://github.com/SunshineStream/Sunshine/discussions + +Downloads +--------- + +.. image:: https://img.shields.io/github/downloads/sunshinestream/sunshine/total?style=for-the-badge&logo=github + :alt: GitHub Releases + :target: https://github.com/SunshineStream/Sunshine/releases/latest + +.. comment + image:: https://img.shields.io/docker/pulls/sunshinestream/sunshine?style=for-the-badge&logo=docker + :alt: Docker + :target: https://hub.docker.com/r/sunshinestream/sunshine diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 7fb08089e8..0000000000 --- a/appveyor.yml +++ /dev/null @@ -1,44 +0,0 @@ -services: - - docker - -environment: - matrix: - - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2004 - DOCKERFILE: Dockerfile-ubuntu_20_04 - - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2004 - DOCKERFILE: Dockerfile-ubuntu_21_04 - - APPVEYOR_BUILD_WORKER_IMAGE: Ubuntu2004 - DOCKERFILE: Dockerfile-debian - - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 - BUILD_TYPE: Release - -install: - - cmd: C:\msys64\usr\bin\bash -lc "pacman --needed --noconfirm -S mingw-w64-x86_64-binutils mingw-w64-x86_64-openssl mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-opus mingw-w64-x86_64-x265 mingw-w64-x86_64-boost git yasm nasm diffutils make" - -before_build: - - cmd: git submodule update --init --recursive - - cmd: mkdir build - - cmd: cd build - - sh: cd scripts - - sh: ./build-container.sh -f $DOCKERFILE - -build_script: - - cmd: set OLDPATH=%PATH% - - cmd: set PATH=C:\msys64\mingw64\bin - - cmd: cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DSUNSHINE_ASSETS_DIR=assets -G "MinGW Makefiles" .. - - cmd: mingw32-make -j2 - - cmd: set PATH=%OLDPATH% - - sh: ./build-sunshine.sh -pu - -after_build: - - cmd: Del ..\assets\apps_linux.json - - cmd: 7z a Sunshine-Windows.zip ..\assets - - cmd: 7z a Sunshine-Windows.zip sunshine.exe - - cmd: 7z a Sunshine-Windows.zip tools\dxgi-info.exe - - cmd: 7z a Sunshine-Windows.zip tools\audio-info.exe - - cmd: 7z a Sunshine-Windows.zip tools\sunshinesvc.exe - - cmd: 7z a Sunshine-Windows.zip ..\tools\install-service.bat - - cmd: 7z a Sunshine-Windows.zip ..\tools\uninstall-service.bat - - cmd: appveyor PushArtifact Sunshine-Windows.zip - - sh: appveyor PushArtifact sunshine-build/sunshine.deb - diff --git a/assets/sunshine.conf b/assets/sunshine.conf deleted file mode 100644 index a1e020f03c..0000000000 --- a/assets/sunshine.conf +++ /dev/null @@ -1,318 +0,0 @@ -# If no external IP address is given, Sunshine will attempt to automatically detect external ip-address -# external_ip = 123.456.789.12 - -# Set the familly of ports used by Sunshine -# port = 47989 - -# The private key must be 2048 bits -# pkey = /dir/pkey.pem - -# The certificate must be signed with a 2048 bit key -# cert = /dir/cert.pem - -# The name displayed by Moonlight -# If not specified, the PC's hostname is used -# sunshine_name = Sunshine - -# The minimum log level printed to standard out -# -# none -> no logs are printed to standard out -# -# verbose = [0] -# debug = [1] -# info = [2] -# warning = [3] -# error = [4] -# fatal = [5] -# none = [6] -# -# min_log_level = info - -# The origin of the remote endpoint address that is not denied for HTTP method /pin -# Could be any of the following values: -# pc|lan|wan -# pc: Only localhost may access /pin -# lan: Only those in LAN may access /pin -# wan: Anyone may access /pin -# -# origin_pin_allowed = pc - -# The origin of the remote endpoint address that is not denied for HTTPS Web UI -# Could be any of the following values: -# pc|lan|wan -# pc: Only localhost may access the Web Manager -# lan: Only those in LAN may access the Web Manager -# wan: Anyone may access the Web Manager -# -# origin_web_ui_allowed = lan - -# If UPnP is enabled, Sunshine will attempt to open ports for streaming over the internet -# To enable it, uncomment the following line: -# upnp = on - -# The file where current state of Sunshine is stored -# file_state = sunshine_state.json - -# The file where user credentials for the UI are stored -# By default, credentials are stored in `file_state` -# credentials_file = sunshine_state.json - -# The display modes advertised by Sunshine -# -# Some versions of Moonlight, such as Moonlight-nx (Switch), -# rely on this list to ensure that the requested resolutions and fps -# are supported. -# -# fps = [10, 30, 60, 90, 120] -# resolutions = [ -# 352x240, -# 480x360, -# 858x480, -# 1280x720, -# 1920x1080, -# 2560x1080, -# 3440x1440, -# 1920x1200, -# 3860x2160, -# 3840x1600, -# ] - -# Sometimes it may be usefull to map keybindings. -# Wayland won't allow clients to capture the Win Key for example -# -# See https://docs.microsoft.com/en-us/windows/win32/inputdev/virtual-key-codes -# -# Note: -# keybindings needs to have a multiple of two elements -# keybindings = [ -# 0x10, 0xA0, -# 0x11, 0xA2, -# 0x12, 0xA4, -# 0x4A, 0x4B -# ] - -# It may be possible that you cannot send the Windows Key from Moonlight directly. -# In those cases it may be useful to make Sunshine think the Right Alt key is the Windows key -# key_rightalt_to_key_win = enabled - -# How long to wait in milliseconds for data from moonlight before shutting down the stream -# ping_timeout = 10000 - -# The file where configuration for the different applications that Sunshine can run during a stream -# file_apps = apps.json - -# Percentage of error correcting packets per data packet in each video frame -# Higher values can correct for more network packet loss, but at the cost of increasing bandwidth usage -# The default value of 20 is what GeForce Experience uses -# -# The value must be greater than 0 and lower than or equal to 255 -# fec_percentage = 20 - -# When multicasting, it could be usefull to have different configurations for each connected Client. -# For example: -# Clients connected through WAN and LAN have different bitrate contstraints. -# Decoders may require different settings for color -# -# Unlike simply broadcasting to multiple Client, this will generate distinct video streams. -# Note, CPU usage increases for each distinct video stream generated -# channels = 1 - -# The back/select button on the controller -# On the Shield, the home and powerbutton are not passed to Moonlight -# If, after the timeout, the back button is still pressed down, Home/Guide button press is emulated. -# If back_button_timeout < 0, then the Home/Guide button will not be emulated -# back_button_timeout = 2000 - -# !! Windows only !! -# Gamepads supported by Sunshine -# Possible values: -# x360 -- xbox 360 controller -# ds4 -- dualshock controller (PS4) -# gamepad = x360 - -# Control how fast keys will repeat themselves -# The initial delay in milliseconds before repeating keys -# key_repeat_delay = 500 -# -# How often keys repeat every second -# This configurable option supports decimals -# key_repeat_frequency = 24.9 - -# The name of the audio sink used for Audio Loopback -# If you do not specify this variable, pulseaudio will select the default monitor device. -# -# You can find the name of the audio sink using the following command: -# !! Linux only !! -# pacmd list-sinks | grep "name:" if running vanilla pulseaudio -# pPipewire: Use `pactl info | grep Source`. In some causes you'd need to use the `sink` device. Try `pactl info | grep Sink`, if _Source_ doesn't work -# audio_sink = alsa_output.pci-0000_09_00.3.analog-stereo -# -# !! Windows only !! -# tools\audio-info.exe -# audio_sink = {0.0.0.00000000}.{FD47D9CC-4218-4135-9CE2-0C195C87405B} -# -# The virtual sink, is the audio device that's virtual (Like Steam Streaming Speakers), it allows Sunshine -# to stream audio, while muting the speakers. -# virtual_sink = {0.0.0.00000000}.{8edba70c-1125-467c-b89c-15da389bc1d4} - -# -# !! MacOS only !! -# audio_sink = BlackHole 2ch - -# !! Windows only !! -# You can select the video card you want to stream: -# The appropriate values can be found using the following command: -# tools\dxgi-info.exe -# adapter_name = Radeon RX 580 Series -# output_name = \\.\DISPLAY1 - -# !! Linux only !! -# Set the display number to stream. -# You can find them by the following command: -# xrandr --listmonitors -# Example output: "0: +HDMI-1 1920/518x1200/324+0+0 HDMI-1" -# ^ <-- You need this. -# output_name = 0 - -############################################### -# FFmpeg software encoding parameters -# Honestly, I have no idea what the optimal values would be. -# Play around with this :) - -# Quantitization Parameter -# Some devices don't support Constant Bit Rate. For those devices, QP is used instead -# Higher value means more compression, but less quality -# qp = 28 - -# Minimum number of threads used by ffmpeg to encode the video. -# Increasing the value slightly reduces encoding efficiency, but the tradeoff is usually -# worth it to gain the use of more CPU cores for encoding. The ideal value is the lowest -# value that can reliably encode at your desired streaming settings on your hardware. -# min_threads = 1 - -# Allows the client to request HEVC Main or HEVC Main10 video streams. -# HEVC is more CPU-intensive to encode, so enabling this may reduce performance when using software encoding. -# If set to 0 (default), Sunshine will specify support for HEVC based on encoder -# If set to 1, Sunshine will not advertise support for HEVC -# If set to 2, Sunshine will advertise support for HEVC Main profile -# If set to 3, Sunshine will advertise support for HEVC Main and Main10 (HDR) profiles -# hevc_mode = 2 - -# Force a specific encoder, otherwise Sunshine will use the first encoder that is available -# supported encoders: -# nvenc -# amdvce # NOTE: alpha stage. The cursor is not yet displayed -# software -# -# encoder = nvenc -##################################### Software ##################################### -# See x264 --fullhelp for the different presets -# sw_preset = superfast -# sw_tune = zerolatency -# - -##################################### NVENC ##################################### -###### presets ########### -# default -# hp -- high performance -# hq -- high quality -# slow -- hq 2 passes -# medium -- hq 1 pass -# fast -- hp 1 pass -# bd -# ll -- low latency -# llhq -# llhp -# lossless -# losslesshp -########################## -# nv_preset = llhq -# -####### rate control ##### -# auto -- let ffmpeg decide rate control -# constqp -- constant QP mode -# vbr -- variable bitrate -# cbr -- constant bitrate -# cbr_hq -- cbr high quality -# cbr_ld_hq -- cbr low delay high quality -# vbr_hq -- vbr high quality -########################## -# nv_rc = auto - -###### h264 entropy ###### -# auto -- let ffmpeg nvenc decide the entropy encoding -# cabac -# cavlc -########################## -# nv_coder = auto - -##################################### AMD ##################################### -###### presets ########### -# default -# speed -# balanced -########################## -# amd_quality = balanced -# -####### rate control ##### -# auto -- let ffmpeg decide rate control -# constqp -- constant QP mode -# vbr_latency -- Latency Constrained Variable Bitrate -# vbr_peak -- Peak Contrained Variable Bitrate -# cbr -- constant bitrate -########################## -# amd_rc = auto - -###### h264 entropy ###### -# auto -- let ffmpeg nvenc decide the entropy encoding -# cabac -# cavlc -########################## -# amd_coder = auto - -#################################### VAAPI ################################### -####### adapter ########## -# Unlike with `amdvce` and `nvenc`, it doesn't matter if video encoding is done -# on a different GPU. -# Run the following commands: -# 1. ls /dev/dri/renderD* -# to find all devices capable of VAAPI -# 2. vainfo --display drm --device /dev/dri/renderD129 | grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)|Driver version" -# Lists the name and capabilities of the device. -# To be supported by Sunshine, it needs to have at the very minimum: -# VAProfileH264High : VAEntrypointEncSlice -# adapter_name = /dev/dri/renderD128 - -################################# VideoToolbox ############################### -####### software encoding ########## -# Video Toolbox can be allowed/required to use software encoding instead of -# hardware accelerated encoding. -# auto -- let sunshine decide on encoding -# disabled -- disable software encoding -# allowed -- allow software encoding -# forced -- force software encoding -########################## -# vt_software = auto -# -####### realtime encoding ########## -# Disabling realtime encoding might result in a delayed frame encoding or frame drop -########################## -# vt_realtime = enabled -# -###### h264/hevc entropy ###### -# auto -- let ffmpeg decide the entropy encoding -# cabac -# cavlc -########################## -# vt_coder = auto - - -############################################## -# Some configurable parameters, are merely toggles for specific features -# The first occurrence turns it on, the second occurence turns it off, the third occurence turns it on again, etc, etc -# Here, you change the default state of any flag -# -# To set the initial state of flags -0 and -1 to on, set the following flags: -# flags = 012 -# -# See: sunshine --help for all options under the header: flags diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 0000000000..ca9c8c5c58 --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,21 @@ +"base_path": "." +"base_url": "https://api.crowdin.com" # optional (for Crowdin Enterprise only) +"preserve_hierarchy": false # flatten tree on crowdin +"pull_request_labels": [ + "crowdin", + "l10n" +] + +"files" : [ + { + "source" : "/locale/*.po", + "translation" : "/locale/%two_letters_code%/LC_MESSAGES/%original_file_name%", + "languages_mapping": { + "two_letters_code": { + # map non-two letter codes here, left side is crowdin designation, right side is babel designation + "en-GB": "en_GB", + "en-US": "en_US" + } + } + } +] diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000000..d0c3cbf102 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = source +BUILDDIR = build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000000..dc1312ab09 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=source +set BUILDDIR=build + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.https://www.sphinx-doc.org/ + exit /b 1 +) + +if "%1" == "" goto help + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/docs/source/about/advanced_usage.rst b/docs/source/about/advanced_usage.rst new file mode 100644 index 0000000000..e090322345 --- /dev/null +++ b/docs/source/about/advanced_usage.rst @@ -0,0 +1,1111 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/about/advanced_usage.rst + +Advanced Usage +============== +Sunshine will work with the default settings for most users. In some cases you may want to configure Sunshine further. + +Configuration +------------- +The default location for the configuration file is listed below. You can use another location if you +choose, by passing in the full configuration file path as the first argument when you start Sunshine. + +The default location of the ``apps.json`` is the same as the configuration file. You can use a custom +location by modifying the configuration file. + +**Default File Location** + +.. table:: + :widths: auto + + ======= =========== + Value Description + ======= =========== + Docker /config/ + Linux /usr/local/sunshine/config/ + MacOS /usr/local/sunshine/config/ + Windows ./config/ + ======= =========== + +Example + .. code-block:: bash + + sunshine ~/sunshine_config.conf + +To manually configure sunshine you may edit the `conf` file in a text editor. Use the examples as reference. + +.. Hint:: Some settings are not available within the web ui. + +General +------- + +sunshine_name +^^^^^^^^^^^^^ + +Description + The name displayed by Moonlight + +Default + PC hostname + +Example + .. code-block:: text + + sunshine_name = Sunshine + +min_log_level +^^^^^^^^^^^^^ + +Description + The minimum log level printed to standard out. + +**Choices** + +.. table:: + :widths: auto + + ======= =========== + Value Description + ======= =========== + verbose verbose logging + debug debug logging + info info logging + warning warning logging + error error logging + fatal fatal logging + none no logging + ======= =========== + +Default + ``info`` + +Example + .. code-block:: text + + min_log_level = info + +Controls +-------- + +gamepad +^^^^^^^ + +Description + The type of gamepad to emulate on the host. + + .. Caution:: Applies to Windows only. + +**Choices** + +.. table:: + :widths: auto + + ===== =========== + Value Description + ===== =========== + x360 xbox 360 controller + ds4 dualshock controller (PS4) + ===== =========== + +Default + ``x360`` + +Example + .. code-block:: text + + gamepad = x360 + +back_button_timeout +^^^^^^^^^^^^^^^^^^^ + +Description + If, after the timeout, the back/select button is still pressed down, Home/Guide button press is emulated. + + On Nvidia Shield, the home and power button are not passed to Moonlight. + + .. Tip:: If back_button_timeout < 0, then the Home/Guide button will not be emulated. + +Default + ``2000`` + +Example + .. code-block:: text + + back_button_timeout = 2000 + +key_repeat_delay +^^^^^^^^^^^^^^^^ + +Description + The initial delay in milliseconds before repeating keys. Controls how fast keys will repeat themselves. + +Default + ``500`` + +Example + .. code-block:: text + + key_repeat_delay = 500 + +key_repeat_frequency +^^^^^^^^^^^^^^^^^^^^ + +Description + How often keys repeat every second. + + .. Tip:: This configurable option supports decimals. + +Default + .. Todo:: Unknown + +Example + .. code-block:: text + + key_repeat_frequency = 24.9 + +keybindings +^^^^^^^^^^^ + +Description + Sometimes it may be useful to map keybindings. Wayland won't allow clients to capture the Win Key for example. + + .. Tip:: See `virtual key codes `_ + + .. Hint:: keybindings needs to have a multiple of two elements. + +Default + None + +Example + .. code-block:: text + + keybindings = [ + 0x10, 0xA0, + 0x11, 0xA2, + 0x12, 0xA4, + 0x4A, 0x4B + ] + +key_rightalt_to_key_win +^^^^^^^^^^^^^^^^^^^^^^^ + +Description + It may be possible that you cannot send the Windows Key from Moonlight directly. In those cases it may be useful to + make Sunshine think the Right Alt key is the Windows key. + +Default + None + +Example + .. code-block:: text + + key_rightalt_to_key_win = enabled + +Display +------- + +adapter_name +^^^^^^^^^^^^ + +Description + Select the video card you want to stream. + + .. Tip:: To find the name of the appropriate values follow these instructions. + + Linux + VA-API + Unlike with `amdvce` and `nvenc`, it doesn't matter if video encoding is done on a different GPU. + + .. code-block:: bash + + ls /dev/dri/renderD* # to find all devices capable of VAAPI + + # replace ``renderD129`` with the device from above to lists the name and capabilities of the device + vainfo --display drm --device /dev/dri/renderD129 | \ + grep -E "((VAProfileH264High|VAProfileHEVCMain|VAProfileHEVCMain10).*VAEntrypointEncSlice)|Driver version" + + To be supported by Sunshine, it needs to have at the very minimum: + ``VAProfileH264High : VAEntrypointEncSlice`` + + .. Todo:: MacOS + + Windows + .. code-block:: batch + + tools\dxgi-info.exe + +Default + Sunshine will select the default video card. + +Examples + Linux + .. code-block:: text + + adapter_name = /dev/dri/renderD128 + + .. Todo:: MacOS + + Windows + .. code-block:: text + + adapter_name = Radeon RX 580 Series + +output_name +^^^^^^^^^^^ + +Description + Select the display number you want to stream. + + .. Tip:: To find the name of the appropriate values follow these instructions. + + Linux + .. code-block:: bash + + xrandr --listmonitors + + Example output: ``0: +HDMI-1 1920/518x1200/324+0+0 HDMI-1`` + + You need to use the value before the colon in the output, e.g. ``0``. + + .. Todo:: MacOS + + Windows + .. code-block:: batch + + tools\dxgi-info.exe + +Default + Sunshine will select the default display. + +Examples + Linux + .. code-block:: text + + output_name = 0 + + .. Todo:: MacOS + + Windows + .. code-block:: text + + output_name = \\.\DISPLAY1 + +fps +^^^ + +Description + The fps modes advertised by Sunshine. + + .. Note:: Some versions of Moonlight, such as Moonlight-nx (Switch), rely on this list to ensure that the requested + fps is supported. + +Default + .. Todo:: Unknown + +Example + .. code-block:: text + + fps = [10, 30, 60, 90, 120] + +resolutions +^^^^^^^^^^^ + +Description + The resolutions advertised by Sunshine. + + .. Note:: Some versions of Moonlight, such as Moonlight-nx (Switch), rely on this list to ensure that the requested + resolution is supported. + +Default + .. Todo:: Unknown + +Example + .. code-block:: text + + resolutions = [ + 352x240, + 480x360, + 858x480, + 1280x720, + 1920x1080, + 2560x1080, + 3440x1440, + 1920x1200, + 3860x2160, + 3840x1600, + ] + +dwmflush +^^^^^^^^ + +Description + Invoke DwmFlush() to sync screen capture to the Windows presentation interval. + + .. Caution:: Applies to Windows only. Alleviates visual stuttering during mouse movement. + If enabled, this feature will automatically deactivate if the client framerate exceeds + the host monitor's current refresh rate. + +Default + ``enabled`` + +Examples + + Windows + .. code-block:: text + + dwmflush = enabled + +Audio +----- + +audio_sink +^^^^^^^^^^ + +Description + The name of the audio sink used for audio loopback. + + .. Tip:: To find the name of the audio sink follow these instructions. + + Linux + pulseaudio + .. code-block:: bash + + pacmd list-sinks | grep "name:" + + Linux + pipewire + .. code-block:: bash + + pactl info | grep Source + # in some causes you'd need to use the `Sink` device, if `Source` doesn't work, so try: + pactl info | grep Sink + + MacOS + Sunshine can only access microphones on MacOS due to system limitations. To stream system audio use + `Soundflower `_ or + `BlackHole `_. + + Windows + .. code-block:: batch + + tools\audio-info.exe + +Default + Sunshine will select the default audio device. + +Examples + Linux + .. code-block:: text + + audio_sink = alsa_output.pci-0000_09_00.3.analog-stereo + + MacOS + .. code-block:: text + + audio_sink = BlackHole 2ch + + Windows + .. code-block:: text + + audio_sink = {0.0.0.00000000}.{FD47D9CC-4218-4135-9CE2-0C195C87405B} + +virtual_sink +^^^^^^^^^^^^ + +Description + The audio device that's virtual, like Steam Streaming Speakers. This allows Sunshine to stream audio, while muting + the speakers. + + .. Tip:: See `audio_sink`_! + +Default + .. Todo:: Unknown + +Example + .. code-block:: text + + virtual_sink = {0.0.0.00000000}.{8edba70c-1125-467c-b89c-15da389bc1d4} + +Network +------- + +external_ip +^^^^^^^^^^^ + +Description + If no external IP address is given, Sunshine will attempt to automatically detect external ip-address. + +Default + Automatic + +Example + .. code-block:: text + + external_ip = 123.456.789.12 + +port +^^^^ + +Description + Set the family of ports used by Sunshine. + +Default + ``47989`` + +Example + .. code-block:: text + + port = 47989 + +pkey +^^^^ + +Description + The private key. This must be 2048 bits. + +Default + .. Todo:: Unknown + +Example + .. code-block:: text + + pkey = /dir/pkey.pem + +cert +^^^^ + +Description + The certificate. Must be signed with a 2048 bit key. + +Default + .. Todo:: Unknown + +Example + .. code-block:: text + + cert = /dir/cert.pem + +origin_pin_allowed +^^^^^^^^^^^^^^^^^^ + +Description + The origin of the remote endpoint address that is not denied for HTTP method /pin. + +**Choices** + +.. table:: + :widths: auto + + ===== =========== + Value Description + ===== =========== + pc Only localhost may access /pin + lan Only LAN devices may access /pin + wan Anyone may access /pin + ===== =========== + +Default + ``pc`` + +Example + .. code-block:: text + + origin_pin_allowed = pc + +origin_web_ui_allowed +^^^^^^^^^^^^^^^^^^^^^ + +Description + The origin of the remote endpoint address that is not denied for HTTPS Web UI. + +**Choices** + +.. table:: + :widths: auto + + ===== =========== + Value Description + ===== =========== + pc Only localhost may access the web ui + lan Only LAN devices may access the web ui + wan Anyone may access the web ui + ===== =========== + +Default + ``lan`` + +Example + .. code-block:: text + + origin_web_ui_allowed = lan + +upnp +^^^^ + +Description + Sunshine will attempt to open ports for streaming over the internet. + +**Choices** + +.. table:: + :widths: auto + + ===== =========== + Value Description + ===== =========== + on enable UPnP + off disable UPnP + ===== =========== + +Default + ``off`` + +Example + .. code-block:: text + + upnp = on + +ping_timeout +^^^^^^^^^^^^ + +Description + How long to wait in milliseconds for data from Moonlight before shutting down the stream. + +Default + ``10000`` + +Example + .. code-block:: text + + ping_timeout = 10000 + +Encoding +-------- + +channels +^^^^^^^^ + +Description + This will generate distinct video streams, unlike simply broadcasting to multiple Clients. + + When multicasting, it could be useful to have different configurations for each connected Client. + + For instance: + + - Clients connected through WAN and LAN have different bitrate constraints. + - Decoders may require different settings for color. + + .. Warning:: CPU usage increases for each distinct video stream generated. + +Default + ``1`` + +Example + .. code-block:: text + + channels = 1 + +fec_percentage +^^^^^^^^^^^^^^ + +Description + Percentage of error correcting packets per data packet in each video frame. + + .. Warning:: Higher values can correct for more network packet loss, but at the cost of increasing bandwidth usage. + +Default + ``20`` + +Range + ``1-255`` + +Example + .. code-block:: text + + fec_percentage = 20 + +qp +^^ + +Description + Quantitization Parameter. Some devices don't support Constant Bit Rate. For those devices, QP is used instead. + + .. Warning:: Higher value means more compression, but less quality. + +Default + ``28`` + +Example + .. code-block:: text + + qp = 28 + +min_threads +^^^^^^^^^^^ + +Description + Minimum number of threads used by ffmpeg to encode the video. + + .. Note:: Increasing the value slightly reduces encoding efficiency, but the tradeoff is usually worth it to gain + the use of more CPU cores for encoding. The ideal value is the lowest value that can reliably encode at your + desired streaming settings on your hardware. + +Default + ``1`` + +Example + .. code-block:: text + + min_threads = 1 + +hevc_mode +^^^^^^^^^ + +Description + Allows the client to request HEVC Main or HEVC Main10 video streams. + + .. Warning:: HEVC is more CPU-intensive to encode, so enabling this may reduce performance when using software + encoding. + +**Choices** + +.. table:: + :widths: auto + + ===== =========== + Value Description + ===== =========== + 0 advertise support for HEVC based on encoder + 1 do not advertise support for HEVC + 2 advertise support for HEVC Main profile + 3 advertise support for HEVC Main and Main10 (HDR) profiles + ===== =========== + +Default + ``0`` + +Example + .. code-block:: text + + hevc_mode = 2 + +encoder +^^^^^^^ + +Description + Force a specific encoder. + +**Choices** + +.. table:: + :widths: auto + + ======== =========== + Value Description + ======== =========== + nvenc For Nvidia graphics cards + amdvce For AMD graphics cards + software Encoding occurs on the CPU + ======== =========== + +Default + Sunshine will use the first encoder that is available. + +Example + .. code-block:: text + + encoder = nvenc + +sw_preset +^^^^^^^^^ + +Description + The encoder preset to use. + + .. Note:: This option only applies when using software `encoder`_. + + .. Note:: From `FFmpeg `_. + + A preset is a collection of options that will provide a certain encoding speed to compression ratio. A slower + preset will provide better compression (compression is quality per filesize). This means that, for example, if + you target a certain file size or constant bit rate, you will achieve better quality with a slower preset. + Similarly, for constant quality encoding, you will simply save bitrate by choosing a slower preset. + + Use the slowest preset that you have patience for. + +**Choices** + +.. table:: + :widths: auto + + ========= =========== + Value Description + ========= =========== + ultrafast fastest + superfast + veryfast + superfast + faster + fast + medium + slow + slow + slower + veryslow slowest + ========= =========== + +Default + ``superfast`` + +Example + .. code-block:: text + + sw_preset = superfast + +sw_tune +^^^^^^^ + +Description + The tuning preset to use. + + .. Note:: This option only applies when using software `encoder`_. + + .. Note:: From `FFmpeg `_. + + You can optionally use -tune to change settings based upon the specifics of your input. + +**Choices** + +.. table:: + :widths: auto + + =========== =========== + Value Description + =========== =========== + film use for high quality movie content; lowers deblocking + animation good for cartoons; uses higher deblocking and more reference frames + grain preserves the grain structure in old, grainy film material + stillimage good for slideshow-like content + fastdecode allows faster decoding by disabling certain filters + zerolatency good for fast encoding and low-latency streaming + =========== =========== + +Default + ``zerolatency`` + +Example + .. code-block:: text + + sw_tune = zerolatency + +nv_preset +^^^^^^^^^ + +Description + The encoder preset to use. + + .. Note:: This option only applies when using nvenc `encoder`_. + +**Choices** + +.. table:: + :widths: auto + + ========== =========== + Value Description + ========== =========== + default let ffmpeg decide + hp high performance + hq high quality + slow high quality, 2 passes + medium high quality, 1 pass + fast high performance, 1 pass + bd + ll low latency + llhq low latency, high quality + llhp low latency, high performance + lossless lossless + losslesshp lossless, high performance + ========== =========== + +Default + ``llhq`` + +Example + .. code-block:: text + + nv_preset = llhq + +nv_rc +^^^^^ + +Description + The encoder rate control. + + .. Note:: This option only applies when using nvenc `encoder`_. + + .. Note:: Moonlight does not currently support variable bitrate, although it can still be selected here. + +**Choices** + +.. table:: + :widths: auto + + ========== =========== + Value Description + ========== =========== + auto let ffmpeg decide + constqp constant QP mode + cbr constant bitrate + cbr_hq constant bitrate, high quality + cbr_ld_hq constant bitrate, low delay, high quality + vbr variable bitrate + vbr_hq variable bitrate, high quality + ========== =========== + +Default + ``auto`` + +Example + .. code-block:: text + + nv_rc = auto + +nv_coder +^^^^^^^^ + +Description + The entropy encoding to use. + + .. Note:: This option only applies when using nvenc `encoder`_. + +**Choices** + +.. table:: + :widths: auto + + ========== =========== + Value Description + ========== =========== + auto let ffmpeg decide + cabac + cavlc + ========== =========== + +Default + ``auto`` + +Example + .. code-block:: text + + nv_coder = auto + +amd_quality +^^^^^^^^^^^ + +Description + The encoder preset to use. + + .. Note:: This option only applies when using amdvce `encoder`_. + +**Choices** + +.. table:: + :widths: auto + + ========== =========== + Value Description + ========== =========== + default let ffmpeg decide + speed fast + balanced balance performance and speed + ========== =========== + +Default + ``balanced`` + +Example + .. code-block:: text + + amd_quality = balanced + +amd_rc +^^^^^^ + +Description + The encoder rate control. + + .. Note:: This option only applies when using amdvce `encoder`_. + + .. Note:: Moonlight does not currently support variable bitrate, although it can still be selected here. + +**Choices** + +.. table:: + :widths: auto + + =========== =========== + Value Description + =========== =========== + auto let ffmpeg decide + constqp constant QP mode + cbr constant bitrate + vbr_latency variable bitrate, latency constrained + vbr_peak variable bitrate, peak constrained + =========== =========== + +Default + ``auto`` + +Example + .. code-block:: text + + amd_rc = auto + +amd_coder +^^^^^^^^^ + +Description + The entropy encoding to use. + + .. Note:: This option only applies when using nvenc `encoder`_. + +**Choices** + +.. table:: + :widths: auto + + ========== =========== + Value Description + ========== =========== + auto let ffmpeg decide + cabac + cavlc + ========== =========== + +Default + ``auto`` + +Example + .. code-block:: text + + amd_coder = auto + +vt_software +^^^^^^^^^^^ + +Description + Force Video Toolbox to use software encoding. + + .. Note:: This option only applies when using MacOS. + +**Choices** + +.. table:: + :widths: auto + + ========== =========== + Value Description + ========== =========== + auto let ffmpeg decide + disabled disable software encoding + allowed allow software encoding + forced force software encoding + ========== =========== + +Default + ``auto`` + +Example + .. code-block:: text + + vt_software = auto + +vt_realtime +^^^^^^^^^^^ + +Description + Realtime encoding. + + .. Note:: This option only applies when using MacOS. + + .. Warning:: Disabling realtime encoding might result in a delayed frame encoding or frame drop. + +Default + ``enabled`` + +Example + .. code-block:: text + + vt_realtime = enabled + +vt_coder +^^^^^^^^ + +Description + The entropy encoding to use. + + .. Note:: This option only applies when using MacOS. + +**Choices** + +.. table:: + :widths: auto + + ========== =========== + Value Description + ========== =========== + auto let ffmpeg decide + cabac + cavlc + ========== =========== + +Default + ``auto`` + +Example + .. code-block:: text + + vt_coder = auto + +Advanced +-------- + +file_apps +^^^^^^^^^ + +Description + The application configuration file path. The file contains a json formatted list of applications that can be started + by Moonlight. + +Default + OS and package dependent + +Example + .. code-block:: text + + file_apps = apps.json + +file_state +^^^^^^^^^^ + +Description + The file where current state of Sunshine is stored. + +Default + ``sunshine_state.json`` + +Example + .. code-block:: text + + file_state = sunshine_state.json + +credentials_file +^^^^^^^^^^^^^^^^ + +Description + The file where user credentials for the UI are stored. + +Default + ``sunshine_state.json`` + +Example + .. code-block:: text + + credentials_file = sunshine_state.json diff --git a/docs/source/about/docker.rst b/docs/source/about/docker.rst new file mode 100644 index 0000000000..f9afa25191 --- /dev/null +++ b/docs/source/about/docker.rst @@ -0,0 +1,5 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/DOCKER_README.md + +.. Todo:: This is a planned feature. Currently no Dockerfile or image exists for Sunshine. + +.. mdinclude:: ../../../DOCKER_README.md diff --git a/docs/source/about/installation.rst b/docs/source/about/installation.rst new file mode 100644 index 0000000000..2176206a85 --- /dev/null +++ b/docs/source/about/installation.rst @@ -0,0 +1,127 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/about/installation.rst + +Installation +============ +The recommended method for running Sunshine is to use the `binaries`_ bundled with the `latest release`_. + +Binaries +-------- +Binaries of Sunshine are created for each release. They are available for Linux, and Windows. +Binaries can be found in the `latest release`_. + +.. Todo:: Create binary package(s) for MacOS. See `here `_. + +.. Tip:: Some third party packages also exist. See + :ref:`Third Party Packages `. + +Docker +------ +.. Todo:: Docker images of Sunshine are planned to be included in the future. + They will be available on `Dockerhub.io`_ and `ghcr.io`_. + +Linux +----- +Follow the instructions for your preferred package type below. + +AppImage +^^^^^^^^ +.. image:: https://img.shields.io/github/issues/sunshinestream/sunshine/pkg:appimage?logo=github&style=for-the-badge + :alt: GitHub issues by-label + +The current known compatibility of the AppImage is shown below. + + - [✖] Debian oldstable (buster) + - [✔] Debian stable (bullseye) + - [✔] Debian testing (bookworm) + - [✔] Debian unstable (sid) + - [✔] Ubuntu jammy + - [✔] Ubuntu impish + - [✔] Ubuntu focal + - [✖] Ubuntu bionic + - [✖] Ubuntu xenial + - [✖] Ubuntu trusty + - [✖] CentOS 7 + +#. Download and extract ``sunshine-appimage.zip`` to your home directory. + +Debian Packages +^^^^^^^^^^^^^^^ +.. image:: https://img.shields.io/github/issues/sunshinestream/sunshine/os:linux:debian?logo=github&style=for-the-badge + :alt: GitHub issues by-label + +#. Download ``sunshine.deb`` and run the following code. + + .. code-block:: bash + + sudo apt install -f ./sunshine.deb + +.. Tip:: You can double click the deb file to see details about the package and begin installation. + +Red Hat Packages +^^^^^^^^^^^^^^^^ +.. image:: https://img.shields.io/github/issues/sunshinestream/sunshine/os:linux:fedora?logo=github&style=for-the-badge + :alt: GitHub issues by-label + +#. Add `rpmfusion` repositories by running the following code. + + .. code-block:: bash + + sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \ + https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm + +#. Download ``sunshine.rpm`` and run the following code. + + .. code-block:: bash + + sudo dnf install ./sunshine.rpm + +.. Tip:: You can double click the rpm file to see details about the package and begin installation. + +MacOS +----- +.. image:: https://img.shields.io/github/issues/sunshinestream/sunshine/os:macos?logo=github&style=for-the-badge + :alt: GitHub issues by-label + +Portfile + #. Install `MacPorts `_ + #. Update the Macports sources. + + .. code-block:: bash + + sudo nano /opt/local/etc/macports/sources.conf + + Add this line, replacing your username, below the line that starts with ``rsync``. + + file://Users//ports + + ``Ctrl+x``, then ``Y`` to exit and save changes. + + #. Download the ``Portfile`` to ``~/Downloads`` and run the following code. + + .. code-block:: bash + + mkdir -p ~/ports/multimedia/sunshine + mv ~/Downlaods/Portfile ~/ports/multimedia/sunshine + cd ~/ports + portindex + sudo port install sunshine + + #. The first time you start Sunshine, you will be asked to grant access to screen recording and your microphone. + +Windows +------- +.. image:: https://img.shields.io/github/issues/sunshinestream/sunshine/os:windows:10?logo=github&style=for-the-badge + :alt: GitHub issues by-label + +.. image:: https://img.shields.io/github/issues/sunshinestream/sunshine/os:windows:11?logo=github&style=for-the-badge + :alt: GitHub issues by-label + +Installed option: + #. Download and install ``sunshine-windows.exe`` + +Standalone option: + #. Download and extract ``sunshine-windows.zip`` + +.. _latest release: https://github.com/SunshineStream/Sunshine/releases/latest +.. _Dockerhub.io: https://hub.docker.com/repository/docker/sunshinestream/sunshine +.. _ghcr.io: https://github.com/orgs/SunshineStream/packages?repo_name=sunshine diff --git a/docs/source/about/overview.rst b/docs/source/about/overview.rst new file mode 100644 index 0000000000..e4a3ad51c7 --- /dev/null +++ b/docs/source/about/overview.rst @@ -0,0 +1 @@ +.. include:: ../../../README.rst diff --git a/docs/source/about/third_party_packages.rst b/docs/source/about/third_party_packages.rst new file mode 100644 index 0000000000..5b63a496bd --- /dev/null +++ b/docs/source/about/third_party_packages.rst @@ -0,0 +1,57 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/about/third_party_packages.rst + +Third Party Packages +==================== + +.. Danger:: These packages are not maintained by SunshineStream. Use at your own risk. + +AUR (Arch Linux User Repository) +-------------------------------- + +.. image:: https://img.shields.io/aur/version/sunshine?style=for-the-badge&logo=archlinux + :alt: AUR version + :target: https://aur.archlinux.org/packages/sunshine + +.. image:: https://img.shields.io/aur/last-modified/sunshine?style=for-the-badge&logo=archlinux + :alt: AUR last modified + +.. image:: https://img.shields.io/aur/votes/sunshine?style=for-the-badge&logo=archlinux + :alt: AUR votes + +.. image:: https://img.shields.io/aur/maintainer/sunshine?style=for-the-badge&logo=archlinux + :alt: AUR maintainer + +Chocolatey +---------- + +.. image:: https://img.shields.io/chocolatey/v/Sunshine?style=for-the-badge&logo=chocolatey + :alt: Chocolatey Version + :target: https://community.chocolatey.org/packages/sunshine + +.. image:: https://img.shields.io/chocolatey/dt/sunshine?style=for-the-badge&logo=chocolatey + :alt: Chocolatey + +Scoop +----- + +.. image:: https://img.shields.io/scoop/v/sunshine?bucket=extras&style=for-the-badge + :alt: Scoop Version (extras bucket) + :target: https://scoop.sh/#/apps?s=0&d=1&o=true&q=sunshine + +Legacy GitHub Repo +------------------ + +.. Attention:: This repo is not maintained. Thank you to Loki for bringing this amazing project to life! + +.. image:: https://img.shields.io/static/v1?label=repo&message=loki-47-6F-64/sunshine&color=blue&style=for-the-badge&logo=github + :alt: GitHub Maintainer + :target: https://github.com/loki-47-6F-64/sunshine/releases + +.. image:: https://img.shields.io/github/last-commit/loki-47-6F-64/sunshine?style=for-the-badge&logo=github + :alt: GitHub last commit + +.. image:: https://img.shields.io/github/release-date/loki-47-6F-64/sunshine?style=for-the-badge&logo=github + :alt: GitHub Release Date + +.. image:: https://img.shields.io/github/downloads/loki-47-6F-64/sunshine/total?style=for-the-badge&logo=github + :alt: GitHub Releases diff --git a/docs/source/about/usage.rst b/docs/source/about/usage.rst new file mode 100644 index 0000000000..79d285f9cf --- /dev/null +++ b/docs/source/about/usage.rst @@ -0,0 +1,215 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/about/usage.rst + +Usage +===== +#. See the `setup`_ section for your specific OS. +#. Run ``sunshine /sunshine.conf``. + + .. Note:: You do not need to specify a config file. If no config file is entered the default location will be used. + + .. Attention:: The configuration file specified will be created if it doesn't exist. + + .. Tip:: If using the Linux AppImage, replace ``sunshine`` with ``./sunshine.AppImage`` + +#. Configure Sunshine in the web ui + The web ui is available on `https://localhost:47990 `_ by default. You may replace + `localhost` with your internal ip address. + + .. Attention:: Ignore any warning given by your browser about "insecure website". + + .. Caution:: If running for the first time, make sure to note the username and password Sunshine showed to you, + since you cannot get back later! + + Add games and applications. + This can be configured in the web ui. + + .. Note:: Additionally, apps can be configured manually. `src_assets//config/apps.json` is an example of a + list of applications that are started just before running a stream. This is the directory within the GitHub + repo. + + .. Attention:: Application list is not fully supported on MacOS + +#. In Moonlight, you may need to add the PC manually. +#. When Moonlight request you insert the correct pin on sunshine: + + - Login to the web ui + - Go to "PIN" in the Header + - Type in your PIN and press Enter, you should get a Success Message + - In Moonlight, select one of the Applications listed + +Network +------- +Sunshine will be available on port 47990 by default. + +.. Danger:: Do not expose port 47990, or the web ui, to the internet! + +Arguments +--------- +To get a list of available arguments run the following: + + .. code-block:: bash + + sunshine --help + +Setup +----- + +Linux +^^^^^ +The deb and rpm packages handle these steps automatically. The AppImage does not, third party packages may not as well. + +Sunshine needs access to `uinput` to create mouse and gamepad events. + +Add user to group `input`, if this is the first time installing. + .. code-block:: bash + + sudo usermod -a -G input $USER + sudo reboot now + +Create `udev` rules. + .. code-block:: bash + + sudo nano /etc/udev/rules.d/85-sunshine-input.rules + + Input the following contents. + + .. code-block:: + + KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput" + + Save the file and exit: + + #. ``CTRL+X`` to start exit. + #. ``Y`` to save modifications. + +Configure autostart service + - filename: ``~/.config/systemd/user/sunshine.service`` + - contents: + + .. code-block:: + + [Unit] + Description=Sunshine Gamestream Server for Moonlight + + [Service] + ExecStart= + + [Install] + WantedBy=graphical-session.target + + .. table:: + :widths: auto + + ======== =================== =============== + package ExecStart Auto Configured + ======== =================== =============== + deb /usr/bin/sunshine ✔ + rpm /usr/bin/sunshine ✔ + AppImage ~/sunshine.AppImage ✖ + ======== =================== =============== + + Start once + .. code-block:: bash + + systemctl --user start sunshine + + Start on boot + .. code-block:: bash + + systemctl --user enable sunshine + +Additional Setup for KMS + .. Note:: ``cap_sys_admin`` may as well be root, except you don't need to be root to run it. It is necessary to + allow Sunshine to use KMS. + + Enable + .. code-block:: bash + + sudo setcap cap_sys_admin+p $(readlink -f $(which sunshine)) + + Disable + .. code-block:: bash + + sudo setcap -r $(readlink -f $(which sunshine)) + +MacOS +^^^^^ +Sunshine can only access microphones on macOS due to system limitations. To stream system audio use +`Soundflower `_ or +`BlackHole `_ and +select their sink as audio device in `sunshine.conf`. + +.. Note:: Command Keys are not forwarded by Moonlight. Right Option-Key is mapped to CMD-Key. + +.. Caution:: Gamepads are not currently supported. + +Configure autostart service + + MacPorts + .. code-block:: bash + + sudo port load Sunshine + +Windows +^^^^^^^ +For gamepad support, install `ViGEmBus `_ + +Shortcuts +--------- +All shortcuts start with CTRL + ALT + SHIFT, just like Moonlight + + - ``CTRL + ALT + SHIFT + N`` - Hide/Unhide the cursor (This may be useful for Remote Desktop Mode for Moonlight) + - ``CTRL + ALT + SHIFT + F1/F13`` - Switch to different monitor for Streaming + +Application List +---------------- +- You can use Environment variables in place of values +- ``$(HOME)`` will be replaced by the value of ``$HOME`` +- ``$$`` will be replaced by ``$``, e.g. ``$$(HOME)`` will be replaced by ``$(HOME)`` +- ``env`` - Adds or overwrites Environment variables for the commands/applications run by Sunshine +- ``"Variable name":"Variable value"`` +- ``apps`` - The list of applications +- Example application: + + .. code-block:: json + + { + "name":"An App", + "cmd":"command to open app", + "prep-cmd":[ + { + "do":"some-command", + "undo":"undo-that-command" + } + ], + "detached":[ + "some-command", + "another-command" + ] + } + + - ``name`` - The name of the application/game + - ``output`` - The file where the output of the command is stored + - ``detached`` - A list of commands to be run and forgotten about + - ``prep-cmd`` - A list of commands to be run before/after the application + + - If any of the prep-commands fail, starting the application is aborted + - ``do`` - Run before the application + + - If it fails, all ``undo`` commands of the previously succeeded ``do`` commands are run + + - ``undo`` - Run after the application has terminated + + - This should not fail considering it is supposed to undo the ``do`` commands + - If it fails, Sunshine is terminated + + - ``cmd`` - The main application + + - If not specified, a process is started that sleeps indefinitely + +Considerations +-------------- +- When an application is started, if there is an application already running, it will be terminated. +- When the application has been shutdown, the stream shuts down as well. +- In addition to the apps listed, one app "Desktop" is hardcoded into Sunshine. It does not start an application, + instead it simply starts a stream. diff --git a/docs/source/building/build.rst b/docs/source/building/build.rst new file mode 100644 index 0000000000..cd83cb1403 --- /dev/null +++ b/docs/source/building/build.rst @@ -0,0 +1,35 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/building/build.rst + +Build +===== +Sunshine binaries are built using `CMake `_. Cross compilation is not +supported. That means the binaries must be built on the target operating system and architecture. + +Building Locally +---------------- + +Clone +^^^^^ +Ensure `git `_ is installed and run the following: + + .. code-block:: bash + + git clone https://github.com/sunshinestream/sunshine.git --recurse-submodules + cd sunshine && mkdir build && cd build + +Compile +^^^^^^^ +See the section specific to your OS. + +- :ref:`Linux ` +- :ref:`MacOS ` +- :ref:`Windows ` + +Remote Build +------------ +It may be beneficial to build remotely in some cases. This will enable easier building on different operating systems. + +#. Fork the project +#. Activate workflows +#. Trigger the `CI` workflow manually +#. Download the artifacts/binaries from the workflow run summary diff --git a/docs/source/building/linux.rst b/docs/source/building/linux.rst new file mode 100644 index 0000000000..475e0c6696 --- /dev/null +++ b/docs/source/building/linux.rst @@ -0,0 +1,302 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/building/linux.rst + +Linux +===== + +Requirements +------------ +.. Danger:: Installing these dependencies may break your distribution. It is recommended to build in a virtual machine + or to use the `Dockerfile builds`_ located in the `./scripts` directory. + +Debian Bullseye +^^^^^^^^^^^^^^^ +End of Life: TBD + +Install Requirements + .. code-block:: bash + + sudo apt update && sudo apt install \ + build-essential \ + cmake \ + git \ + libavdevice-dev \ + libboost-filesystem-dev \ + libboost-log-dev \ + libboost-thread-dev \ + libcap-dev \ # KMS + libdrm-dev \ # KMS + libevdev-dev \ + libpulse-dev \ + libopus-dev \ + libssl-dev \ + libwayland-dev \ # Wayland + libx11-dev \ # X11 + libxcb-shm0-dev \ # X11 + libxcb-xfixes0-dev \ # X11 + libxcb1-dev \ # X11 + libxfixes-dev \ # X11 + libxrandr-dev \ # X11 + libxtst-dev \ # X11 + nvidia-cuda-dev \ # Cuda, NvFBC + nvidia-cuda-toolkit \ # Cuda, NvFBC + +Fedora 35 +^^^^^^^^^ +End of Life: TBD + +Install Repositories + .. code-block:: bash + + sudo dnf update && \ + sudo dnf group install "Development Tools" && \ + sudo dnf install https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm + +Install Requirements + .. code-block:: bash + + sudo dnf install \ + boost-devel \ + boost-static.x86_64 \ + cmake \ + ffmpeg-devel \ + gcc-c++ \ + libevdev-devel \ + libX11-devel \ # X11 + libxcb-devel \ # X11 + libXcursor-devel \ # X11 + libXfixes-devel \ # X11 + libXinerama-devel \ # X11 + libXi-devel \ # X11 + libXrandr-devel \ # X11 + libXtst-devel \ # X11 + mesa-libGL-devel \ + openssl-devel \ + opus-devel \ + pulseaudio-libs-devel \ + rpm-build \ # if you want to build an RPM binary package + +Ubuntu 18.04 +^^^^^^^^^^^^ +End of Life: April 2028 + +Install Repositories + .. code-block:: bash + + sudo apt update && sudo apt install \ + software-properties-common \ + && add-apt-repository ppa:savoury1/graphics && \ + add-apt-repository ppa:savoury1/multimedia && \ + add-apt-repository ppa:savoury1/ffmpeg4 && \ + add-apt-repository ppa:savoury1/boost-defaults-1.71 && \ + add-apt-repository ppa:ubuntu-toolchain-r/test && \ + +Install Requirements + .. code-block:: bash + + sudo apt install \ + build-essential \ + cmake \ + gcc-10 \ + git \ + g++-10 \ + libavdevice-dev \ + libboost-filesystem1.71-dev \ + libboost-log1.71-dev \ + libboost-regex1.71-dev \ + libboost-thread1.71-dev \ + libcap-dev \ # KMS + libdrm-dev \ # KMS + libevdev-dev \ + libpulse-dev \ + libopus-dev \ + libssl-dev \ + libwayland-dev \ # Wayland + libx11-dev \ # X11 + libxcb-shm0-dev \ # X11 + libxcb-xfixes0-dev \ # X11 + libxcb1-dev \ # X11 + libxfixes-dev \ # X11 + libxrandr-dev \ # X11 + libxtst-dev \ # X11 + wget \ + +Update gcc alias + .. code-block:: bash + + update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 + +Install CuDA + .. code-block:: bash + + wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O ./cuda.run && chmod a+x ./cuda.run + ./cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && rm ./cuda.run + +Install CMake + .. code-block:: bash + + wget https://cmake.org/files/v3.22/cmake-3.22.2-linux-x86_64.sh + mkdir /opt/cmake + sh /cmake-3.22.2-linux-x86_64.sh --prefix=/opt/cmake --skip-license + ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake + cmake --version + +Ubuntu 20.04 +^^^^^^^^^^^^ +End of Life: April 2030 + +Install Requirements + .. code-block:: bash + + sudo apt update && sudo apt install \ + build-essential \ + cmake \ + git \ + g++-10 \ + libavdevice-dev \ + libboost-filesystem-dev \ + libboost-log-dev \ + libboost-thread-dev \ + libcap-dev \ # KMS + libdrm-dev \ # KMS + libevdev-dev \ + libpulse-dev \ + libopus-dev \ + libssl-dev \ + libwayland-dev \ # Wayland + libx11-dev \ # X11 + libxcb-shm0-dev \ # X11 + libxcb-xfixes0-dev \ # X11 + libxcb1-dev \ # X11 + libxfixes-dev \ # X11 + libxrandr-dev \ # X11 + libxtst-dev \ # X11 + wget \ + +Update gcc alias + .. code-block:: bash + + update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 + +Install CuDA + .. code-block:: bash + + wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O ./cuda.run && chmod a+x ./cuda.run + ./cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && rm ./cuda.run + +Ubuntu 21.10 +^^^^^^^^^^^^ +End of Life: July 2022 + +Install Requirements + .. code-block:: bash + + sudo apt update && sudo apt install \ + build-essential \ + cmake \ + git \ + libavdevice-dev \ + libboost-filesystem-dev \ + libboost-log-dev \ + libboost-thread-dev \ + libcap-dev \ # KMS + libdrm-dev \ # KMS + libevdev-dev \ + libpulse-dev \ + libopus-dev \ + libssl-dev \ + libwayland-dev \ # Wayland + libx11-dev \ # X11 + libxcb-shm0-dev \ # X11 + libxcb-xfixes0-dev \ # X11 + libxcb1-dev \ # X11 + libxfixes-dev \ # X11 + libxrandr-dev \ # X11 + libxtst-dev \ # X11 + nvidia-cuda-dev \ # Cuda, NvFBC + nvidia-cuda-toolkit \ # Cuda, NvFBC + +Ubuntu 22.04 +^^^^^^^^^^^^ +End of Life: April 2027 + +.. Todo:: Create Ubuntu 22.04 Dockerfile and complete this documentation. + +Build +----- +.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing. + +Debian based OSes + .. code-block:: bash + + cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 .. + +Red Hat based Oses + .. code-block:: bash + + cmake -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ .. + +Finally + .. code-block:: bash + + make -j ${nproc} + cpack -G DEB # optionally, create a deb package + cpack -G RPM # optionally, create a rpm package + +Dockerfile Builds +----------------- +You may wish to simply build sunshine from source, without bloating your OS with development files. +There are scripts located in the ``./scripts`` directory that will create docker images that have the necessary +packages. As a result, removing the development files after you're done is a single command away. +These scripts use docker under the hood, as such, they can only be used to compile the Linux version + +.. Todo:: Publish the Dockerfiles to Dockerhub and ghcr. + +Requirements + Install `Docker `_ + +Instructions + #. :ref:`Clone `. Sunshine. + #. Select the desired Dockerfile from the ``./scripts`` directory. + + Available Files: + .. code-block:: text + + Dockerfile-debian + Dockerfile-fedora_33 # end of life + Dockerfile-fedora_35 + Dockerfile-ubuntu_18_04 + Dockerfile-ubuntu_20_04 + Dockerfile-ubuntu_21_04 # end of life + Dockerfile-ubuntu_21_10 + + #. Execute + + .. code-block:: bash + + cd scripts # move to the scripts directory + ./build-container.sh -f Dockerfile- # create the container (replace the "") + ./build-sunshine.sh -p -s .. # compile and build sunshine + + #. Updating + + .. code-block:: bash + + git pull # pull the latest changes from github + ./build-sunshine.sh -p -s .. # compile and build sunshine + + #. Optionally, delete the container + .. code-block:: bash + + ./build-container.sh -c delete + + #. Install the resulting package + + Debian + .. code-block:: bash + + sudo apt install -f sunshine-build/sunshine.deb + + Red Hat + .. code-block:: bash + + sudo dnf install sunshine-build/sunshine.rpm diff --git a/docs/source/building/macos.rst b/docs/source/building/macos.rst new file mode 100644 index 0000000000..51ae6b1597 --- /dev/null +++ b/docs/source/building/macos.rst @@ -0,0 +1,43 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/building/macos.rst + +MacOS +===== + +Requirements +------------ +MacOS Big Sur and Xcode 12.5+ + +Use either `MacPorts `_ or `Homebrew `_ + +MacPorts +"""""""" +Install Requirements + .. code-block:: bash + + sudo port install cmake boost ffmpeg libopus + +Homebrew +"""""""" +Install Requirements + .. code-block:: bash + + brew install boost cmake ffmpeg opus + # if there are issues with an SSL header that is not found: + cd /usr/local/include + ln -s ../opt/openssl/include/openssl . + +Build +----- +.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing. + + .. code-block:: bash + + cmake .. + make -j ${nproc} + + cpack -G DragNDrop # optionally, create a MacOS dmg package + +If cmake fails complaining to find Boost, try to set the path explicitly. + + ``cmake -DBOOST_ROOT=[boost path] ..``, e.g., ``cmake -DBOOST_ROOT=/opt/local/libexec/boost/1.76 ..`` + diff --git a/docs/source/building/windows.rst b/docs/source/building/windows.rst new file mode 100644 index 0000000000..7708da49b7 --- /dev/null +++ b/docs/source/building/windows.rst @@ -0,0 +1,27 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/building/windows.rst + +Windows +======= + +Requirements +------------ +First you need to install `MSYS2 `_, then startup "MSYS2 MinGW 64-bit" and install the +following packages using: + +.. code-block:: bash + + pacman -S mingw-w64-x86_64-binutils mingw-w64-x86_64-openssl mingw-w64-x86_64-cmake mingw-w64-x86_64-toolchain mingw-w64-x86_64-opus mingw-w64-x86_64-x265 mingw-w64-x86_64-boost git mingw-w64-x86_64-make cmake make gcc + +Build +----- +.. Attention:: Ensure you are in the build directory created during the clone step earlier before continuing. + + .. code-block:: bash + + cmake -G"Unix Makefiles" .. + cmake -G"MinGW Makefiles" .. # alternatively + + mingw32-make + + cpack -G NSIS # optionally, create a windows installer + cpack -G ZIP # optionally, create a windows standalone package diff --git a/docs/source/conf.py b/docs/source/conf.py new file mode 100644 index 0000000000..f4873f1531 --- /dev/null +++ b/docs/source/conf.py @@ -0,0 +1,97 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# standard imports +from datetime import datetime +import os +import re + + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. + +script_dir = os.path.dirname(os.path.abspath(__file__)) # the directory of this file +source_dir = os.path.dirname(script_dir) # the source folder directory +root_dir = os.path.dirname(source_dir) # the root folder directory + +# -- Project information ----------------------------------------------------- +project = 'Sunshine' +copyright = f'{datetime.now ().year}, {project}' +author = 'ReenigneArcher' + +# The full version, including alpha/beta/rc tags +with open(os.path.join(root_dir, 'CMakeLists.txt'), 'r') as f: + version = re.search(r"project\(Sunshine VERSION ((\d+)\.(\d+)\.(\d+))", str(f.read())).group(1) +""" +To use cmake method for obtaining version instead of regex, +1. Within CMakeLists.txt add the following line without backticks: + ``configure_file(docs/source/conf.py.in "${CMAKE_CURRENT_SOURCE_DIR}/docs/source/conf.py" @ONLY)`` +2. Rename this file to ``conf.py.in`` +3. Uncomment the next line +""" +# version = '@PROJECT_VERSION@' # use this for cmake configure_file method + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [ + 'm2r2', # enable markdown files + 'sphinx.ext.autosectionlabel', + 'sphinx.ext.todo', # enable to-do sections + 'sphinx.ext.viewcode', # add links to view source code + 'sphinx_copybutton', # add a copy button to code blocks +] + +# Add any paths that contain templates here, relative to this directory. +# templates_path = ['_templates'] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ['toc.rst'] + +# Extensions to include. +source_suffix = ['.rst', '.md'] + + +# -- Options for HTML output ------------------------------------------------- + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +# html_static_path = ['_static'] + +html_logo = os.path.join(root_dir, 'sunshine.png') + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'sphinx_rtd_theme' + +html_theme_options = { + # 'analytics_id': 'G-XXXXXXXXXX', # Provided by Google in your dashboard + # 'analytics_anonymize_ip': False, + 'logo_only': False, + 'display_version': False, + 'prev_next_buttons_location': 'bottom', + 'style_external_links': True, + 'vcs_pageview_mode': 'blob', + # 'style_nav_header_background': 'white', + # Toc options + 'collapse_navigation': True, + 'sticky_navigation': True, + 'navigation_depth': 4, + 'includehidden': True, + 'titles_only': False, +} + +# extension config options +autosectionlabel_prefix_document = True # Make sure the target is unique +todo_include_todos = True diff --git a/docs/source/contributing/contributing.rst b/docs/source/contributing/contributing.rst new file mode 100644 index 0000000000..d9f5106f39 --- /dev/null +++ b/docs/source/contributing/contributing.rst @@ -0,0 +1,32 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/contributing/contributing.rst + +Contributing +============ +#. Fork the repo on GitHub +#. Create a new branch for the feature you are adding or the issue you are fixing + + .. Tip:: Base the new branch off the `nightly` branch. It will make your life easier when you submit the PR! + +#. Make changes, push commits, etc. +#. Files should contain an empty line at the end. +#. Document your code! +#. Test your code! +#. When ready create a PR to this repo on the `nightly` branch. + + .. Hint:: If you accidentally make your PR against a different branch, a bot will comment letting you know it's on + the wrong branch. Don't worry. You can edit the PR to change the target branch. There is no reason to close the + PR! + + .. Note:: Draft PRs are also welcome as you work through issues. The benefit of creating a draft PR is that an + automated build can run in a github runner. + + .. Attention:: Do not expect partially complete PRs to be merged. These topics will be considered before merging. + + - Does the code follows the style guidelines of this project? + + .. Tip:: Look at examples of existing code in the project! + + - Is the code well commented? + - Were documentation blocks updated for new or modified components? + + .. Note:: Developers and maintainers will attempt to assist with challenging issues. diff --git a/docs/source/contributing/localization.rst b/docs/source/contributing/localization.rst new file mode 100644 index 0000000000..8127eda3d5 --- /dev/null +++ b/docs/source/contributing/localization.rst @@ -0,0 +1,84 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/contributing/localization.rst + +Localization +============ +Sunshine is being localized into various languages. The default language is `en` (English) and is highlighted green. + +.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=de&style=for-the-badge&query=%24.progress.0.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json +.. image:: https://img.shields.io/badge/dynamic/json?color=green&label=en&style=for-the-badge&query=%24.progress.1.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json +.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=en-GB&style=for-the-badge&query=%24.progress.2.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json +.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=en-US&style=for-the-badge&query=%24.progress.3.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json +.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=es-ES&style=for-the-badge&query=%24.progress.4.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json +.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=fr&style=for-the-badge&query=%24.progress.5.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json +.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=it&style=for-the-badge&query=%24.progress.6.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json +.. image:: https://img.shields.io/badge/dynamic/json?color=blue&label=ru&style=for-the-badge&query=%24.progress.7.data.translationProgress&url=https%3A%2F%2Fbadges.awesome-crowdin.com%2Fstats-15178612-503956.json + +Graph + .. image:: https://badges.awesome-crowdin.com/translation-15178612-503956.png + +CrowdIn +------- +The translations occur on +`CrowdIn `_. Feel free to contribute to localization there. +Only elements of the API are planned to be translated. + +.. Attention:: The rest API has not yet been implemented. + +Translations Basics + - The brand names `SunshineStream` and `Sunshine` should never be translated. + - Other brand names should never be translated. + Examples: + + - AMD + - Nvidia + +CrowdIn Integration + How does it work? + + When a change is made to sunshine source code, a workflow generates new translation templates + that get pushed to CrowdIn automatically. + + When translations are updated on CrowdIn, a push gets made to the `l10n_nightly` branch and a PR is made against the + `nightly` branch. Once PR is merged, all updated translations are part of the project and will be included in the + next release. + +Extraction +---------- +There should be minimal cases where strings need to be extracted from source code; however it may be necessary in some +situations. For example if a system tray icon is added it should be localized as it is user interfacing. + + - Wrap the string to be extracted in a function as shown. + + .. code-block:: cpp + + #include + boost::locale::translate("Hello world!") + + .. Tip:: More examples can be found in the documentation for + `boost locale `_. + +.. Warning:: This is for information only. Contributors should never include manually updated template files, or + manually compiled language files in Pull Requests. + +Strings are automatically extracted from the code to the `locale/sunshine.po` template file. The generated file is +used by CrowdIn to generate language specific template files. The file is generated using the +`.github/workflows/localize.yml` workflow and is run on any push event into the `nightly` branch. Jobs are only run if +any of the following paths are modified. + + .. code-block:: yaml + + - 'sunshine/**' + +When testing locally it may be desirable to manually extract, initialize, update, and compile strings. Python is +required for this, along with the python dependencies in the `./scripts/requirements.txt` file. Additionally, +`xgettext `_ must be installed. + + Extract, initialize, and update + .. code-block:: bash + + python ./scripts/_locale.py --extract --init --update + + Compile + .. code-block:: bash + + python ./scripts/_locale.py --compile diff --git a/docs/source/contributing/testing.rst b/docs/source/contributing/testing.rst new file mode 100644 index 0000000000..a08c6f9c81 --- /dev/null +++ b/docs/source/contributing/testing.rst @@ -0,0 +1,42 @@ +:github_url: https://github.com/RetroArcher/RetroArcher/tree/nightly/docs/source/contributing/testing.rst + +Testing +======= + +Clang Format +------------ +Source code is tested against the `.clang-format` file for linting errors. The workflow file responsible for clang +format testing is `.github/workflows/clang.yml`. + +Test clang-format locally. + .. Todo:: This documentation needs to be improved. + + .. code-block:: bash + + clang-format ... + +Sphinx +------ +Sunshine uses `Sphinx `_ for documentation building. Sphinx is included +in the `./scripts/requirements.txt` file. Python is required to build sphinx docs. Installation and setup of python +will not be covered here. + +The config file for Sphinx is `docs/source/conf.py`. This is already included in the repo and should not be modified. + +Test with Sphinx + .. code-block:: bash + + cd docs + make html + + Alternatively + + .. code-block:: bash + + cd docs + sphinx-build -b html source build + +Unit Testing +------------ +.. Todo:: Sunshine does not currently have any unit tests. If you would like to help us improve please get in contact + with us, or make a PR with suggested changes. diff --git a/docs/source/index.rst b/docs/source/index.rst new file mode 100644 index 0000000000..5384c8e282 --- /dev/null +++ b/docs/source/index.rst @@ -0,0 +1,7 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/index.rst + +SunshineStream has this documentation hosted on `Read the Docs `_. + +Table of Contents +================= +.. include:: toc.rst diff --git a/docs/source/toc.rst b/docs/source/toc.rst new file mode 100644 index 0000000000..efafa92bff --- /dev/null +++ b/docs/source/toc.rst @@ -0,0 +1,36 @@ +.. toctree:: + :maxdepth: 2 + :caption: About + + about/overview + about/installation + about/docker + about/third_party_packages + about/usage + about/advanced_usage + +.. toctree:: + :maxdepth: 2 + :caption: Troubleshooting + + troubleshooting/general + troubleshooting/linux + troubleshooting/macos + troubleshooting/windows + +.. toctree:: + :maxdepth: 2 + :caption: Build + + building/build + building/linux + building/macos + building/windows + +.. toctree:: + :maxdepth: 2 + :caption: Contributing + + contributing/contributing + contributing/localization + contributing/testing diff --git a/docs/source/troubleshooting/general.rst b/docs/source/troubleshooting/general.rst new file mode 100644 index 0000000000..322327ccba --- /dev/null +++ b/docs/source/troubleshooting/general.rst @@ -0,0 +1,13 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/troubleshooting/general.rst + +General +======= +If you forgot your credentials to the web UI, try this. + + .. code-block:: bash + + sunshine -creds + +Can't access the web UI? + + #. Check firefall rules. diff --git a/docs/source/troubleshooting/linux.rst b/docs/source/troubleshooting/linux.rst new file mode 100644 index 0000000000..71e9eac0e6 --- /dev/null +++ b/docs/source/troubleshooting/linux.rst @@ -0,0 +1,9 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/troubleshooting/linux.rst + +Linux +===== +If screencasting fails with Wayland, you may need to run the following to force screencasting with X11. + + .. code-block:: bash + + sudo setcap -r $(readlink -f $(which sunshine)) diff --git a/docs/source/troubleshooting/macos.rst b/docs/source/troubleshooting/macos.rst new file mode 100644 index 0000000000..18ea93615b --- /dev/null +++ b/docs/source/troubleshooting/macos.rst @@ -0,0 +1,14 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/troubleshooting/macos.rst + +MacOS +===== +If you get this error: + + ``Dynamic session lookup supported but failed: launchd did not provide a socket path, verify that + org.freedesktop.dbus-session.plist is loaded!`` + + Try this. + + .. code-block:: bash + + launchctl load -w /Library/LaunchAgents/org.freedesktop.dbus-session.plist diff --git a/docs/source/troubleshooting/windows.rst b/docs/source/troubleshooting/windows.rst new file mode 100644 index 0000000000..461bce0a9e --- /dev/null +++ b/docs/source/troubleshooting/windows.rst @@ -0,0 +1,7 @@ +:github_url: https://github.com/SunshineStream/Sunshine/tree/nightly/docs/source/troubleshooting/windows.rst + +Windows +======= +No gamepad is detected. + + #. Verify that you've installed `ViGEmBus `_. diff --git a/gamepad.png b/gamepad.png deleted file mode 100644 index 274c7cede5..0000000000 Binary files a/gamepad.png and /dev/null differ diff --git a/gen-deb.in b/gen-deb.in deleted file mode 100755 index 25ca36096f..0000000000 --- a/gen-deb.in +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/sh - -if [ ! "@SUNSHINE_UNDEFINED_VARIABLE@" = "" ]; then - echo "Please run gen-deb generated by cmake inside the build directory" - exit 1 -fi - -if [ -d package-deb ]; then - echo "package-deb already exists: It will be replaced" - rm -rf package-deb -fi - -export DEBIAN=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/DEBIAN -export RULES=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/etc/udev/rules.d -export BIN=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/usr/bin -export SERVICE=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/usr/lib/systemd/user -export ASSETS=@CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine/etc/sunshine - -mkdir -p $DEBIAN -mkdir -p $RULES -mkdir -p $BIN -mkdir -p $ASSETS/shaders -mkdir -p $SERVICE - -if [ ! -f sunshine ]; then - echo "Error: Can't find sunshine" - exit 1 -fi - -cat << 'EOF' > $DEBIAN/conffiles -/etc/sunshine/sunshine.conf -/etc/sunshine/apps_linux.json -EOF - -cat << 'EOF' > $DEBIAN/control -Package: sunshine -Architecture: amd64 -Maintainer: @loki -Priority: optional -Version: @PROJECT_VERSION@ -Depends: libssl1.1, libavdevice58, libboost-thread1.67.0 | libboost-thread1.71.0 | libboost-thread1.74.0, libboost-filesystem1.67.0 | libboost-filesystem1.71.0 | libboost-filesystem1.74.0, libboost-log1.67.0 | libboost-log1.71.0 | libboost-log1.74.0, libpulse0, libopus0, libxcb-shm0, libxcb-xfixes0, libxtst6, libevdev2, libdrm2, libcap2 -Description: Gamestream host for Moonlight -EOF - -cat << 'EOF' > $DEBIAN/preinst -#Store backup for old config files to prevent it from being overwritten -if [ -f /etc/sunshine/sunshine.conf ]; then - cp /etc/sunshine/sunshine.conf /etc/sunshine/sunshine.conf.old -fi - -if [ -f /etc/sunshine/apps_linux.json ]; then - cp /etc/sunshine/apps_linux.json /etc/sunshine/apps_linux.json.old -fi -EOF - -cat << 'EOF' > $DEBIAN/postinst -#!/bin/sh - -export GROUP_INPUT=input - -if [ -f /etc/group ]; then - if ! grep -q $GROUP_INPUT /etc/group; then - echo "Creating group $GROUP_INPUT" - - groupadd $GROUP_INPUT - fi -else - echo "Warning: /etc/group not found" -fi - -if [ -f /etc/sunshine/sunshine.conf.old ]; then - echo "Restoring old sunshine.conf" - mv /etc/sunshine/sunshine.conf.old /etc/sunshine/sunshine.conf -fi - -if [ -f /etc/sunshine/apps_linux.json.old ]; then - echo "Restoring old apps_linux.json" - mv /etc/sunshine/apps_linux.json.old /etc/sunshine/apps_linux.json -fi - -# Update permissions on config files for Web Manager -if [ -f /etc/sunshine/apps_linux.json ]; then - echo "chmod 666 /etc/sunshine/apps_linux.json" - chmod 666 /etc/sunshine/apps_linux.json -fi - -if [ -f /etc/sunshine/sunshine.conf ]; then - echo "chmod 666 /etc/sunshine/sunshine.conf" - chmod 666 /etc/sunshine/sunshine.conf -fi - -# Ensure Sunshine can grab images from KMS -path_to_setcap=$(which setcap) -if [ -x "$path_to_setcap" ] ; then - echo "$path_to_setcap cap_sys_admin+p /usr/bin/sunshine" - $path_to_setcap cap_sys_admin+p /usr/bin/sunshine -fi -EOF - -cat << 'EOF' > $RULES/85-sunshine-rules.rules -KERNEL=="uinput", GROUP="input", MODE="0660" -EOF - -cp sunshine $BIN/sunshine -cp @CMAKE_CURRENT_SOURCE_DIR@/assets/apps_linux.json $ASSETS/apps_linux.json -cp @CMAKE_CURRENT_SOURCE_DIR@/assets/sunshine.conf $ASSETS/sunshine.conf -cp @CMAKE_CURRENT_BINARY_DIR@/sunshine.service $SERVICE/sunshine.service -cp -r @CMAKE_CURRENT_SOURCE_DIR@/assets/web $ASSETS/web -cp -r @CMAKE_CURRENT_SOURCE_DIR@/assets/shaders/opengl $ASSETS/shaders/opengl - -chmod 755 $DEBIAN/postinst -chmod 755 $DEBIAN/preinst -chmod 755 $BIN/sunshine -chmod 644 $RULES/85-sunshine-rules.rules -chmod 666 $ASSETS/apps_linux.json -chmod 666 $ASSETS/sunshine.conf - -cd package-deb -if fakeroot dpkg-deb --build sunshine; then - echo "generated debian package: @CMAKE_CURRENT_BINARY_DIR@/package-deb/sunshine.deb" -fi -cd .. - diff --git a/scripts/Dockerfile-debian b/scripts/Dockerfile-debian index 15f0d65637..fc77eb8e98 100644 --- a/scripts/Dockerfile-debian +++ b/scripts/Dockerfile-debian @@ -1,5 +1,7 @@ FROM debian:bullseye AS sunshine-debian +# Debian Bullseye end of life is TBD + ARG DEBIAN_FRONTEND=noninteractive ARG TZ="Europe/London" @@ -11,9 +13,9 @@ RUN apt-get update -y && \ cmake \ git \ libavdevice-dev \ - libboost-thread-dev \ libboost-filesystem-dev \ libboost-log-dev \ + libboost-thread-dev \ libcap-dev \ libdrm-dev \ libevdev-dev \ @@ -33,7 +35,6 @@ RUN apt-get update -y && \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +# Entrypoint COPY build-private.sh /root/build.sh - - -ENTRYPOINT ["/root/build.sh"] +ENTRYPOINT ["/root/build.sh", "-deb"] diff --git a/scripts/Dockerfile-fedora_33 b/scripts/Dockerfile-fedora_33 index ae7e49592e..320c6a6748 100644 --- a/scripts/Dockerfile-fedora_33 +++ b/scripts/Dockerfile-fedora_33 @@ -1,5 +1,8 @@ FROM fedora:33 AS sunshine-fedora_33 +# Fedora 33 end of life is November 2021 +# This file remains for reference only + SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN dnf -y update && \ dnf -y group install "Development Tools" && \ @@ -18,10 +21,12 @@ RUN dnf -y update && \ openssl-devel \ opus-devel \ pulseaudio-libs-devel \ + libcap-devel \ + libdrm-devel \ + rpm-build \ && dnf clean all \ && rm -rf /var/cache/yum +# Entrypoint COPY build-private.sh /root/build.sh - - -ENTRYPOINT ["/root/build.sh"] +ENTRYPOINT ["/root/build.sh", "-rpm"] diff --git a/scripts/Dockerfile-fedora_35 b/scripts/Dockerfile-fedora_35 index 0cde7aa4b0..18f5bf53a5 100644 --- a/scripts/Dockerfile-fedora_35 +++ b/scripts/Dockerfile-fedora_35 @@ -1,5 +1,7 @@ FROM fedora:35 AS sunshine-fedora_35 +# Fedora 35 end of life is TBD + SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN dnf -y update && \ dnf -y group install "Development Tools" && \ @@ -11,8 +13,8 @@ RUN dnf -y update && \ ffmpeg-devel \ gcc-c++ \ libevdev-devel \ - libxcb-devel \ libX11-devel \ + libxcb-devel \ libXcursor-devel \ libXfixes-devel \ libXinerama-devel \ @@ -23,10 +25,12 @@ RUN dnf -y update && \ openssl-devel \ opus-devel \ pulseaudio-libs-devel \ + libcap-devel \ + libdrm-devel \ + rpm-build \ && dnf clean all \ && rm -rf /var/cache/yum +# Entrypoint COPY build-private.sh /root/build.sh - - -ENTRYPOINT ["/root/build.sh"] +ENTRYPOINT ["/root/build.sh", "-rpm"] diff --git a/scripts/Dockerfile-ubuntu_18_04 b/scripts/Dockerfile-ubuntu_18_04 index 5ee33ae331..6ad3e8c02a 100644 --- a/scripts/Dockerfile-ubuntu_18_04 +++ b/scripts/Dockerfile-ubuntu_18_04 @@ -1,35 +1,31 @@ FROM ubuntu:18.04 AS sunshine-ubuntu_18_04 +# Ubuntu 18.04 end of life is April 2028 + ARG DEBIAN_FRONTEND=noninteractive ARG TZ="Europe/London" SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get update -y && \ apt-get install -y \ - apt-transport-https \ - ca-certificates \ - gnupg \ software-properties-common \ - wget \ - && wget -qO - https://apt.kitware.com/keys/kitware-archive-latest.asc | apt-key add - && \ - add-apt-repository 'deb https://apt.kitware.com/ubuntu/ bionic main' && \ - add-apt-repository ppa:ubuntu-toolchain-r/test && \ - add-apt-repository ppa:savoury1/graphics && \ + && add-apt-repository ppa:savoury1/graphics && \ add-apt-repository ppa:savoury1/multimedia && \ add-apt-repository ppa:savoury1/ffmpeg4 && \ + add-apt-repository ppa:savoury1/boost-defaults-1.71 && \ + add-apt-repository ppa:ubuntu-toolchain-r/test && \ apt-get update -y && \ apt-get install -y \ build-essential \ cmake \ - ffmpeg \ gcc-10 \ git \ g++-10 \ libavdevice-dev \ - libboost-filesystem-dev \ - libboost-log-dev \ - libboost-regex-dev \ - libboost-thread-dev \ + libboost-filesystem1.71-dev \ + libboost-log1.71-dev \ + libboost-regex1.71-dev \ + libboost-thread1.71-dev \ libcap-dev \ libdrm-dev \ libevdev-dev \ @@ -44,15 +40,24 @@ RUN apt-get update -y && \ libxfixes-dev \ libxrandr-dev \ libxtst-dev \ + wget \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +# Update gcc alias RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 +# Install CuDA RUN wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O /root/cuda.run && chmod a+x /root/cuda.run RUN /root/cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && rm /root/cuda.run -COPY build-private.sh /root/build.sh - +# Install cmake +ADD https://cmake.org/files/v3.22/cmake-3.22.2-linux-x86_64.sh /cmake-3.22.2-linux-x86_64.sh +RUN mkdir /opt/cmake +RUN sh /cmake-3.22.2-linux-x86_64.sh --prefix=/opt/cmake --skip-license +RUN ln -s /opt/cmake/bin/cmake /usr/local/bin/cmake +RUN cmake --version -ENTRYPOINT ["/root/build.sh"] +# Entrypoint +COPY build-private.sh /root/build.sh +ENTRYPOINT ["/root/build.sh", "-deb"] diff --git a/scripts/Dockerfile-ubuntu_20_04 b/scripts/Dockerfile-ubuntu_20_04 index 5a633a10d6..44e897a758 100644 --- a/scripts/Dockerfile-ubuntu_20_04 +++ b/scripts/Dockerfile-ubuntu_20_04 @@ -1,8 +1,11 @@ FROM ubuntu:20.04 AS sunshine-ubuntu_20_04 +# Ubuntu 20.04 end of life is April 2030 + ARG DEBIAN_FRONTEND=noninteractive ARG TZ="Europe/London" +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get update -y && \ apt-get install -y \ build-essential \ @@ -31,12 +34,13 @@ RUN apt-get update -y && \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +# Update gcc alias RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 --slave /usr/bin/g++ g++ /usr/bin/g++-10 +# Install CuDA RUN wget https://developer.download.nvidia.com/compute/cuda/11.4.2/local_installers/cuda_11.4.2_470.57.02_linux.run --progress=bar:force:noscroll -q --show-progress -O /root/cuda.run && chmod a+x /root/cuda.run RUN /root/cuda.run --silent --toolkit --toolkitpath=/usr --no-opengl-libs --no-man-page --no-drm && rm /root/cuda.run +# Entrypoint COPY build-private.sh /root/build.sh - - -ENTRYPOINT ["/root/build.sh"] +ENTRYPOINT ["/root/build.sh", "-deb"] diff --git a/scripts/Dockerfile-ubuntu_21_04 b/scripts/Dockerfile-ubuntu_21_04 index d5668df415..012845a5b6 100644 --- a/scripts/Dockerfile-ubuntu_21_04 +++ b/scripts/Dockerfile-ubuntu_21_04 @@ -1,8 +1,12 @@ FROM ubuntu:21.04 AS sunshine-ubuntu_21_04 +# Ubuntu 21.04 end of life is January 2022 +# This file remains for reference only + ARG DEBIAN_FRONTEND=noninteractive ARG TZ="Europe/London" +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get update -y && \ apt-get install -y \ build-essential \ @@ -31,7 +35,6 @@ RUN apt-get update -y && \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +# Entrypoint COPY build-private.sh /root/build.sh - - -ENTRYPOINT ["/root/build.sh"] +ENTRYPOINT ["/root/build.sh", "-deb"] diff --git a/scripts/Dockerfile-ubuntu_21_10 b/scripts/Dockerfile-ubuntu_21_10 index 1477062536..6be49dbe0c 100644 --- a/scripts/Dockerfile-ubuntu_21_10 +++ b/scripts/Dockerfile-ubuntu_21_10 @@ -1,17 +1,20 @@ FROM ubuntu:21.10 AS sunshine-ubuntu_21_10 +# Ubuntu 21.10 end of life is July 2022 + ARG DEBIAN_FRONTEND=noninteractive ARG TZ="Europe/London" +SHELL ["/bin/bash", "-o", "pipefail", "-c"] RUN apt-get update -y && \ apt-get install -y \ build-essential \ cmake \ git \ libavdevice-dev \ - libboost-thread-dev \ libboost-filesystem-dev \ libboost-log-dev \ + libboost-thread-dev \ libcap-dev \ libdrm-dev \ libevdev-dev \ @@ -31,7 +34,6 @@ RUN apt-get update -y && \ && apt-get clean \ && rm -rf /var/lib/apt/lists/* +# Entrypoint COPY build-private.sh /root/build.sh - - -ENTRYPOINT ["/root/build.sh"] +ENTRYPOINT ["/root/build.sh", "-deb"] diff --git a/scripts/README.md b/scripts/README.md deleted file mode 100644 index 16e99ac80e..0000000000 --- a/scripts/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# Introduction -Sunshine is a Gamestream host for Moonlight - -[![AppVeyor Build Status](https://ci.appveyor.com/api/projects/status/cgrtw2g3fq9b0b70/branch/master?svg=true)](https://ci.appveyor.com/project/loki-47-6F-64/sunshine/branch/master) -[![Downloads](https://img.shields.io/github/downloads/Loki-47-6F-64/sunshine/total)](https://github.com/Loki-47-6F-64/sunshine/releases) - -You may wish to simply build sunshine from source, without bloating your OS with development files. -These scripts will create a docker images that have the necessary packages. As a result, removing the development files after you're done is a single command away. -These scripts use docker under the hood, as such, they can only be used to compile the Linux version - - -#### Requirements - -``` -sudo apt install docker -``` - -#### instructions - -You'll require one of the following Dockerfiles: -* Dockerfile-2004 --> Ubuntu 20.04 -* Dockerfile-2104 --> Ubuntu 21.04 -* Dockerfile-debian --> Debian Bullseye - -Depending on your system, the build-* scripts may need root privilleges - -First, the docker container needs to be created: -``` -cd scripts -./build-container.sh -f Dockerfile- -``` - -Then, the sources will be compiled and the debian package generated: -``` -./build-sunshine.sh -p -s .. -``` -You can run `build-sunshine -p -s ..` again as long as the docker container exists. - -``` -git pull -./build-sunshine.sh -p -s .. -``` - -Optionally, the docker container can be removed after you're finished: -``` -./build-container.sh -c delete -``` - -Finally install the resulting package: -``` -sudo apt install -f sunshine-build/sunshine.deb -``` - diff --git a/scripts/_locale.py b/scripts/_locale.py new file mode 100644 index 0000000000..339e2d4aea --- /dev/null +++ b/scripts/_locale.py @@ -0,0 +1,170 @@ +""" +.. + _locale.py + +Functions related to building, initializing, updating, and compiling localization translations. + +Borrowed from RetroArcher. +""" +# standard imports +import argparse +import datetime +import os +import subprocess + +project_name = 'Sunshine' +project_owner = 'SunshineStream' + +script_dir = os.path.dirname(os.path.abspath(__file__)) +root_dir = os.path.dirname(script_dir) +locale_dir = os.path.join(root_dir, 'locale') +project_dir = os.path.join(root_dir, project_name.lower()) + +year = datetime.datetime.now().year + +# retroarcher target locales +target_locales = [ + 'de', # Deutsch + 'en', # English + 'en_GB', # English (United Kingdom) + 'en_US', # English (United States) + 'es', # español + 'fr', # français + 'it', # italiano + 'ru', # русский +] + + +def x_extract(): + """Executes `xgettext extraction` in subprocess.""" + + pot_filepath = os.path.join(locale_dir, f'{project_name.lower()}.po') + + commands = [ + 'xgettext', + '--keyword=translate:1,1t', + '--keyword=translate:1c,2,2t', + '--keyword=translate:1,2,3t', + '--keyword=translate:1c,2,3,4t', + '--keyword=gettext:1', + '--keyword=pgettext:1c,2', + '--keyword=ngettext:1,2', + '--keyword=npgettext:1c,2,3', + f'--default-domain={project_name.lower()}', + f'--output={pot_filepath}', + '--language=C++', + '--boost', + '--from-code=utf-8', + '-F', + f'--msgid-bugs-address=github.com/{project_owner.lower()}/{project_name.lower()}', + f'--copyright-holder={project_owner}', + f'--package-name={project_name}', + '--package-version=v0' + ] + + extensions = ['cpp', 'h', 'm', 'mm'] + + # find input files + for root, dirs, files in os.walk(project_dir, topdown=True): + for name in files: + filename = os.path.join(root, name) + extension = filename.rsplit('.', 1)[-1] + if extension in extensions: # append input files + commands.append(filename) + + print(commands) + subprocess.check_output(args=commands, cwd=root_dir) + + try: + # fix header + body = "" + with open(file=pot_filepath, mode='r') as file: + for line in file.readlines(): + if line != '"Language: \\n"\n': # do not include this line + if line == '# SOME DESCRIPTIVE TITLE.\n': + body += f'# Translations template for {project_name}.\n' + elif line.startswith('#') and 'YEAR' in line: + body += line.replace('YEAR', str(year)) + elif line.startswith('#') and 'PACKAGE' in line: + body += line.replace('PACKAGE', project_name) + else: + body += line + + # rewrite pot file with updated header + with open(file=pot_filepath, mode='w+') as file: + file.write(body) + except FileNotFoundError: + pass + + +def babel_init(locale_code: str): + """Executes `pybabel init` in subprocess. + + :param locale_code: str - locale code + """ + commands = [ + 'pybabel', + 'init', + '-i', os.path.join(locale_dir, f'{project_name.lower()}.po'), + '-d', locale_dir, + '-D', project_name.lower(), + '-l', locale_code + ] + + print(commands) + subprocess.check_output(args=commands, cwd=root_dir) + + +def babel_update(): + """Executes `pybabel update` in subprocess.""" + commands = [ + 'pybabel', + 'update', + '-i', os.path.join(locale_dir, f'{project_name.lower()}.po'), + '-d', locale_dir, + '-D', project_name.lower(), + '--update-header-comment' + ] + + print(commands) + subprocess.check_output(args=commands, cwd=root_dir) + + +def babel_compile(): + """Executes `pybabel compile` in subprocess.""" + commands = [ + 'pybabel', + 'compile', + '-d', locale_dir, + '-D', project_name.lower() + ] + + print(commands) + subprocess.check_output(args=commands, cwd=root_dir) + + +if __name__ == '__main__': + # Set up and gather command line arguments + parser = argparse.ArgumentParser( + description='Script helps update locale translations. Translations must be done manually.') + + parser.add_argument('--extract', action='store_true', help='Extract messages from c++ files.') + parser.add_argument('--init', action='store_true', help='Initialize any new locales specified in target locales.') + parser.add_argument('--update', action='store_true', help='Update existing locales.') + parser.add_argument('--compile', action='store_true', help='Compile translated locales.') + + args = parser.parse_args() + + if args.extract: + x_extract() + + if args.init: + for locale_id in target_locales: + if not os.path.isdir(os.path.join(locale_dir, locale_id)): + babel_init(locale_code=locale_id) + + if args.update: + babel_update() + + if args.compile: + babel_compile() diff --git a/scripts/build-private.sh b/scripts/build-private.sh index 69446de648..93d1874889 100755 --- a/scripts/build-private.sh +++ b/scripts/build-private.sh @@ -32,4 +32,17 @@ cmake "-DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE" "-DSUNSHINE_EXECUTABLE_PATH=$SUNSHI make -j ${nproc} -./gen-deb +# Get preferred package format +if [ "$1" == "-rpm" ] +then + echo "Packaging in .rpm format." + ./gen-rpm -d +elif [ "$1" == "-deb" ] +then + echo "Packaging in .deb format." + ./gen-deb +else + echo "Preferred packaging not specified." + echo "Use -deb or -rpm to specify preferred package format." + exit 1 +fi diff --git a/scripts/build-sunshine.sh b/scripts/build-sunshine.sh index df21df3cb4..5be8280823 100755 --- a/scripts/build-sunshine.sh +++ b/scripts/build-sunshine.sh @@ -4,7 +4,8 @@ set -e usage() { echo "Usage: $0" echo " -d: Generate a debug build" - echo " -p: Generate a debian package" + echo " -p: Generate a linux package" + echo " -e: Extension of package... i.e. 'deb', 'rpm' --> default [deb]" echo " -u: The input device is not a TTY" echo " -n name: Docker container name --> default [sunshine]" echo " -s path/to/sources/sunshine: Use local sources instead of a git repository" @@ -26,13 +27,14 @@ absolute_path() { CMAKE_BUILD_TYPE="-e CMAKE_BUILD_TYPE=Release" SUNSHINE_PACKAGE_BUILD=OFF +SUNSHINE_PACKAGE_EXTENSION=deb SUNSHINE_GIT_URL=https://github.com/sunshinestream/sunshine.git CONTAINER_NAME=sunshine # Docker will fail if ctrl+c is passed through and the input is not a tty DOCKER_INTERACTIVE=-ti -while getopts ":dpuhc:s:n:" arg; do +while getopts ":dpuhc:e:s:n:" arg; do case ${arg} in u) echo "Input device is not a TTY" @@ -49,6 +51,21 @@ while getopts ":dpuhc:s:n:" arg; do SUNSHINE_ASSETS_DIR="-e SUNSHINE_ASSETS_DIR=/etc/sunshine" SUNSHINE_EXECUTABLE_PATH="-e SUNSHINE_EXECUTABLE_PATH=/usr/bin/sunshine" ;; + e) + echo "Defining package extension: $OPTARG" + if [ "$OPTARG" == "deb" ] + then + SUNSHINE_PACKAGE_EXTENSION=$OPTARG + echo "Package extension: deb" + elif [ "$OPTARG" == "rpm" ] + then + SUNSHINE_PACKAGE_EXTENSION=$OPTARG + echo "Package extension: rpm" + else + echo "Package extension not supported: $OPTARG" + echo "Falling back to default package extension: $SUNSHINE_PACKAGE_EXTENSION" + fi + ;; s) absolute_path "$OPTARG" OPTARG="$RETURN" @@ -98,8 +115,8 @@ then mkdir -p $BUILD_DIR case $SUNSHINE_PACKAGE_BUILD in ON) - echo "Downloading package to: $BUILD_DIR/$CONTAINER_NAME.deb" - docker cp $CONTAINER_NAME:/root/sunshine-build/package-deb/sunshine.deb "$BUILD_DIR/$CONTAINER_NAME.deb" + echo "Downloading package to: $BUILD_DIR/$CONTAINER_NAME.$SUNSHINE_PACKAGE_EXTENSION" + docker cp $CONTAINER_NAME:/root/sunshine-build/package-$SUNSHINE_PACKAGE_EXTENSION/sunshine.$SUNSHINE_PACKAGE_EXTENSION "$BUILD_DIR/$CONTAINER_NAME.$SUNSHINE_PACKAGE_EXTENSION" ;; *) echo "Downloading binary and assets to: $BUILD_DIR" diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 0000000000..73eefbe1ff --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1,5 @@ +Babel==2.9.1 +m2r2==0.3.2 +Sphinx==4.5.0 +sphinx-copybutton==0.5.0 +sphinx-rtd-theme==1.0.0 diff --git a/assets/box.png b/src_assets/common/assets/box.png similarity index 100% rename from assets/box.png rename to src_assets/common/assets/box.png diff --git a/assets/steam.png b/src_assets/common/assets/steam.png similarity index 100% rename from assets/steam.png rename to src_assets/common/assets/steam.png diff --git a/assets/web/apps.html b/src_assets/common/assets/web/apps.html similarity index 100% rename from assets/web/apps.html rename to src_assets/common/assets/web/apps.html diff --git a/assets/web/clients.html b/src_assets/common/assets/web/clients.html similarity index 100% rename from assets/web/clients.html rename to src_assets/common/assets/web/clients.html diff --git a/assets/web/config.html b/src_assets/common/assets/web/config.html similarity index 96% rename from assets/web/config.html rename to src_assets/common/assets/web/config.html index 203e807fea..01954e76e7 100644 --- a/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -37,13 +37,13 @@

Configuration

class="form-select" v-model="config.min_log_level" > - - - - - - - + + + + + + +
The minimum log level printed to standard out @@ -400,7 +400,18 @@

Configuration

You can select the video card you want to stream:
The appropriate values can be found using the following command:
tools\dxgi-info.exe
-
+
+ + +
+ + +
+ Improves capture latency/smoothness during mouse movement.
+ Disable if you encounter any VSync-related issues.
@@ -497,7 +508,7 @@

Configuration

- +