SuperCollider GUI for browsers with remote sync capablities.

Overview

webRTCgui

webRTCgui allows to create dynamic GUI elements in the internet or local network from within SuperCollider. Clients get synced among each other and movements in the GUI gets also forwarded to SuperCollider.

Screen recording

This GUI also syncs across multiple devices, also across the internet.

As SuperCollider can not directly communicate via WebRTC we need some translational layers. To get a better understanding we quickly explain each component involved.

Service Folder Description
Backend . A express server which distributes the necessary messages. Can run on your local machine or remote machine.
Frontend ./frontend A frontend through which outside clients can interact. Should run on the same machine as the backend.
Client . Client to translate WebRTC to SuperCollider OSC messages. Needs to run on your local machine.
SuperCollider ./classes A simple Quark with the class WebRTCGUI. Should be used on your local machine.

Installation

SuperCollider

Before we start with setting up the services you should install the necessary Quark in SuperCollider by entering the following lines into the editor and evaluate them.

Quarks.install("https://github.com/capital-G/webRTCgui.git");
// recompile interpreter to make new classes available
thisProcess.platform.recompile;

Services

The easiest way to set up all necessary services is using Docker with docker-compose. If you do not want to use Docker take a look at Dockefile and docker-compose.yml to get a sense on the port mappings and build processes.

Use on local machine for local network

The easiest way to try this setup is by running everything on your local machine. Simply clone the repository by executing the following line within a terminal and a folder of your choice.

git clone https://github.com/capital-G/webRTCgui.git

Now we switch the directory to the just created folder

cd webRTCgui

We assume that SuperCollider is running on the default port 57120 which can be verified by running

NetAddr.langPort;

in the SuperCollider interpreter. If these ports do not match up you will not receive any updates from the frontend in SuperCollider. Check if any other sclang instances are running or modify the port in the docker-compose.yml file.

Now we can build and run the Docker containers by executing

docker-compose up --build

Once everything spun up you can access the frontend on http://localhost:3000 and start creating controls from SuperCollider (see the Help Files in SuperCollider by searching for WebRTCGUI).

Other clients within your local network can access the website as well via http://your_local_ip:3000.

For the sake of completeness there is a schematic on how the services are connected.

Local setup

Use on remote machine for internet

Deploying the service on a remote machine allows you to connect globally to the GUI. One of the nice things about WebRTC is that it can bypass some P2P obstacles such as IPv6 or a firewall, so most likely you do not have to worry about these things.

We assume that you run a linux server on which docker, docker-compose and nginx is already installed.

Start by cloning the repo on your remote machine

git clone https://github.com/capital-G/webRTCgui.git && \
cd webRTCgui

Spin up the remote setup via

docker-compose -f docker-compose.remote.yml up --build

You may add the flag -d to make the container run in the background.

Check via curl -f http://localhost:3000 if the server is reachable.

If so we can now create and activate a nginx config. It is also possible to use an Apache server but I don't have a config for it.

Here is an example of such a nginx config file.

server {
  server_name   my-domain.com;

  location / {
    proxy_pass  http://localhost:3000;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
      client_max_body_size 0;

      access_log /var/log/nginx/remote.access.log;
      error_log /var/log/nginx/remote.error.log;
  }
  listen 80;
}

Modify it according to your URL and port mappings, restart nginx and let certbot give you a certificate for your config.

Verify that you can access the backend server with your browser.

Connect te remote machine

Once we set up everything on the remote machine we need to connect our local client to the remote website.

Use the following command in which we prepend the URL and token of our remote service as environment variables which will passed to the service.

BACKEND_ADDRESS="https://my-domain.com" BACKEND_AUTH_TOKEN="my_token" docker-compose -f docker-compose.remote_client.yml up --build

If everything worked you should see

client_1  | Connected to server

Schematic

Remote setup

Authentication

To restrict the creation and deletion of GUI elements there needs to some kind of authentication to distinguish between the local client which is attached to SuperCollider and the remote clients, accessing the server via a browser. You can use and modify the environment variable BACKEND_AUTH_TOKEN in both places of the docker-compose.yml file (or respectively any other docker-compose file) to change this token. Please do not use precious passwords as these passwords are transmitted non-encrypted and may get spilled by storing and printing them in plaintext.

Development

There is an additional docker-compose file docker-compose.dev.yml which allows for hot-reloading and debugging of the Vue frontend by using the Vue development server instead of shipping the static build via an Express server like on the normal build.

To use this server please install first all frontend dependencies first by running

cd frontend
npm install

