mirror of
https://github.com/nestriness/nestri.git
synced 2025-12-11 00:05:36 +02:00
✨ feat(input): Migrate to moq for input transmission (#38)
## Description **What issue are you solving (or what feature are you adding) and how are you doing it?** We cannot use golang for our input binary as we will be redoing the Webtransport stack, plus we will have to use CGO in-order to hook into X11. Like what [neko](https://github.com/m1k1o/neko) does. However, we could go down the Rust route, where X11 mouse/keyboard drivers are in pretty, and moq-rs (the MoQ library using Webtransport) works really well. So, that is what am trying to do here; implement input using rust.
This commit is contained in:
191
.github/workflows/warp-input.yml
vendored
Normal file
191
.github/workflows/warp-input.yml
vendored
Normal file
@@ -0,0 +1,191 @@
|
||||
#Tabs not spaces, you moron :)
|
||||
|
||||
name: CI for netris:warp-input
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "warp-input.Dockerfile"
|
||||
- ".github/workflows/warp-input.yml"
|
||||
- "bin/input/**"
|
||||
schedule:
|
||||
- cron: 0 0 * * * # At the end of everyday
|
||||
workflow_dispatch:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- "warp-input.Dockerfile"
|
||||
- ".github/workflows/warp-input.yml"
|
||||
tags:
|
||||
- v*.*.*
|
||||
release:
|
||||
types: [published, created]
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: wanjohiryan/netris
|
||||
BASE_TAG_PREFIX: warp-input
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build-docker-pr:
|
||||
name: Build image on pr
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
-
|
||||
name: Setup Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: warp-input.Dockerfile
|
||||
context: ./
|
||||
push: false
|
||||
load: true
|
||||
tags: netris:warp-input
|
||||
|
||||
build-docker-main:
|
||||
name: Build image on merge to main
|
||||
if: ${{github.ref == 'refs/heads/main'}}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
steps:
|
||||
-
|
||||
name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
-
|
||||
name: Log into registry ${{ env.REGISTRY }}
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
-
|
||||
name: Extract Container metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ env.BASE_TAG_PREFIX }}
|
||||
#
|
||||
#tag on release, and a nightly build for 'dev'
|
||||
tags: |
|
||||
type=raw,value=nightly,enable={{is_default_branch}}
|
||||
type=ref,event=tag
|
||||
type=semver,pattern={{version}}
|
||||
type=semver,pattern={{major}}.{{minor}}
|
||||
type=semver,pattern={{major}}
|
||||
-
|
||||
name: Build Docker image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
file: warp-input.Dockerfile
|
||||
context: ./
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
build-warp-input-release:
|
||||
if: ${{ github.event_name == 'release' }}
|
||||
defaults:
|
||||
run:
|
||||
working-directory: bin/input
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
settings:
|
||||
- host: ubuntu-20.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
bundles: appimage
|
||||
asset_name: warp-input-ubuntu-amd64
|
||||
- host: windows-latest
|
||||
target: x86_64-pc-windows-msvc
|
||||
bundles: msi
|
||||
asset_name: warp-input-windows-amd64
|
||||
# - host: macos-latest
|
||||
# target: x86_64-apple-darwin
|
||||
# bundles: dmg
|
||||
# asset_name: warp-input-macos-amd64
|
||||
# - host: macos-latest
|
||||
# target: aarch64-apple-darwin
|
||||
# bundles: dmg
|
||||
# asset_name: warp-input-macos-apple-silicon
|
||||
# - host: ubuntu-20.04
|
||||
# target: x86_64-unknown-linux-musl
|
||||
# - host: ubuntu-20.04
|
||||
# target: aarch64-unknown-linux-gnu
|
||||
# - host: ubuntu-20.04
|
||||
# target: aarch64-unknown-linux-musl
|
||||
# - host: ubuntu-20.04
|
||||
# target: armv7-unknown-linux-gnueabihf
|
||||
name: Build warp-input on release
|
||||
runs-on: ${{ matrix.settings.host }}
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Rust
|
||||
id: toolchain
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: ${{ matrix.settings.target }}
|
||||
toolchain: stable
|
||||
components: clippy, rustfmt
|
||||
|
||||
- name: Cache Rust Dependencies
|
||||
uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
save-if: false
|
||||
prefix-key: 'v0-rust-deps'
|
||||
shared-key: ${{ matrix.settings.target }}
|
||||
|
||||
- name: Cargo build
|
||||
run: cargo build --target ${{ matrix.settings.target }} --release
|
||||
|
||||
- name: Copy and rename artifacts (Linux)
|
||||
if: ${{ matrix.settings.host == 'ubuntu-20.04' }}
|
||||
run: |
|
||||
cp target/${{ matrix.settings.target }}/release/warp-input ./warp-input
|
||||
|
||||
- name: Copy and rename artifacts (Windows)
|
||||
if: ${{ matrix.settings.host == 'windows-latest' }}
|
||||
run: |
|
||||
cp "target/${{ matrix.settings.target }}/release/warp-input.exe" ./warp-input.exe
|
||||
|
||||
- name: Copy and rename artifacts (macOS)
|
||||
if: ${{ matrix.settings.host == 'macos-latest' }}
|
||||
run: |
|
||||
cp target/${{ matrix.settings.target }}/release/warp-input ./warp-input
|
||||
|
||||
- name: Publish release for (${{ matrix.settings.host }})
|
||||
if: ${{ matrix.settings.host == 'windows-latest' }}
|
||||
uses: svenstaro/upload-release-action@2.9.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ./bin/input/warp-input.exe
|
||||
asset_name: ${{ matrix.settings.asset_name }}
|
||||
tag: ${{ github.ref }}
|
||||
|
||||
- name: Publish release for (${{ matrix.settings.host }})
|
||||
if: ${{ matrix.settings.host != 'windows-latest' }}
|
||||
uses: svenstaro/upload-release-action@2.9.0
|
||||
with:
|
||||
repo_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
file: ./bin/input/warp-input
|
||||
asset_name: ${{ matrix.settings.asset_name }}
|
||||
tag: ${{ github.ref }}
|
||||
1
bin/input/.gitignore
vendored
Normal file
1
bin/input/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/target
|
||||
1701
bin/input/Cargo.lock
generated
Normal file
1701
bin/input/Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
19
bin/input/Cargo.toml
Normal file
19
bin/input/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "warp-input"
|
||||
version = "0.0.1"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.82"
|
||||
clap = "4.5.4"
|
||||
enigo = "0.2.1"
|
||||
env_logger = "0.11.3"
|
||||
log = "0.4.21"
|
||||
moq-native = { git = "https://github.com/kixelated/moq-rs", version = "0.1.0" }
|
||||
moq-transport = { git = "https://github.com/kixelated/moq-rs", version = "0.5.0" }
|
||||
serde = { version="1.0.202" , features = ["derive"]}
|
||||
serde_json = "1.0.117"
|
||||
tokio = "1.37.0"
|
||||
tracing = "0.1.40"
|
||||
tracing-subscriber = "0.3.18"
|
||||
url = "2.5.0"
|
||||
@@ -1,3 +0,0 @@
|
||||
module github.com/wanjohiryan/netris
|
||||
|
||||
go 1.22.2
|
||||
@@ -1,7 +0,0 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("hello world")
|
||||
}
|
||||
43
bin/input/src/cli.rs
Normal file
43
bin/input/src/cli.rs
Normal file
@@ -0,0 +1,43 @@
|
||||
use clap::Parser;
|
||||
use std::{net, path};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Parser, Clone, Debug)]
|
||||
pub struct Config {
|
||||
/// Listen for UDP packets on the given address.
|
||||
#[arg(long, default_value = "[::]:0")]
|
||||
pub bind: net::SocketAddr,
|
||||
|
||||
/// Connect to the given URL starting with https://
|
||||
#[arg(value_parser = moq_url)]
|
||||
pub url: Url,
|
||||
|
||||
/// Use the TLS root CA at this path, encoded as PEM.
|
||||
///
|
||||
/// This value can be provided multiple times for multiple roots.
|
||||
/// If this is empty, system roots will be used instead
|
||||
#[arg(long)]
|
||||
pub tls_root: Vec<path::PathBuf>,
|
||||
|
||||
/// Danger: Disable TLS certificate verification.
|
||||
///
|
||||
/// Fine for local development, but should be used in caution in production.
|
||||
#[arg(long)]
|
||||
pub tls_disable_verify: bool,
|
||||
|
||||
/// Publish the current time to the relay, otherwise only subscribe.
|
||||
// #[arg(long)]
|
||||
// pub publish: bool,
|
||||
|
||||
/// The name of the input track.
|
||||
#[arg(long, default_value = "netris")]
|
||||
pub namespace: String,
|
||||
|
||||
/// The name of the input track.
|
||||
#[arg(long, default_value = ".catalog")]
|
||||
pub track: String,
|
||||
}
|
||||
|
||||
fn moq_url(s: &str) -> Result<Url, String> {
|
||||
Url::try_from(s).map_err(|e| e.to_string())
|
||||
}
|
||||
220
bin/input/src/input.rs
Normal file
220
bin/input/src/input.rs
Normal file
@@ -0,0 +1,220 @@
|
||||
use anyhow::Context;
|
||||
use enigo::{
|
||||
Axis::Horizontal,
|
||||
Coordinate::Abs,
|
||||
Direction::{Press, Release},
|
||||
Enigo, Keyboard, Mouse, Settings,
|
||||
};
|
||||
use moq_transport::serve::{
|
||||
DatagramsReader, GroupsReader, ObjectsReader, StreamReader, TrackReader, TrackReaderMode,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub struct Subscriber {
|
||||
track: TrackReader,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct MessageObject {
|
||||
input_type: String,
|
||||
delta_y: Option<i32>,
|
||||
delta_x: Option<i32>,
|
||||
button: Option<i32>,
|
||||
key_code: Option<i32>,
|
||||
}
|
||||
|
||||
impl Subscriber {
|
||||
pub fn new(track: TrackReader) -> Self {
|
||||
Self { track }
|
||||
}
|
||||
|
||||
pub async fn run(self) -> anyhow::Result<()> {
|
||||
match self.track.mode().await.context("failed to get mode")? {
|
||||
TrackReaderMode::Stream(stream) => Self::recv_stream(stream).await,
|
||||
TrackReaderMode::Groups(groups) => Self::recv_groups(groups).await,
|
||||
TrackReaderMode::Objects(objects) => Self::recv_objects(objects).await,
|
||||
TrackReaderMode::Datagrams(datagrams) => Self::recv_datagrams(datagrams).await,
|
||||
}
|
||||
}
|
||||
|
||||
async fn recv_stream(mut track: StreamReader) -> anyhow::Result<()> {
|
||||
while let Some(mut group) = track.next().await? {
|
||||
println!("received a stream");
|
||||
while let Some(object) = group.read_next().await? {
|
||||
println!("received a stream 1");
|
||||
let str = String::from_utf8_lossy(&object);
|
||||
println!("{}", str);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn recv_groups(mut groups: GroupsReader) -> anyhow::Result<()> {
|
||||
while let Some(mut group) = groups.next().await? {
|
||||
let base = group
|
||||
.read_next()
|
||||
.await
|
||||
.context("failed to get first object")?
|
||||
.context("empty group")?;
|
||||
|
||||
//TODO: Use this to allow for authorisation (admin, player or guest) etc etc
|
||||
let _base = String::from_utf8_lossy(&base);
|
||||
// let json = serde_json::from_str(&str)?;
|
||||
|
||||
//TODO: Handle clipboard
|
||||
let mut enigo = Enigo::new(&Settings::default()).unwrap();
|
||||
while let Some(object) = group.read_next().await? {
|
||||
let str = String::from_utf8_lossy(&object);
|
||||
let parsed: MessageObject = serde_json::from_str(&str)?;
|
||||
match parsed.input_type.as_str() {
|
||||
"mouse_move" => {
|
||||
if let (Some(x), Some(y)) = (parsed.delta_x, parsed.delta_y) {
|
||||
// println!("Handling mouse_move with delta_x: {}, delta_y: {}", x, y);
|
||||
enigo.move_mouse(x, y, Abs).unwrap();
|
||||
}
|
||||
}
|
||||
"mouse_key_down" => {
|
||||
if let Some(button) = parsed.button {
|
||||
// println!("Handling mouse_key_down with key: {}", button);
|
||||
if let Some(key) = mouse_key_to_enigo(button) {
|
||||
enigo.button(key, Press).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
"mouse_key_up" => {
|
||||
if let Some(button) = parsed.button {
|
||||
// println!("Handling mouse_key_up with key: {}", button);
|
||||
if let Some(key) = mouse_key_to_enigo(button) {
|
||||
enigo.button(key, Release).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
"mouse_wheel_up" => {
|
||||
//TODO: handle vertical scrolling
|
||||
// println!("Handling mouse_wheel_up with key");
|
||||
enigo.scroll(-2, Horizontal).unwrap();
|
||||
}
|
||||
"mouse_wheel_down" => {
|
||||
//TODO: handle vertical scrolling
|
||||
// println!("Handling mouse_wheel_down with key");
|
||||
enigo.scroll(2, Horizontal).unwrap();
|
||||
}
|
||||
"key_up" => {
|
||||
if let Some(key_code) = parsed.key_code {
|
||||
// println!("Handling key_up with key: {}", key_code);
|
||||
if let Some(key) = key_to_enigo(key_code as u8) {
|
||||
enigo.key(key, Release).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
"key_down" => {
|
||||
if let Some(key_code) = parsed.key_code {
|
||||
// println!("Handling key_down with key: {}", key_code);
|
||||
if let Some(key) = key_to_enigo(key_code as u8) {
|
||||
enigo.key(key, Press).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
println!("Unknown input_type: {}", parsed.input_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn recv_objects(mut objects: ObjectsReader) -> anyhow::Result<()> {
|
||||
while let Some(mut object) = objects.next().await? {
|
||||
let payload = object.read_all().await?;
|
||||
let str = String::from_utf8_lossy(&payload);
|
||||
println!("{}", str);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn recv_datagrams(mut datagrams: DatagramsReader) -> anyhow::Result<()> {
|
||||
while let Some(datagram) = datagrams.read().await? {
|
||||
let str = String::from_utf8_lossy(&datagram.payload);
|
||||
println!("{}", str);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mouse_key_to_enigo(key: i32) -> Option<enigo::Button> {
|
||||
match key {
|
||||
0 => Some(enigo::Button::Left),
|
||||
1 => Some(enigo::Button::Middle),
|
||||
2 => Some(enigo::Button::Right),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn key_to_enigo(key: u8) -> Option<enigo::Key> {
|
||||
match key {
|
||||
27 => Some(enigo::Key::Escape),
|
||||
112 => Some(enigo::Key::F1),
|
||||
113 => Some(enigo::Key::F2),
|
||||
114 => Some(enigo::Key::F3),
|
||||
115 => Some(enigo::Key::F4),
|
||||
116 => Some(enigo::Key::F5),
|
||||
117 => Some(enigo::Key::F6),
|
||||
118 => Some(enigo::Key::F7),
|
||||
119 => Some(enigo::Key::F8),
|
||||
120 => Some(enigo::Key::F9),
|
||||
121 => Some(enigo::Key::F10),
|
||||
122 => Some(enigo::Key::F11),
|
||||
123 => Some(enigo::Key::F12),
|
||||
// 19 => Some(enigo::Key::Pause), // Pause
|
||||
// 97 => Some(enigo::Key::Print), // Print
|
||||
46 => Some(enigo::Key::Delete),
|
||||
35 => Some(enigo::Key::End),
|
||||
192 => Some(enigo::Key::Unicode('`')),
|
||||
48 => Some(enigo::Key::Unicode('0')),
|
||||
49 => Some(enigo::Key::Unicode('1')),
|
||||
50 => Some(enigo::Key::Unicode('2')),
|
||||
51 => Some(enigo::Key::Unicode('3')),
|
||||
52 => Some(enigo::Key::Unicode('4')),
|
||||
53 => Some(enigo::Key::Unicode('5')),
|
||||
54 => Some(enigo::Key::Unicode('6')),
|
||||
55 => Some(enigo::Key::Unicode('7')),
|
||||
56 => Some(enigo::Key::Unicode('8')),
|
||||
57 => Some(enigo::Key::Unicode('9')),
|
||||
189 => Some(enigo::Key::Unicode('-')),
|
||||
187 => Some(enigo::Key::Unicode('=')),
|
||||
8 => Some(enigo::Key::Backspace),
|
||||
9 => Some(enigo::Key::Tab),
|
||||
219 => Some(enigo::Key::Unicode('[')),
|
||||
221 => Some(enigo::Key::Unicode(']')),
|
||||
220 => Some(enigo::Key::Unicode('\\')),
|
||||
20 => Some(enigo::Key::CapsLock),
|
||||
186 => Some(enigo::Key::Unicode(';')),
|
||||
222 => Some(enigo::Key::Unicode('\'')),
|
||||
13 => Some(enigo::Key::Return),
|
||||
16 => Some(enigo::Key::Shift), // ShiftL
|
||||
188 => Some(enigo::Key::Unicode(',')),
|
||||
190 => Some(enigo::Key::Unicode('.')),
|
||||
191 => Some(enigo::Key::Unicode('/')),
|
||||
161 => Some(enigo::Key::Shift), // ShiftR
|
||||
38 => Some(enigo::Key::UpArrow),
|
||||
17 => Some(enigo::Key::Control), // ControlL
|
||||
18 => Some(enigo::Key::Alt), // AltL
|
||||
32 => Some(enigo::Key::Space),
|
||||
165 => Some(enigo::Key::Alt), // AltR
|
||||
// 103 => Some(enigo::Key::Menu),
|
||||
163 => Some(enigo::Key::Control), // ControlR
|
||||
37 => Some(enigo::Key::LeftArrow),
|
||||
40 => Some(enigo::Key::DownArrow),
|
||||
39 => Some(enigo::Key::RightArrow),
|
||||
// 99 => Some(enigo::Key::Raw(45)), // Insert
|
||||
34 => Some(enigo::Key::PageDown),
|
||||
36 => Some(enigo::Key::Home),
|
||||
33 => Some(enigo::Key::PageUp),
|
||||
a if a >= 65 && a <= 90 => Some(enigo::Key::Unicode((a - 65 + ('a' as u8)) as char)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
76
bin/input/src/main.rs
Normal file
76
bin/input/src/main.rs
Normal file
@@ -0,0 +1,76 @@
|
||||
use moq_transport::{serve, session::Subscriber};
|
||||
use moq_native::quic;
|
||||
use std::net;
|
||||
use url::Url;
|
||||
|
||||
use anyhow::Context;
|
||||
use clap::Parser;
|
||||
|
||||
mod input;
|
||||
|
||||
|
||||
#[derive(Parser, Clone)]
|
||||
pub struct Cli {
|
||||
/// Listen for UDP packets on the given address.
|
||||
#[arg(long, default_value = "[::]:0")]
|
||||
pub bind: net::SocketAddr,
|
||||
|
||||
/// Connect to the given URL starting with https://
|
||||
#[arg()]
|
||||
pub url: Url,
|
||||
|
||||
/// The TLS configuration.
|
||||
#[command(flatten)]
|
||||
pub tls: moq_native::tls::Cli,
|
||||
|
||||
// /// Publish the current time to the relay, otherwise only subscribe.
|
||||
// #[arg(long)]
|
||||
// pub publish: bool,
|
||||
/// The name of the input track.
|
||||
#[arg(long, default_value = "netris")]
|
||||
pub namespace: String,
|
||||
|
||||
/// The name of the input track.
|
||||
#[arg(long, default_value = ".catalog")]
|
||||
pub track: String,
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
env_logger::init();
|
||||
|
||||
// Disable tracing so we don't get a bunch of Quinn spam.
|
||||
let tracer = tracing_subscriber::FmtSubscriber::builder()
|
||||
.with_max_level(tracing::Level::WARN)
|
||||
.finish();
|
||||
tracing::subscriber::set_global_default(tracer).unwrap();
|
||||
|
||||
let config = Cli::parse();
|
||||
let tls = config.tls.load()?;
|
||||
|
||||
let quic = quic::Endpoint::new(quic::Config {
|
||||
bind: config.bind,
|
||||
tls,
|
||||
})?;
|
||||
|
||||
log::info!("connecting to server: url={}", config.url);
|
||||
|
||||
let session = quic.client.connect(&config.url).await?;
|
||||
|
||||
let (session, mut subscriber) = Subscriber::connect(session)
|
||||
.await
|
||||
.context("failed to create MoQ Transport session")?;
|
||||
|
||||
let (prod, sub) = serve::Track::new(config.namespace, config.track).produce();
|
||||
|
||||
let input = input::Subscriber::new(sub);
|
||||
|
||||
//TODO: Make sure to retry until the input server comes [Use Supervisord for now]
|
||||
tokio::select! {
|
||||
res = session.run() => res.context("session error")?,
|
||||
res = input.run() => res.context("input error")?,
|
||||
res = subscriber.subscribe(prod) => res.context("failed to subscribe to track")?,
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
14
warp-input.Dockerfile
Normal file
14
warp-input.Dockerfile
Normal file
@@ -0,0 +1,14 @@
|
||||
FROM rust:bookworm as builder
|
||||
|
||||
# Create a build directory and copy over all of the files
|
||||
WORKDIR /build
|
||||
COPY ./bin/input/ ./
|
||||
RUN apt-get update && apt-get install -y libxdo-dev
|
||||
# Reuse a cache between builds.
|
||||
# I tried to `cargo install`, but it doesn't seem to work with workspaces.
|
||||
# There's also issues with the cache mount since it builds into /usr/local/cargo/bin
|
||||
# We can't mount that without clobbering cargo itself.
|
||||
# We instead we build the binaries and copy them to the cargo bin directory.
|
||||
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
||||
--mount=type=cache,target=/build/target \
|
||||
cargo build --target x86_64-unknown-linux-gnu --release && cp target/x86_64-unknown-linux-gnu/release/warp-input /usr/bin/warp-input
|
||||
Reference in New Issue
Block a user