mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-11 00:05:36 +02:00
⚡ perf(runner): Reduce CI buildtimes (#174)
This is an effort to reduce build times, for the runner image --------- Co-authored-by: Kristian Ollikainen <14197772+DatCaptainHorse@users.noreply.github.com>
This commit is contained in:
3
.dockerignore
Normal file
3
.dockerignore
Normal file
@@ -0,0 +1,3 @@
|
||||
**/target/
|
||||
**/.git
|
||||
**/.env
|
||||
55
.github/workflows/runner.yml
vendored
55
.github/workflows/runner.yml
vendored
@@ -6,7 +6,6 @@ on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "containers/runner.Containerfile"
|
||||
- "packages/server/**"
|
||||
- "packages/scripts/**"
|
||||
- ".github/workflows/runner.yml"
|
||||
schedule:
|
||||
@@ -16,7 +15,7 @@ on:
|
||||
paths:
|
||||
- "containers/runner.Containerfile"
|
||||
- ".github/workflows/runner.yml"
|
||||
- "packages/server/**"
|
||||
- "packages/scripts/**"
|
||||
tags:
|
||||
- v*.*.*
|
||||
release:
|
||||
@@ -51,15 +50,22 @@ jobs:
|
||||
name: Set Swap Space
|
||||
uses: pierotofy/set-swap-space@master
|
||||
with:
|
||||
swap-size-gb: 10
|
||||
swap-size-gb: 20
|
||||
-
|
||||
name: Cache Docker layers
|
||||
name: Cache Rust artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-${{ github.sha }}
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
-
|
||||
name: Cache mold linker
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /usr/bin/mold
|
||||
key: ${{ runner.os }}-mold
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
@@ -68,14 +74,7 @@ jobs:
|
||||
context: ./
|
||||
push: false
|
||||
load: true
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
|
||||
tags: nestri:runner
|
||||
# -
|
||||
# name: Move cache
|
||||
# run: |
|
||||
# rm -rf /tmp/.buildx-cache
|
||||
# mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
|
||||
build-docker-main:
|
||||
name: Build image on main
|
||||
@@ -116,15 +115,22 @@ jobs:
|
||||
name: Set Swap Space
|
||||
uses: pierotofy/set-swap-space@master
|
||||
with:
|
||||
swap-size-gb: 10
|
||||
swap-size-gb: 20
|
||||
-
|
||||
name: Cache Docker layers
|
||||
name: Cache Rust artifacts
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ runner.os }}-buildx-
|
||||
restore-keys: |
|
||||
${{ runner.os }}-buildx-${{ github.sha }}
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
target
|
||||
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
-
|
||||
name: Cache mold linker
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: /usr/bin/mold
|
||||
key: ${{ runner.os }}-mold
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
@@ -132,12 +138,5 @@ jobs:
|
||||
file: containers/runner.Containerfile
|
||||
context: ./
|
||||
push: true
|
||||
cache-from: type=local,src=/tmp/.buildx-cache
|
||||
cache-to: type=local,dest=/tmp/.buildx-cache,mode=max
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
# -
|
||||
# name: Move cache
|
||||
# run: |
|
||||
# rm -rf /tmp/.buildx-cache
|
||||
# mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -52,4 +52,6 @@ id_*
|
||||
target
|
||||
|
||||
tmp
|
||||
.partykit
|
||||
.partykit
|
||||
|
||||
key_*
|
||||
@@ -1,29 +0,0 @@
|
||||
# Contributor Covenant Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate
|
||||
120
CONTRIBUTING.md
120
CONTRIBUTING.md
@@ -1,120 +0,0 @@
|
||||
# Contributing to Nestri
|
||||
|
||||
First off, thank you for considering contributing to Nestri! It's people like you that make Nestri such a great tool.
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
By participating in this project, you are expected to uphold our [Code of Conduct](CODE_OF_CONDUCT.md).
|
||||
|
||||
## How Can I Contribute?
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
This section guides you through submitting a bug report for Nestri. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports.
|
||||
|
||||
- Use a clear and descriptive title for the issue to identify the problem.
|
||||
- Describe the exact steps which reproduce the problem in as many details as possible.
|
||||
- Provide specific examples to demonstrate the steps.
|
||||
|
||||
### Suggesting Enhancements
|
||||
|
||||
This section guides you through submitting an enhancement suggestion for Nestri, including completely new features and minor improvements to existing functionality.
|
||||
|
||||
- Use a clear and descriptive title for the issue to identify the suggestion.
|
||||
- Provide a step-by-step description of the suggested enhancement in as many details as possible.
|
||||
- Provide specific examples to demonstrate the steps.
|
||||
|
||||
### Pull Requests
|
||||
|
||||
- Fill in the required template
|
||||
- Do not include issue numbers in the PR title
|
||||
- Include screenshots and animated GIFs in your pull request whenever possible.
|
||||
- Follow the JavaScript/TypeScript styleguides.
|
||||
- End all files with a newline
|
||||
|
||||
## Styleguides
|
||||
|
||||
### Git Commit Messages
|
||||
|
||||
- Use the present tense ("Add feature" not "Added feature")
|
||||
- Use the imperative mood ("Move cursor to..." not "Moves cursor to...")
|
||||
- Limit the first line to 72 characters or less
|
||||
- Reference issues and pull requests liberally after the first line
|
||||
|
||||
### JavaScript/Typescript Styleguide
|
||||
|
||||
All JavaScript and Typescript must adhere to the eslint and TS rules set in `.eslintrc` and `tsconfig` respectively. Your build will fail, otherwise.
|
||||
|
||||
## Additional Notes
|
||||
|
||||
### Issue and Pull Request Labels
|
||||
|
||||
This section lists the labels we use to help us track and manage issues and pull requests.
|
||||
|
||||
* `🐛 fix` - Issues that are bugs.
|
||||
* `✨ feat` - Issues that are feature requests.
|
||||
* `📝 docs` - Issues or pull requests related to documentation.
|
||||
* `🔧 chore` - Pull requests that add or update configuration files
|
||||
* `💄 style` - Issues or Pull requests related to the UI or style files
|
||||
* `⚡ perf` - Issues or Pull Requests that are related to performance
|
||||
* `♻ refactor` - Issues or Pull Requests related to code refactors
|
||||
* `good first issue` - Good for newcomers.
|
||||
|
||||
## Project Structure
|
||||
|
||||
Nestri is organized as a monorepo using Turborepo. Here's an overview of the main directories and their purposes:
|
||||
|
||||
### Root Directory
|
||||
|
||||
- `apps/`: Contains the main applications
|
||||
- `www/`: The main Nestri website built with Qwik
|
||||
- `infra/`: Contains the relevant files to deploy the app using [SST](https://sst.dev)
|
||||
- `packages/`: Shared packages and configurations
|
||||
- `api/`: Core API for Nestri
|
||||
- `eslint-config/`: Shared ESLint configurations
|
||||
- `typescript-config/`: Shared TypeScript configurations
|
||||
- `ui/`: Shared UI components and styles
|
||||
|
||||
### Key Files
|
||||
|
||||
- `package.json`: Root package file defining workspaces and shared dev dependencies
|
||||
- `turbo.json`: Turborepo configuration
|
||||
- `LICENSE`: GNU Affero General Public License v3.0
|
||||
|
||||
### Apps
|
||||
|
||||
#### www (Nestri Website)
|
||||
|
||||
This is the Nestri website hosted on Cloudflare Pages
|
||||
|
||||
### Packages
|
||||
|
||||
#### api (Nestri Core)
|
||||
|
||||
The core API for Nestri, built with Hono and deployed to Cloudflare Workers.
|
||||
|
||||
#### eslint-config
|
||||
|
||||
Shared ESLint configurations for maintaining consistent code style across the project.
|
||||
|
||||
#### typescript-config
|
||||
|
||||
Shared TypeScript configurations to ensure consistent TypeScript settings across the project.
|
||||
|
||||
#### ui
|
||||
|
||||
Shared UI components and styles used across the Nestri project.
|
||||
|
||||
### Infrastructure
|
||||
|
||||
- `infra/`: Contains infrastructure-as-code files
|
||||
- `www.ts`: Defines the deployment configuration for the Nestri website
|
||||
|
||||
### Development
|
||||
|
||||
When working on Nestri, you'll primarily be dealing with the `apps/www` directory for the main website and the various packages in the `packages/` directory for shared functionality.
|
||||
|
||||
For more detailed information about each package or app, refer to their respective README files or package.json scripts.
|
||||
|
||||
|
||||
Thank you for contributing to Nestri!
|
||||
17
Cargo.toml
17
Cargo.toml
@@ -1,17 +0,0 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"packages/server",
|
||||
"packages/relay/dev"
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.0-alpha.1"
|
||||
repository = "https://github.com/nestriness/nestri"
|
||||
edition = "2021"
|
||||
rust-version = "1.80"
|
||||
|
||||
[workspace.dependencies]
|
||||
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main", features = ["v1_24"] }
|
||||
gst-webrtc = { package = "gstreamer-webrtc", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main", features = ["v1_24"] }
|
||||
gstrswebrtc = { package = "gst-plugin-webrtc", git = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs", branch = "main", features = ["v1_22"] }
|
||||
@@ -2,173 +2,252 @@
|
||||
ARG BASE_IMAGE=docker.io/cachyos/cachyos:latest
|
||||
|
||||
#******************************************************************************
|
||||
# nestri-server-builder
|
||||
# base-builder
|
||||
#******************************************************************************
|
||||
FROM ${BASE_IMAGE} AS gst-builder
|
||||
WORKDIR /builder/
|
||||
FROM ${BASE_IMAGE} AS base-builder
|
||||
|
||||
# Grab build and rust packages #
|
||||
RUN pacman -Sy --noconfirm meson pkgconf cmake git gcc make rustup \
|
||||
gstreamer gst-plugins-base gst-plugins-good gst-plugin-rswebrtc
|
||||
|
||||
# Setup stable rust toolchain #
|
||||
RUN rustup default stable
|
||||
|
||||
#Copy the whole repo inside the build container
|
||||
# COPY ./ /builder/nestri/
|
||||
# Install mold linker and sccache upfront
|
||||
RUN pacman -Sy --noconfirm mold && \
|
||||
pacman -S --noconfirm rust && \
|
||||
cargo install -j $(nproc) --root /usr/local sccache
|
||||
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
cargo install --locked cargo-chef
|
||||
|
||||
ENV ARTIFACTS=/artifacts
|
||||
RUN mkdir -p /artifacts
|
||||
|
||||
#******************************************************************************
|
||||
# nestri-server-builder
|
||||
#******************************************************************************
|
||||
# FROM base-builder AS nestri-server-builder
|
||||
# WORKDIR /builder/
|
||||
|
||||
RUN --mount=type=bind,target=/builder/nestri/,rw \
|
||||
--mount=type=cache,target=/builder/nestri/target/ \
|
||||
--mount=type=cache,target=/usr/local/cargo/git/db \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry/ \
|
||||
cd /builder/nestri/packages/server/ \
|
||||
&& cargo build --release \
|
||||
&& cp /builder/nestri/target/release/nestri-server /artifacts/
|
||||
# RUN pacman -Sy --noconfirm meson pkgconf cmake git gcc make \
|
||||
# gstreamer gst-plugins-base gst-plugins-good gst-plugin-rswebrtc
|
||||
|
||||
#******************************************************************************
|
||||
# gstwayland-builder
|
||||
# nestri-server-planner
|
||||
#******************************************************************************
|
||||
FROM ${BASE_IMAGE} AS gstwayland-builder
|
||||
|
||||
# FROM nestri-server-builder AS nestri-server-planner
|
||||
# WORKDIR /builder/nestri/
|
||||
# COPY packages/server/Cargo.toml packages/server/Cargo.lock ./
|
||||
# RUN --mount=type=cache,target=/root/.cache/sccache \
|
||||
# --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
# --mount=type=cache,target=/tmp \
|
||||
# export RUSTC_WRAPPER=/usr/local/bin/sccache && \
|
||||
# cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
#******************************************************************************
|
||||
# nestri-server-cacher
|
||||
#******************************************************************************
|
||||
# FROM nestri-server-builder AS nestri-server-cacher
|
||||
# WORKDIR /builder/nestri/
|
||||
|
||||
# COPY --from=nestri-server-planner /builder/nestri/recipe.json .
|
||||
# RUN --mount=type=cache,target=/root/.cache/sccache \
|
||||
# --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
# --mount=type=cache,target=/tmp \
|
||||
# export RUSTC_WRAPPER=/usr/local/bin/sccache && \
|
||||
# cargo chef cook --release --recipe-path recipe.json
|
||||
|
||||
#******************************************************************************
|
||||
# nestri-server-build
|
||||
#******************************************************************************
|
||||
# FROM nestri-server-builder AS nestri-server-build
|
||||
# WORKDIR /builder/nestri/
|
||||
|
||||
# COPY --from=nestri-server-cacher /builder/nestri/target target
|
||||
# COPY packages/server/ ./packages/server/
|
||||
|
||||
# RUN --mount=type=cache,target=/root/.cache/sccache \
|
||||
# --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
# --mount=type=cache,target=/tmp \
|
||||
# export RUSTC_WRAPPER=/usr/local/bin/sccache && \
|
||||
# export CARGO_BUILD_JOBS=$(nproc) && \
|
||||
# export RUSTFLAGS="-C link-arg=-fuse-ld=mold -C target-cpu=native" && \
|
||||
# cargo build --release && \
|
||||
# cp target/release/nestri-server "$ARTIFACTS"
|
||||
|
||||
#******************************************************************************
|
||||
# gst-wayland-builder
|
||||
#******************************************************************************
|
||||
FROM base-builder AS gst-wayland-builder
|
||||
WORKDIR /builder/
|
||||
|
||||
# Grab build and rust packages #
|
||||
RUN pacman -Sy --noconfirm meson pkgconf cmake git gcc make rustup \
|
||||
libxkbcommon wayland gstreamer gst-plugins-base gst-plugins-good libinput
|
||||
RUN pacman -Sy --noconfirm meson pkgconf cmake git gcc make \
|
||||
libxkbcommon wayland gstreamer gst-plugins-base gst-plugins-good libinput
|
||||
|
||||
# Setup stable rust toolchain #
|
||||
RUN rustup default stable
|
||||
# Build required cargo-c package #
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/git/db \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry/ \
|
||||
--mount=type=cache,target=/root/.cargo/bin/ \
|
||||
cargo install cargo-c
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
cargo install --locked cargo-c
|
||||
|
||||
# Clone gst plugin source #
|
||||
RUN git clone https://github.com/games-on-whales/gst-wayland-display.git
|
||||
|
||||
# Build gst plugin #
|
||||
RUN mkdir plugin
|
||||
|
||||
RUN mkdir -p /artifacts
|
||||
|
||||
#******************************************************************************
|
||||
# gst-wayland-planner
|
||||
#******************************************************************************
|
||||
FROM gst-wayland-builder AS gst-wayland-planner
|
||||
WORKDIR /builder/gst-wayland-display
|
||||
|
||||
RUN --mount=type=cache,target=/builder/gst-wayland-display/target/ \
|
||||
--mount=type=cache,target=/root/.cargo/bin/ \
|
||||
RUN --mount=type=cache,target=/root/.cache/sccache \
|
||||
--mount=type=cache,target=/tmp \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/builder/plugin/ \
|
||||
--mount=type=cache,target=/usr/local/cargo/git/db \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry/ \
|
||||
cargo cinstall --prefix=/builder/plugin/ \
|
||||
&& cp -r /builder/plugin/ /artifacts/
|
||||
export RUSTC_WRAPPER=/usr/local/bin/sccache && \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
#******************************************************************************
|
||||
# runtime
|
||||
# gst-wayland-cacher
|
||||
#******************************************************************************
|
||||
FROM gst-wayland-builder AS gst-wayland-cacher
|
||||
|
||||
COPY --from=gst-wayland-planner /builder/gst-wayland-display/recipe.json .
|
||||
|
||||
RUN --mount=type=cache,target=/root/.cache/sccache \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/builder/target \
|
||||
--mount=type=cache,target=/builder/plugin/ \
|
||||
--mount=type=cache,target=/tmp \
|
||||
export CARGO_TARGET_DIR=/builder/target \
|
||||
export RUSTC_WRAPPER=/usr/local/bin/sccache && \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
cargo chef cook --release --recipe-path recipe.json
|
||||
|
||||
#******************************************************************************
|
||||
# gst-wayland-build
|
||||
#******************************************************************************
|
||||
|
||||
FROM gst-wayland-builder AS gst-wayland-build
|
||||
WORKDIR /builder/gst-wayland-display
|
||||
|
||||
COPY --from=gst-wayland-cacher /builder/ /builder/
|
||||
COPY . .
|
||||
|
||||
RUN --mount=type=cache,target=/root/.cache/sccache \
|
||||
--mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/builder/plugin/ \
|
||||
--mount=type=cache,target=/builder/target \
|
||||
export RUSTC_WRAPPER=/usr/local/bin/sccache \
|
||||
export CARGO_TARGET_DIR=/builder/target \
|
||||
export CARGO_BUILD_JOBS=$(nproc) \
|
||||
export RUSTFLAGS="-C link-arg=-fuse-ld=mold" && \
|
||||
CARGO_HOME=/usr/local/cargo \
|
||||
cargo cinstall --prefix=/builder/plugin/ --release && \
|
||||
cp -r /builder/plugin/ "$ARTIFACTS"
|
||||
|
||||
|
||||
#******************************************************************************
|
||||
# runtime
|
||||
#******************************************************************************
|
||||
FROM ${BASE_IMAGE} AS runtime
|
||||
|
||||
## Install Graphics, Media, and Audio packages ##
|
||||
RUN sed -i '/#\[multilib\]/,/#Include = \/etc\/pacman.d\/mirrorlist/ s/#//' /etc/pacman.conf && \
|
||||
sed -i "s/#Color/Color/" /etc/pacman.conf && \
|
||||
pacman --noconfirm -Syu archlinux-keyring && \
|
||||
dirmngr </dev/null > /dev/null 2>&1 && \
|
||||
# Install mesa-git before Steam for simplicity
|
||||
pacman --noconfirm -Sy mesa && \
|
||||
# Install Steam
|
||||
pacman --noconfirm -Sy steam steam-native-runtime && \
|
||||
# Clean up pacman cache
|
||||
paccache -rk1 && \
|
||||
rm -rf /usr/share/info/* && \
|
||||
rm -rf /usr/share/man/* && \
|
||||
rm -rf /usr/share/doc/
|
||||
# ## Install Graphics, Media, and Audio packages ##
|
||||
# RUN sed -i '/#\[multilib\]/,/#Include = \/etc\/pacman.d\/mirrorlist/ s/#//' /etc/pacman.conf && \
|
||||
# sed -i "s/#Color/Color/" /etc/pacman.conf && \
|
||||
# pacman --noconfirm -Syu archlinux-keyring && \
|
||||
# dirmngr </dev/null > /dev/null 2>&1 && \
|
||||
# # Install mesa-git before Steam for simplicity
|
||||
# pacman --noconfirm -Sy mesa && \
|
||||
# # Install Steam
|
||||
# pacman --noconfirm -Sy steam steam-native-runtime && \
|
||||
# # Clean up pacman cache
|
||||
# paccache -rk1 && \
|
||||
# rm -rf /usr/share/info/* && \
|
||||
# rm -rf /usr/share/man/* && \
|
||||
# rm -rf /usr/share/doc/
|
||||
|
||||
RUN pacman -Sy --noconfirm --needed \
|
||||
# Graphics packages
|
||||
sudo xorg-xwayland labwc wlr-randr mangohud \
|
||||
# GStreamer and plugins
|
||||
gstreamer gst-plugins-base gst-plugins-good \
|
||||
gst-plugins-bad gst-plugin-pipewire \
|
||||
gst-plugin-rswebrtc gst-plugin-rsrtp \
|
||||
# Audio packages
|
||||
pipewire pipewire-pulse pipewire-alsa wireplumber \
|
||||
# Non-latin fonts
|
||||
noto-fonts-cjk \
|
||||
# Other requirements
|
||||
supervisor jq chwd lshw pacman-contrib && \
|
||||
# Clean up pacman cache
|
||||
paccache -rk1 && \
|
||||
rm -rf /usr/share/info/* && \
|
||||
rm -rf /usr/share/man/* && \
|
||||
rm -rf /usr/share/doc/*
|
||||
# RUN pacman -Sy --noconfirm --needed \
|
||||
# # Graphics packages
|
||||
# sudo xorg-xwayland labwc wlr-randr mangohud \
|
||||
# # GStreamer and plugins
|
||||
# gstreamer gst-plugins-base gst-plugins-good \
|
||||
# gst-plugins-bad gst-plugin-pipewire \
|
||||
# gst-plugin-rswebrtc gst-plugin-rsrtp \
|
||||
# # Audio packages
|
||||
# pipewire pipewire-pulse pipewire-alsa wireplumber \
|
||||
# # Non-latin fonts
|
||||
# noto-fonts-cjk \
|
||||
# # Other requirements
|
||||
# supervisor jq chwd lshw pacman-contrib && \
|
||||
# # Clean up pacman cache
|
||||
# paccache -rk1 && \
|
||||
# rm -rf /usr/share/info/* && \
|
||||
# rm -rf /usr/share/man/* && \
|
||||
# rm -rf /usr/share/doc/*
|
||||
|
||||
#Install our backup manager
|
||||
ARG LUDUSAVI_VERSION="0.28.0"
|
||||
RUN pacman -Sy --noconfirm --needed wget &&\
|
||||
wget "https://github.com/mtkennerly/ludusavi/releases/download/v${LUDUSAVI_VERSION}/ludusavi-v${LUDUSAVI_VERSION}-linux.tar.gz" -O "ludusavi.tar.gz" &&\
|
||||
tar -xzvf ludusavi.tar.gz &&\
|
||||
mv ludusavi /usr/bin/ &&\
|
||||
#Clean up
|
||||
rm *.tar.gz
|
||||
# #Install our backup manager
|
||||
# ARG LUDUSAVI_VERSION="0.28.0"
|
||||
# RUN pacman -Sy --noconfirm --needed curl &&\
|
||||
# curl -fsSL -o ludusavi.tar.gz "https://github.com/mtkennerly/ludusavi/releases/download/v${LUDUSAVI_VERSION}/ludusavi-v${LUDUSAVI_VERSION}-linux.tar.gz" &&\
|
||||
# tar -xzvf ludusavi.tar.gz &&\
|
||||
# mv ludusavi /usr/bin/ &&\
|
||||
# #Clean up
|
||||
# rm *.tar.gz
|
||||
|
||||
# Regenerate locale
|
||||
RUN locale-gen
|
||||
# # Regenerate locale
|
||||
# RUN locale-gen
|
||||
|
||||
## User ##
|
||||
# Create and setup user #
|
||||
ENV USER="nestri" \
|
||||
UID=1000 \
|
||||
GID=1000 \
|
||||
USER_PWD="nestri1234"
|
||||
# ## User ##
|
||||
# # Create and setup user #
|
||||
# ENV USER="nestri" \
|
||||
# UID=1000 \
|
||||
# GID=1000 \
|
||||
# USER_PWD="nestri1234"
|
||||
|
||||
RUN mkdir -p /home/${USER} && \
|
||||
groupadd -g ${GID} ${USER} && \
|
||||
useradd -d /home/${USER} -u ${UID} -g ${GID} -s /bin/bash ${USER} && \
|
||||
chown -R ${USER}:${USER} /home/${USER} && \
|
||||
echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
|
||||
echo "${USER}:${USER_PWD}" | chpasswd
|
||||
# RUN mkdir -p /home/${USER} && \
|
||||
# groupadd -g ${GID} ${USER} && \
|
||||
# useradd -d /home/${USER} -u ${UID} -g ${GID} -s /bin/bash ${USER} && \
|
||||
# chown -R ${USER}:${USER} /home/${USER} && \
|
||||
# echo "${USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers && \
|
||||
# echo "${USER}:${USER_PWD}" | chpasswd
|
||||
|
||||
# Run directory #
|
||||
RUN mkdir -p /run/user/${UID} && \
|
||||
chown ${USER}:${USER} /run/user/${UID}
|
||||
# # Run directory #
|
||||
# RUN mkdir -p /run/user/${UID} && \
|
||||
# chown ${USER}:${USER} /run/user/${UID}
|
||||
|
||||
# Groups #
|
||||
RUN usermod -aG input root && usermod -aG input ${USER} && \
|
||||
usermod -aG video root && usermod -aG video ${USER} && \
|
||||
usermod -aG render root && usermod -aG render ${USER} && \
|
||||
usermod -aG seat root && usermod -aG seat ${USER}
|
||||
# # Groups #
|
||||
# RUN usermod -aG input root && usermod -aG input ${USER} && \
|
||||
# usermod -aG video root && usermod -aG video ${USER} && \
|
||||
# usermod -aG render root && usermod -aG render ${USER} && \
|
||||
# usermod -aG seat root && usermod -aG seat ${USER}
|
||||
|
||||
## Copy files from builders ##
|
||||
# this is done here at end to not trigger full rebuild on changes to builder
|
||||
# nestri
|
||||
COPY --from=gst-builder /artifacts/nestri-server /usr/bin/nestri-server
|
||||
# ## Copy files from builders ##
|
||||
# # this is done here at end to not trigger full rebuild on changes to builder
|
||||
# # nestri
|
||||
# COPY --from=nestri-server-build /artifacts/nestri-server /usr/bin/nestri-server
|
||||
# gstwayland
|
||||
COPY --from=gstwayland-builder /artifacts/plugin/include/libgstwaylanddisplay /usr/include/
|
||||
COPY --from=gstwayland-builder /artifacts/plugin/lib/*libgstwayland* /usr/lib/
|
||||
COPY --from=gstwayland-builder /artifacts/plugin/lib/gstreamer-1.0/libgstwayland* /usr/lib/gstreamer-1.0/
|
||||
COPY --from=gstwayland-builder /artifacts/plugin/lib/pkgconfig/gstwayland* /usr/lib/pkgconfig/
|
||||
COPY --from=gstwayland-builder /artifacts/plugin/lib/pkgconfig/libgstwayland* /usr/lib/pkgconfig/
|
||||
COPY --from=gst-wayland-build /artifacts/plugin/include/libgstwaylanddisplay /usr/include/
|
||||
COPY --from=gst-wayland-build /artifacts/plugin/lib/*libgstwayland* /usr/lib/
|
||||
COPY --from=gst-wayland-build /artifacts/plugin/lib/gstreamer-1.0/libgstwayland* /usr/lib/gstreamer-1.0/
|
||||
COPY --from=gst-wayland-build /artifacts/plugin/lib/pkgconfig/gstwayland* /usr/lib/pkgconfig/
|
||||
COPY --from=gst-wayland-build /artifacts/plugin/lib/pkgconfig/libgstwayland* /usr/lib/pkgconfig/
|
||||
|
||||
## Copy scripts ##
|
||||
COPY packages/scripts/ /etc/nestri/
|
||||
# Set scripts as executable #
|
||||
RUN chmod +x /etc/nestri/envs.sh /etc/nestri/entrypoint.sh /etc/nestri/entrypoint_nestri.sh
|
||||
# ## Copy scripts ##
|
||||
# COPY packages/scripts/ /etc/nestri/
|
||||
# # Set scripts as executable #
|
||||
# RUN chmod +x /etc/nestri/envs.sh /etc/nestri/entrypoint.sh /etc/nestri/entrypoint_nestri.sh
|
||||
|
||||
## Set runtime envs ##
|
||||
ENV XDG_RUNTIME_DIR=/run/user/${UID} \
|
||||
HOME=/home/${USER}
|
||||
# ## Set runtime envs ##
|
||||
# ENV XDG_RUNTIME_DIR=/run/user/${UID} \
|
||||
# HOME=/home/${USER}
|
||||
|
||||
# Required for NVIDIA.. they want to be special like that #
|
||||
ENV NVIDIA_DRIVER_CAPABILITIES=all
|
||||
ENV NVIDIA_VISIBLE_DEVICES=all
|
||||
# # Required for NVIDIA.. they want to be special like that #
|
||||
# ENV NVIDIA_DRIVER_CAPABILITIES=all
|
||||
# ENV NVIDIA_VISIBLE_DEVICES=all
|
||||
|
||||
# DBus run directory creation #
|
||||
RUN mkdir -p /run/dbus
|
||||
# # DBus run directory creation #
|
||||
# RUN mkdir -p /run/dbus
|
||||
|
||||
# Wireplumber disable suspend #
|
||||
# Remove suspend node
|
||||
RUN sed -z -i 's/{[[:space:]]*name = node\/suspend-node\.lua,[[:space:]]*type = script\/lua[[:space:]]*provides = hooks\.node\.suspend[[:space:]]*}[[:space:]]*//g' /usr/share/wireplumber/wireplumber.conf
|
||||
# Remove "hooks.node.suspend" want
|
||||
RUN sed -i '/wants = \[/{s/hooks\.node\.suspend\s*//; s/,\s*\]/]/}' /usr/share/wireplumber/wireplumber.conf
|
||||
# # Wireplumber disable suspend #
|
||||
# # Remove suspend node
|
||||
# RUN sed -z -i 's/{[[:space:]]*name = node\/suspend-node\.lua,[[:space:]]*type = script\/lua[[:space:]]*provides = hooks\.node\.suspend[[:space:]]*}[[:space:]]*//g' /usr/share/wireplumber/wireplumber.conf
|
||||
# # Remove "hooks.node.suspend" want
|
||||
# RUN sed -i '/wants = \[/{s/hooks\.node\.suspend\s*//; s/,\s*\]/]/}' /usr/share/wireplumber/wireplumber.conf
|
||||
|
||||
ENTRYPOINT ["supervisord", "-c", "/etc/nestri/supervisord.conf"]
|
||||
# ENTRYPOINT ["supervisord", "-c", "/etc/nestri/supervisord.conf"]
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
"@pulumi/pulumi": "^3.134.0",
|
||||
"@types/aws-lambda": "8.10.145",
|
||||
"prettier": "^3.2.5",
|
||||
"turbo": "^2.0.12",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
[package]
|
||||
name = "dev"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
name = "nestri-test-server"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
webrtc = "0.11.0"
|
||||
tokio = { version = "1.41.1", features = ["full"] }
|
||||
reqwest = { version = "0.12", features = ["json"] }
|
||||
serde = { version = "1.0.215", features = ["derive"]}
|
||||
serde_json = "1.0.133"
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
FROM archlinux:latest
|
||||
|
||||
RUN pacman -Syu --noconfirm
|
||||
|
||||
RUN pacman -Su --noconfirm \
|
||||
gstreamer gst-plugins-base gst-plugins-good gst-plugin-rswebrtc
|
||||
|
||||
RUN pacman -Syu --noconfirm \
|
||||
mesa mesa-utils xorg-xwayland vulkan-intel vpl-gpu-rt intel-media-driver gst-plugin-va gst-plugins-bad gst-plugin-fmp4 gst-plugin-qsv gst-plugin-pipewire
|
||||
|
||||
CMD [ "bash","-c", "gst-launch-1.0 videotestsrc ! openh264enc ! whip0. audiotestsrc ! opusenc ! whip0. whipclientsink name=whip0 signaller::whip-endpoint=http://localhost:8088/api/whip/test" ]
|
||||
@@ -1,17 +0,0 @@
|
||||
#! /bin/bash -e
|
||||
|
||||
# sudo apt install build-essential -y
|
||||
|
||||
# To run tests, run the relay first - go run main.go.
|
||||
# Run the docker container next - docker run --rm --init -d --device /dev/dri --network=host test-server
|
||||
# Then run the nestri-test-server - cd packages/relay/dev cargo run
|
||||
# Then run the frontend site, and navigate to http://localhost:5713/play/test
|
||||
|
||||
# Expected behavior, see some random messages on the browser's console tab
|
||||
# And if you input works correctly, it should be logged to the console on the server-side of things
|
||||
|
||||
# docker build -t test-server -f Containerfile .
|
||||
|
||||
# docker run --rm --init -d --device /dev/dri --network=host test-server
|
||||
|
||||
# echo -e "Navigate to http://localhost:5713/play/test"
|
||||
@@ -1,11 +0,0 @@
|
||||
mod room;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> std::io::Result<()> {
|
||||
let room = "test";
|
||||
let base_url = "http://localhost:8088";
|
||||
let mut room_handler = room::Room::new(room, base_url).await?;
|
||||
room_handler.run().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,292 +0,0 @@
|
||||
use reqwest;
|
||||
use std::collections::HashSet;
|
||||
use std::io;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::mpsc;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio::time::Duration;
|
||||
use webrtc::api::interceptor_registry::register_default_interceptors;
|
||||
// use std::collections::HashSet;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::from_str;
|
||||
use webrtc::api::media_engine::MediaEngine;
|
||||
use webrtc::api::APIBuilder;
|
||||
use webrtc::data_channel::data_channel_message::DataChannelMessage;
|
||||
use webrtc::ice_transport::ice_server::RTCIceServer;
|
||||
use webrtc::interceptor::registry::Registry;
|
||||
use webrtc::peer_connection::configuration::RTCConfiguration;
|
||||
use webrtc::peer_connection::math_rand_alpha;
|
||||
use webrtc::peer_connection::peer_connection_state::RTCPeerConnectionState;
|
||||
use webrtc::peer_connection::sdp::session_description::RTCSessionDescription;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(tag = "type")]
|
||||
enum InputMessage {
|
||||
#[serde(rename = "mousemove")]
|
||||
MouseMove { x: i32, y: i32 },
|
||||
|
||||
#[serde(rename = "mousemoveabs")]
|
||||
MouseMoveAbs { x: i32, y: i32 },
|
||||
|
||||
#[serde(rename = "wheel")]
|
||||
Wheel { x: f64, y: f64 },
|
||||
|
||||
#[serde(rename = "mousedown")]
|
||||
MouseDown { key: i32 },
|
||||
// Add other variants as needed
|
||||
#[serde(rename = "mouseup")]
|
||||
MouseUp { key: i32 },
|
||||
|
||||
#[serde(rename = "keydown")]
|
||||
KeyDown { key: i32 },
|
||||
|
||||
#[serde(rename = "keyup")]
|
||||
KeyUp { key: i32 },
|
||||
}
|
||||
|
||||
pub struct Room {
|
||||
peer_connection: Arc<webrtc::peer_connection::RTCPeerConnection>,
|
||||
data_channel: Arc<webrtc::data_channel::RTCDataChannel>,
|
||||
done_tx: mpsc::Sender<()>,
|
||||
done_rx: mpsc::Receiver<()>,
|
||||
base_url: String,
|
||||
stream_name: String,
|
||||
// pipeline: Arc<Mutex<gst::Pipeline>>,
|
||||
}
|
||||
|
||||
impl Room {
|
||||
pub async fn new(
|
||||
stream_name: &str,
|
||||
base_url: &str,
|
||||
// pipeline: Arc<Mutex<gst::Pipeline>>,
|
||||
) -> io::Result<Self> {
|
||||
// Create a MediaEngine object to configure the supported codec
|
||||
let mut m = MediaEngine::default();
|
||||
|
||||
// Register default codecs
|
||||
let _ = m.register_default_codecs().map_err(map_to_io_error)?;
|
||||
|
||||
let mut registry = Registry::new();
|
||||
|
||||
// Use the default set of Interceptors
|
||||
registry = register_default_interceptors(registry, &mut m).map_err(map_to_io_error)?;
|
||||
|
||||
// Create the API object with the MediaEngine
|
||||
let api = APIBuilder::new()
|
||||
.with_media_engine(m)
|
||||
.with_interceptor_registry(registry)
|
||||
.build();
|
||||
|
||||
// Prepare the configuration
|
||||
let config = RTCConfiguration {
|
||||
ice_servers: vec![RTCIceServer {
|
||||
urls: vec!["stun:stun.l.google.com:19302".to_owned()],
|
||||
..Default::default()
|
||||
}],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
// Create a new RTCPeerConnection
|
||||
let peer_connection = Arc::new(
|
||||
api.new_peer_connection(config)
|
||||
.await
|
||||
.map_err(map_to_io_error)?,
|
||||
);
|
||||
|
||||
// Create a datachannel with label 'data'
|
||||
let data_channel = peer_connection
|
||||
.create_data_channel("input", None)
|
||||
.await
|
||||
.map_err(map_to_io_error)?;
|
||||
|
||||
let (done_tx, done_rx) = mpsc::channel::<()>(1);
|
||||
|
||||
let done_tx_clone = done_tx.clone();
|
||||
// Peer connection state change handler
|
||||
peer_connection.on_peer_connection_state_change(Box::new(
|
||||
move |s: RTCPeerConnectionState| {
|
||||
println!("Peer Connection State has changed: {s}");
|
||||
|
||||
if s == RTCPeerConnectionState::Failed {
|
||||
println!("Peer Connection has gone to failed exiting");
|
||||
let _ = done_tx_clone.try_send(());
|
||||
}
|
||||
|
||||
Box::pin(async {})
|
||||
},
|
||||
));
|
||||
|
||||
Ok(Self {
|
||||
peer_connection,
|
||||
// pipeline,
|
||||
data_channel,
|
||||
done_tx,
|
||||
done_rx,
|
||||
base_url: base_url.to_string(),
|
||||
stream_name: stream_name.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn run(&mut self) -> io::Result<()> {
|
||||
// Create an async channel for sending events to the pipeline
|
||||
let (event_tx, mut event_rx) = mpsc::channel(10);
|
||||
|
||||
// A shared state to track currently pressed keys
|
||||
let pressed_keys = Arc::new(tokio::sync::Mutex::new(HashSet::new()));
|
||||
|
||||
// Spawn a task to process events for the pipeline
|
||||
let pipeline_task = {
|
||||
// let pipeline = Arc::clone(self.pipeline);
|
||||
// let pipeline_clone = self.pipeline.clone();
|
||||
tokio::spawn(async move {
|
||||
while let Some(event) = event_rx.recv().await {
|
||||
// let pipeline = pipeline_clone.lock().await;
|
||||
// pipeline.send_event(event);
|
||||
println!("Invoked an event: {}", event)
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
let data_channel = self.data_channel.clone();
|
||||
//TODO: Handle heartbeats here
|
||||
let d1 = Arc::clone(&self.data_channel);
|
||||
data_channel.on_open(Box::new(move || {
|
||||
println!("Data channel '{}'-'{}' open. Random messages will now be sent to any connected DataChannels every 5 seconds", d1.label(), d1.id());
|
||||
|
||||
let d2 = Arc::clone(&d1);
|
||||
Box::pin(async move {
|
||||
let mut result = std::io::Result::<usize>::Ok(0);
|
||||
while result.is_ok() {
|
||||
let timeout = tokio::time::sleep(Duration::from_secs(5));
|
||||
tokio::pin!(timeout);
|
||||
|
||||
tokio::select! {
|
||||
_ = timeout.as_mut() =>{
|
||||
let message = math_rand_alpha(15);
|
||||
println!("Sending '{message}'");
|
||||
result = d2.send_text(message).await.map_err(map_to_io_error);
|
||||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
}));
|
||||
|
||||
// Data channel message handler
|
||||
let d_label = data_channel.label().to_owned();
|
||||
data_channel.on_message(Box::new(move |msg: DataChannelMessage| {
|
||||
let msg_str = String::from_utf8(msg.data.to_vec()).unwrap();
|
||||
println!("Message from DataChannel '{d_label}': '{msg_str}'");
|
||||
|
||||
let event_tx = event_tx.clone();
|
||||
let pressed_keys = Arc::clone(&pressed_keys);
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Ok(input_msg) = from_str::<InputMessage>(&msg_str) {
|
||||
if let Some(event) = handle_input_message(input_msg, &pressed_keys).await {
|
||||
event_tx.send(event).await.unwrap();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Box::pin(async {})
|
||||
}));
|
||||
|
||||
// Create an offer to send to the browser
|
||||
let offer = self
|
||||
.peer_connection
|
||||
.create_offer(None)
|
||||
.await
|
||||
.map_err(map_to_io_error)?;
|
||||
|
||||
// Create channel that is blocked until ICE Gathering is complete
|
||||
let mut gather_complete = self.peer_connection.gathering_complete_promise().await;
|
||||
|
||||
// Sets the LocalDescription, and starts our UDP listeners
|
||||
self.peer_connection
|
||||
.set_local_description(offer)
|
||||
.await
|
||||
.map_err(map_to_io_error)?;
|
||||
|
||||
// Block until ICE Gathering is complete, disabling trickle ICE
|
||||
// we do this because we only can exchange one signaling message
|
||||
// in a production application you should exchange ICE Candidates via OnICECandidate
|
||||
let _ = gather_complete.recv().await;
|
||||
|
||||
if let Some(local_description) = self.peer_connection.local_description().await {
|
||||
let url = format!("{}/api/whep/{}", self.base_url, self.stream_name);
|
||||
let response = reqwest::Client::new()
|
||||
.post(&url)
|
||||
.header("Content-Type", "application/sdp")
|
||||
.body(local_description.sdp.clone()) // clone if you don't want to move offer.sdp
|
||||
.send()
|
||||
.await
|
||||
.map_err(map_to_io_error)?;
|
||||
|
||||
let answer = response
|
||||
.json::<RTCSessionDescription>()
|
||||
.await
|
||||
.map_err(map_to_io_error)?;
|
||||
|
||||
self.peer_connection
|
||||
.set_remote_description(answer)
|
||||
.await
|
||||
.map_err(map_to_io_error)?;
|
||||
} else {
|
||||
println!("generate local_description failed!");
|
||||
};
|
||||
|
||||
println!("Press ctrl-c to stop");
|
||||
|
||||
tokio::select! {
|
||||
_ = self.done_rx.recv() => {
|
||||
println!("received done signal!");
|
||||
}
|
||||
_ = tokio::signal::ctrl_c() => {
|
||||
println!();
|
||||
}
|
||||
};
|
||||
self.peer_connection
|
||||
.close()
|
||||
.await
|
||||
.map_err(map_to_io_error)?;
|
||||
|
||||
//FIXME: Ctr + C is not working... i suspect it has something to do with this guy -- Do not forget to fix packages/server/room.rs as well
|
||||
|
||||
pipeline_task.await?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn map_to_io_error<E: std::fmt::Display>(e: E) -> io::Error {
|
||||
io::Error::new(io::ErrorKind::Other, format!("{}", e))
|
||||
}
|
||||
|
||||
async fn handle_input_message(
|
||||
input_msg: InputMessage,
|
||||
pressed_keys: &Arc<tokio::sync::Mutex<HashSet<i32>>>,
|
||||
) -> Option<String> {
|
||||
match input_msg {
|
||||
InputMessage::MouseMove { x, y } => Some("MouseMoved".to_string()),
|
||||
InputMessage::MouseMoveAbs { x, y } => Some("MouseMoveAbsolute".to_string()),
|
||||
InputMessage::KeyDown { key } => {
|
||||
let mut keys = pressed_keys.lock().await;
|
||||
// If the key is already pressed, return to prevent key lockup
|
||||
if keys.contains(&key) {
|
||||
return None;
|
||||
}
|
||||
keys.insert(key);
|
||||
|
||||
Some("KeyDown".to_string())
|
||||
}
|
||||
InputMessage::KeyUp { key } => {
|
||||
let mut keys = pressed_keys.lock().await;
|
||||
// Remove the key from the pressed state when released
|
||||
keys.remove(&key);
|
||||
|
||||
Some("KeyUp".to_string())
|
||||
}
|
||||
InputMessage::Wheel { x, y } => Some("Wheel".to_string()),
|
||||
InputMessage::MouseDown { key } => Some("MouseDown".to_string()),
|
||||
InputMessage::MouseUp { key } => Some("MouseUp".to_string()),
|
||||
}
|
||||
}
|
||||
1288
Cargo.lock → packages/server/Cargo.lock
generated
1288
Cargo.lock → packages/server/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nestri-server"
|
||||
version = "0.1.0"
|
||||
version = "0.1.0-alpha.2"
|
||||
edition = "2021"
|
||||
|
||||
[[bin]]
|
||||
@@ -8,9 +8,9 @@ name = "nestri-server"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
gst.workspace = true
|
||||
gst-webrtc.workspace = true
|
||||
gstrswebrtc.workspace = true
|
||||
gst = { package = "gstreamer", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main", features = ["v1_24"] }
|
||||
gst-webrtc = { package = "gstreamer-webrtc", git = "https://gitlab.freedesktop.org/gstreamer/gstreamer-rs", branch = "main", features = ["v1_24"] }
|
||||
gstrswebrtc = { package = "gst-plugin-webrtc", git = "https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs", branch = "main", features = ["v1_22"] }
|
||||
serde = {version = "1.0.214", features = ["derive"] }
|
||||
tokio = { version = "1.41.0", features = ["full"] }
|
||||
clap = { version = "4.5.20", features = ["env"] }
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
42
turbo.json
42
turbo.json
@@ -1,42 +0,0 @@
|
||||
{
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"globalDependencies": ["**/.env.*local"],
|
||||
"ui": "tui",
|
||||
"tasks": {
|
||||
"build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"inputs": [
|
||||
"$TURBO_DEFAULT$",
|
||||
".env*"
|
||||
],
|
||||
"outputs": [
|
||||
".next/**",
|
||||
"!.next/cache/**",
|
||||
"dist/**"
|
||||
]
|
||||
},
|
||||
"web#build": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"outputs": [
|
||||
"dist/**"
|
||||
]
|
||||
},
|
||||
"lint": {
|
||||
"dependsOn": [
|
||||
"^lint",
|
||||
"^build"
|
||||
]
|
||||
},
|
||||
"dev": {
|
||||
"cache": false,
|
||||
"persistent": true
|
||||
},
|
||||
"clean": {
|
||||
"cache": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user