as we will completely mount and replace the folder in the container with our local instance which would otherwise lack the necessary dependencies in node_modules.

To use the dev version simply run

docker-compose -f docker-compose.dev.yml up --build

The Vue development server is then available under http://localhost:8080.

Please install and setup pre-commit before committing which will run some linting checks.

The schematics of the dev environment are a bit more complex.

Dev schematic

License

GPL-2

Comments
  • Implement locking mechanism

    Implement locking mechanism

    A rabbit hole, but at least it should

    • [x] prevent feedbacks
    • [x] prevent out-of-sync GUIs (maybe send a "beacon"/state of the server?)

    It seems the more delay/lag we have via network the worser it gets

    enhancement 
    opened by capital-G 2
  • Slider does not react to touch inputs

    Slider does not react to touch inputs

    Does not work as expected on smartphones (they dont use mouseup)

    https://github.com/capital-G/webRTCgui/blob/07e9b6e9187856d17a135c41663e98a299d4e3a2/js/src/components/ControllerSlider.vue#L33-L40

    bug 
    opened by capital-G 1
  • Add forwarding of wss in reverse proxy

    Add forwarding of wss in reverse proxy

    Currently it seems the wss connections are rejected by the server, see

    Firefox can’t establish a connection to the server at wss://remote.dennis-scheiba.com/socket.io/?EIO=4&transport=websocket&sid=_2cYrudD3-U8XHojAAAG.
    

    Thankfully socket.io falls back on a simple get/post workflow so it still works.

    bug documentation 
    opened by capital-G 1
  • Make socket.io host address dynamic in frontend

    Make socket.io host address dynamic in frontend

    Currently the remote deployment does not work because we build against the wrong socket address, see

    https://github.com/capital-G/webRTCgui/blob/4c98636d1e0c85613feac095508fb64f9b1e47ab/js/src/services/socketio.service.ts#L6

    2 ways to solve this

    • inject the URL as argument during build time
    • use the same host url as the current visited url - maybe this is a good fallback for the first usecase
    bug 
    opened by capital-G 1
  • Fix quark file

    Fix quark file

    Not a deal breaker, but I wasn't sure if the "DemonWidgets" in the quark file is correct? Also, I'd be curious to see how it compares with the WsGUI quark :-)

    Originally posted by @dyfer in https://github.com/supercollider-quarks/quarks/issues/130#issuecomment-1344634778

    bug 
    opened by capital-G 1
  • Get values of controller on startup

    Get values of controller on startup

    Currently only what controllers are available is synced at startup but not their position. This could probably done for each controller item independently in order to make syncing easier.

    bug 
    opened by capital-G 1
  • Add schematcis via uml

    Add schematcis via uml

    First sketch via https://www.planttext.com/

    grafik

    @startuml
    
    rectangle "Local" {
      rectangle "docker" as localdocker {
          frame client {
            rectangle "client.js:57220" as LocalClient
          }
        }
        frame "SuperCollider" {
          rectangle "sclang:57120" as sclang
        }
    }
    
    rectangle "Server" {
      rectangle "docker" {
      frame "backend" {
        rectangle ":3000" <<express>> as express
      }
      frame "frontend" {
        rectangle ":8080" <<vue>> as vue
      }
      }
      
      frame "nginx" {
        rectangle ":80" <<webserver>> as webserver
      }
    
    }
    
    cloud "Remote Clients" as RemoteClients
    
    
    RemoteClients <-> webserver : "WebRTC"
    
    
    vue -> webserver : "http"
    express <-> webserver : "ws"
    
    
    LocalClient <--> webserver : "WebRTC"
    
    sclang <-> LocalClient : "OSC"
    
    
    @enduml
    
    documentation 
    opened by capital-G 1
  • Implement proper env handling for frontend

    Implement proper env handling for frontend

    Frontend relies on VUE_APP_SOCKET_ENDPOINT which is declared in gitignored ./frontend/.venv - should be handeled better, also consider this for static build

    bug 
    opened by capital-G 1
  • Fix slider entering

    Fix slider entering

    @mouseon/@mouseoff seem to work good in theory but they do not work on touch interfaces and also don't work fast (enough?) when one just clicks on a section instead of dragging it.

    bug 
    opened by capital-G 1
  • 26 make socketio host address dynamic in frontend

    26 make socketio host address dynamic in frontend

    closes #26 by improving the detection of the socketio host. The steps are:

    • use export VUE_APP_SOCKET_ENDPOINT=https://my-custom-ws.com:4000 env variable if set - this needs to be set during build time of the docker container - useful if the websocket host deviates (e.g. different host or port)
    • if host == localhost -> use localhost:3000 as the vue development server (port 8080) has no websocket initaited which runs under 3000 in the dev setup
    • otherwise use the base address of the website
    opened by capital-G 0
  • GUI does not sync across devices

    GUI does not sync across devices

    We currently ignore the values that we receive from other clients in the frontend. This bug was introduced by the rewriting in typescript which changed the behavior of how we distribute the receiving channels. Maybe its best to fix this properly by adding a state management?

    bug 
    opened by capital-G 0
  • Docker compose client fails under linux

    Docker compose client fails under linux

    https://github.com/capital-G/webRTCgui/blob/59dce5df8f0968afe3c0ba5ac1478b1d78b0a8bb/docker-compose.client.yml#L11-L13

    host.docker.internal is a macOS/Windows featuer, for linux see https://stackoverflow.com/questions/48546124/what-is-linux-equivalent-of-host-docker-internal

    Creating webrtcgui_client_1 ... done
    Attaching to webrtcgui_client_1                                                                                                    
    client_1  |  
    client_1  | > [email protected] client /root/web_rtc_gui 
    client_1  | > ts-node --esm src/client.ts 
    client_1  |  
    client_1  | Start client 
    client_1  | Backend address: https://remote.dennis-scheiba.com 
    client_1  | SuperCollider address: host.docker.internal:57120 
    client_1  | Client port: 57220 
    client_1  | Auth token: "somePW" 
    client_1  | Started client 
    client_1  | Connected to server 
    client_1  | Received freq: 113.30357142857143 
    client_1  | Received freq: 119.75 
    client_1  | Received freq: 132.98214285714286 
    client_1  | Received freq: 152.32142857142856 
    client_1  | Received freq: 167.92857142857142 
    client_1  | Error: getaddrinfo ENOTFOUND host.docker.internal 
    client_1  |     at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:71:26) { 
    client_1  |   errno: -3008, 
    client_1  |   code: 'ENOTFOUND', 
    client_1  |   syscall: 'getaddrinfo', 
    client_1  |   hostname: 'host.docker.internal' 
    client_1  | } 
    client_1  | npm ERR! code ELIFECYCLE 
    client_1  | npm ERR! errno 1 
    client_1  | npm ERR! [email protected] client: `ts-node --esm src/client.ts` 
    client_1  | npm ERR! Exit status 1 
    client_1  | npm ERR!  
    client_1  | npm ERR! Failed at the [email protected] client script. 
    client_1  | npm ERR! This is probably not a problem with npm. There is likely additional logging output above. 
    client_1  |  
    client_1  | npm ERR! A complete log of this run can be found in: 
    client_1  | npm ERR!     /root/.npm/_logs/2022-12-15T16_03_32_530Z-debug.log 
    webrtcgui_client_1 exited with code 1
    
    bug 
    opened by capital-G 0
Releases(v0.2.1)
  • v0.2.1(Dec 12, 2022)

    What's Changed

    • remove web font loader by @capital-G in https://github.com/capital-G/webRTCgui/pull/24
    • Fix reverse proxy config by @capital-G in https://github.com/capital-G/webRTCgui/pull/29
    • Pinia store by @capital-G in https://github.com/capital-G/webRTCgui/pull/30
    • 26 make socketio host address dynamic in frontend by @capital-G in https://github.com/capital-G/webRTCgui/pull/31
    • Share connection by @capital-G in https://github.com/capital-G/webRTCgui/pull/35
    • Develop by @capital-G in https://github.com/capital-G/webRTCgui/pull/36

    Full Changelog: https://github.com/capital-G/webRTCgui/compare/v0.2.0...v0.2.1

    Source code(tar.gz)
    Source code(zip)
  • v0.2.0(Dec 9, 2022)

    What's Changed

    • Add typescript by @capital-G in https://github.com/capital-G/webRTCgui/pull/16
    • add monospace option to text component by @capital-G in https://github.com/capital-G/webRTCgui/pull/23

    Full Changelog: https://github.com/capital-G/webRTCgui/compare/v0.1.0...v0.2.0

    Source code(tar.gz)
    Source code(zip)
  • v0.1.0(Dec 9, 2022)

Owner
Dennis Scheiba
Sound Research @ RSH Düsseldorf
Dennis Scheiba
Resurrection of mediagroup / MediaController (renamed) which can be used to sync and control multiple audio / video elements.

media-group (examples) Resurrection of the mediagroup attribute and MediaController API (but renamed) which can be used to sync and control multiple a

Mux 6 Aug 2, 2022
Remote Code Execution V1 For iOS 15 sent through airdrop after the device was connected to a trusted host

iOS 15.0.1 RCE V1 Author: Jonathan Scott @jonathandata1 Date: October 9th, 2021 Release Version 1.0 Description When an iOS device has been connected

Jonathan Scott 307 Dec 26, 2022
WebRTC + WebXR Remote Desktop

WebRTC + WebXR RDP WebRTCとWebXRを使ったブラウザ上で動くリモートデスクトップです.WebXRではない通常表示も可能です. 最近の Chrome や Edge で動くはずです.VRモードは Oculus Quest 2 の Oculus Browser で動作確認していま

Kosuke Kawahira 28 Dec 27, 2022
Remote Keyboard Tutoring System is a web-based system that can be attached to any keyboard synthesizer through a MIDI connector.

The Remote Keyboard Tutoring System is a web-based system that can be attached to any (electronic) keyboard synthesizer through a MIDI connector. Once our system is connected to the keyboard, the user can interactively learn, play or teach in combination with the web application that we provide.

Department of Computer Engineering, University of Peradeniya 3 Nov 15, 2022
whatsapp api to remote your whatsapp device. Support multi device, multi client. Still update to more feature. Please fork, star, donate and share.

Ndalu-wa-client DEPENDENCIES : { "@adiwajshing/baileys": "^4.2.0", "@adiwajshing/keyed-db": "^0.2.4", "axios": "^0.27.2", "body-parser

null 29 Jan 4, 2023
Enables

HTML5 video made easy All it takes is a single line of code to make HTML5 video and audio tags work in all major browsers. How to enable video and aud

Dave Hall 1.3k Dec 17, 2022
HTML5

One file. Any browser. Same UI. Author: John Dyer http://j.hn/ Website: http://mediaelementjs.com/ License: MIT Meaning: Use everywhere, keep copyrigh

MediaElement.js 8k Dec 27, 2022
A Javascript library for working with Audio. It provides a consistent API for loading and playing audio on different browsers and devices. Currently supports WebAudio, HTML5 Audio, Cordova / PhoneGap, and a Flash fallback.

SoundJS SoundJS is a library to make working with audio on the web easier. It provides a consistent API for playing audio in different browsers, inclu

CreateJS 4.3k Dec 31, 2022
JavaScript plugin for playing sounds and music in browsers

JavaScript plugin for playing sounds on user actions and page events. Version: 3.0.7 Project page and demos Download ZIP Support the plugin on GitHub

Denis Ineshin 704 Sep 24, 2022
HTML5

One file. Any browser. Same UI. Author: John Dyer http://j.hn/ Website: http://mediaelementjs.com/ License: MIT Meaning: Use everywhere, keep copyrigh

MediaElement.js 8k Jan 8, 2023
Modern browsers already had a vivid player for video

Modern browsers already had a vivid player for video. However, web developers and designers still want to custom their own style player for different situations. Sounds like web component will do a lot favor for this purpose. With <msc-ez-video /> support, customize control panel will become a piece of cake. <msc-ez-video /> adopts CSS custom properties, developers could style them as they want.

Paul 1 Dec 29, 2021
HLS.js is a JavaScript library that plays HLS in browsers with support for MSE.

HLS.js is a JavaScript library that implements an HTTP Live Streaming client. It relies on HTML5 video and MediaSource Extensions for playback. It wor

video-dev 12.3k Jan 2, 2023
Secretly record audio and video with chromium based browsers

snoop TCC restricts access to the device camera and microphone to protect user data from unauthorized access. But... If you trusted your browser with

BreakPoint Technologies 10 Aug 30, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Javascript client for Sanity. Works in node.js and modern browsers (older browsers needs a Promise polyfill).

@sanity/client Javascript client for Sanity. Works in node.js and modern browsers (older browsers needs a Promise polyfill). Requirements Sanity Clien

Sanity 23 Nov 29, 2022
This package generates a unique ID/String for different browsers. Like chrome, Firefox and any other browsers which supports canvas and audio Fingerprinting.

Broprint.js The world's easiest, smallest and powerful visitor identifier for browsers. This package generates a unique ID/String for different browse

Rajesh Royal 68 Dec 25, 2022
⚡ Zero config GUI for Jest

Majestic is a GUI for Jest ✅ Run all the tests or a single file ⏱ Toggle watch mode ?? Update snapshots ❌ Examine test failures as they happen ⏲ Conso

Raathi Kugarajan 7.4k Jan 2, 2023