mirror of
https://github.com/m1k1o/neko.git
synced 2025-06-18 18:52:30 +02:00
update docs.
This commit is contained in:
parent
6f3760e5b9
commit
e3cdad3f81
41 changed files with 213 additions and 198 deletions
|
@ -1,9 +1,8 @@
|
|||
---
|
||||
title: Overview of Neko
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Overview of Neko
|
||||
# Overview
|
||||
|
||||
Neko is an open-source self-hosted virtual browser solution that allows multiple users to share a single web browser instance remotely. It is designed for use cases such as collaborative browsing, remote access to web-based applications, and private cloud-based browsing.
|
||||
|
||||
|
@ -31,3 +30,11 @@ Neko runs on various platforms, including:
|
|||
- **Raspberry Pi & ARM Devices** – Optimized versions for embedded and low-power hardware.
|
||||
|
||||
Explore the documentation to learn how to deploy, configure, and optimize Neko for your use case.
|
||||
|
||||
## Next Steps
|
||||
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
import {useCurrentSidebarCategory} from '@docusaurus/theme-common';
|
||||
|
||||
<DocCardList items={useCurrentSidebarCategory().items.filter((item) => item.docId !== 'getting-started/README')} />
|
||||
|
|
@ -1,378 +0,0 @@
|
|||
# Configuration
|
||||
|
||||
Neko uses the [Viper](https://github.com/spf13/viper) library to manage configuration. The configuration file is optional and is not required for Neko to run. If a configuration file is present, it will be read in and merged with the default configuration values.
|
||||
|
||||
The merge order is as follows:
|
||||
|
||||
- Default configuration values
|
||||
- Configuration file
|
||||
- Environment variables
|
||||
- Command-line arguments
|
||||
|
||||
<details>
|
||||
<summary>Example merging order</summary>
|
||||
|
||||
```bash
|
||||
# Default Value: 127.0.0.1:8080
|
||||
|
||||
# Config File
|
||||
cat config.yaml <<EOF
|
||||
server:
|
||||
bind: "127.0.0.1:8081"
|
||||
EOF
|
||||
|
||||
# Environment Variable
|
||||
export NEKO_SERVER_BIND=127.0.0.1:8082
|
||||
|
||||
# Command-line Argument
|
||||
./neko -config=config.yaml -server.bind=127.0.0.1:8083
|
||||
```
|
||||
|
||||
The final value of `server.bind` will be `127.0.0.1:8083`.
|
||||
|
||||
</details>
|
||||
|
||||
## Configuration File
|
||||
|
||||
You have multiple ways to specify the configuration file for the neko server:
|
||||
|
||||
- Command-line argument: `-config=/path/to/config.yaml`
|
||||
- Environment variable: `NEKO_CONFIG=/path/to/config.yaml`
|
||||
- Place the `neko.yaml` file in the same directory as the neko binary.
|
||||
- Place the `neko.yaml` file to `/etc/neko/neko.yaml` *(ideal for Docker containers)*.
|
||||
|
||||
The configuration file can be specified in YAML, JSON, TOML, HCL, envfile, and Java properties format. Throughout the documentation, we will use the YAML format.
|
||||
|
||||
<details>
|
||||
<summary>Example configuration files</summary>
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="yaml" label="YAML">
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
screencast:
|
||||
enabled: false
|
||||
|
||||
server:
|
||||
pprof: true
|
||||
|
||||
desktop:
|
||||
screen: "1920x1080@60"
|
||||
|
||||
member:
|
||||
provider: "multiuser"
|
||||
multiuser:
|
||||
admin_password: "admin"
|
||||
user_password: "neko"
|
||||
|
||||
session:
|
||||
merciful_reconnect: true
|
||||
implicit_hosting: false
|
||||
inactive_cursors: true
|
||||
cookie:
|
||||
enabled: false
|
||||
|
||||
webrtc:
|
||||
icelite: true
|
||||
iceservers:
|
||||
# Backend servers are ignored if icelite is true.
|
||||
backend:
|
||||
- urls: [ stun:stun.l.google.com:19302 ]
|
||||
frontend:
|
||||
- urls: [ stun:stun.l.google.com:19305 ]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="json" label="JSON">
|
||||
|
||||
```json title="config.json"
|
||||
{
|
||||
"capture": {
|
||||
"screencast": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"server": {
|
||||
"pprof": true
|
||||
},
|
||||
"desktop": {
|
||||
"screen": "1920x1080@60"
|
||||
},
|
||||
"member": {
|
||||
"provider": "multiuser",
|
||||
"multiuser": {
|
||||
"admin_password": "admin",
|
||||
"user_password": "neko"
|
||||
}
|
||||
},
|
||||
"session": {
|
||||
"merciful_reconnect": true,
|
||||
"implicit_hosting": false,
|
||||
"inactive_cursors": true,
|
||||
"cookie": {
|
||||
"enabled": false
|
||||
}
|
||||
},
|
||||
"webrtc": {
|
||||
"icelite": true,
|
||||
"iceservers": {
|
||||
"backend": [
|
||||
{
|
||||
"urls": [ "stun:stun.l.google.com:19302" ]
|
||||
}
|
||||
],
|
||||
"frontend": [
|
||||
{
|
||||
"urls": [ "stun:stun.l.google.com:19305" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="toml" label="TOML">
|
||||
|
||||
```toml title="config.toml"
|
||||
[capture.screencast]
|
||||
enabled = false
|
||||
|
||||
[server]
|
||||
pprof = true
|
||||
|
||||
[desktop]
|
||||
screen = "1920x1080@60"
|
||||
|
||||
[member]
|
||||
provider = "multiuser"
|
||||
|
||||
[member.multiuser]
|
||||
admin_password = "admin"
|
||||
user_password = "neko"
|
||||
|
||||
[session]
|
||||
merciful_reconnect = true
|
||||
implicit_hosting = false
|
||||
inactive_cursors = true
|
||||
|
||||
[session.cookie]
|
||||
enabled = false
|
||||
|
||||
[webrtc]
|
||||
icelite = true
|
||||
|
||||
[[webrtc.iceservers.backend]]
|
||||
urls = [ "stun:stun.l.google.com:19302" ]
|
||||
|
||||
[[webrtc.iceservers.frontend]]
|
||||
urls = [ "stun:stun.l.google.com:19305" ]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="hcl" label="HCL">
|
||||
|
||||
```hcl title="config.hcl"
|
||||
capture {
|
||||
screencast {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
pprof = true
|
||||
}
|
||||
|
||||
desktop {
|
||||
screen = "1920x1080@60"
|
||||
}
|
||||
|
||||
member {
|
||||
provider = "multiuser"
|
||||
|
||||
multiuser {
|
||||
admin_password = "admin"
|
||||
user_password = "neko"
|
||||
}
|
||||
}
|
||||
|
||||
session {
|
||||
merciful_reconnect = true
|
||||
implicit_hosting = false
|
||||
inactive_cursors = true
|
||||
|
||||
cookie {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
webrtc {
|
||||
icelite = true
|
||||
|
||||
iceservers {
|
||||
backend {
|
||||
urls = [ "stun:stun.l.google.com:19302" ]
|
||||
}
|
||||
|
||||
frontend {
|
||||
urls = [ "stun:stun.l.google.com:19305" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="envfile" label="Envfile">
|
||||
|
||||
```env title=".env"
|
||||
CAPTURE_SCREENCAST_ENABLED=false
|
||||
|
||||
SERVER_PPROF=true
|
||||
|
||||
DESKTOP_SCREEN=1920x1080@60
|
||||
|
||||
MEMBER_PROVIDER=multiuser
|
||||
MEMBER_MULTIUSER_ADMIN_PASSWORD=admin
|
||||
MEMBER_MULTIUSER_USER_PASSWORD=neko
|
||||
|
||||
SESSION_MERCIFUL_RECONNECT=true
|
||||
SESSION_IMPLICIT_HOSTING=false
|
||||
SESSION_INACTIVE_CURSORS=true
|
||||
SESSION_COOKIE_ENABLED=false
|
||||
|
||||
WEBRTC_ICELITE=true
|
||||
|
||||
WEBRTC_ICESERVERS_BACKEND="[{"urls":["stun:stun.l.google.com:19302"]}]"
|
||||
WEBRTC_ICESERVERS_FRONTEND="[{"urls":["stun:stun.l.google.com:19305"]}]"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="properties" label="Java Properties">
|
||||
|
||||
```properties title="config.properties"
|
||||
capture.screencast.enabled = false
|
||||
|
||||
server.pprof = true
|
||||
|
||||
desktop.screen = 1920x1080@60
|
||||
|
||||
member.provider = multiuser
|
||||
member.multiuser.admin_password = admin
|
||||
member.multiuser.user_password = neko
|
||||
|
||||
session.merciful_reconnect = true
|
||||
session.implicit_hosting = false
|
||||
session.inactive_cursors = true
|
||||
session.cookie.enabled = false
|
||||
|
||||
webrtc.icelite = true
|
||||
|
||||
webrtc.iceservers.backend[0].urls[0] = stun:stun.l.google.com:19302
|
||||
webrtc.iceservers.frontend[0].urls[0] = stun:stun.l.google.com:19305
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
</Tabs>
|
||||
|
||||
</details>
|
||||
|
||||
## Room Configuration
|
||||
|
||||
This is the initial configuration of the room that can be modified by an admin in real-time.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
session:
|
||||
private_mode: false
|
||||
locked_logins: false
|
||||
locked_controls: false
|
||||
control_protection: false
|
||||
implicit_hosting: true
|
||||
inactive_cursors: false
|
||||
merciful_reconnect: true
|
||||
heartbeat_interval: 120
|
||||
```
|
||||
|
||||
- `private_mode` whether private mode is enabled, users do not receive the room video or audio.
|
||||
- `locked_logins` whether logins are locked for users, admins can still login.
|
||||
- `locked_controls` whether controls are locked for users, admins can still control.
|
||||
- `control_protection` users can gain control only if at least one admin is in the room.
|
||||
- `implicit_hosting` allows switching control implicitly without the need for explicit control request before
|
||||
- `inactive_cursors` whether to show inactive cursors server-wide (only for users that have it enabled in their profile)
|
||||
- `merciful_reconnect` whether to allow reconnecting to the websocket even if the previous connection was not closed. This means that a new login can kick out the previous one.
|
||||
- `heartbeat_interval` interval in seconds for sending a heartbeat message to the server. This is used to keep the connection alive and to detect when the connection is lost.
|
||||
|
||||
## Server Configuration
|
||||
|
||||
This is the configuration of the neko server.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
server:
|
||||
bind: "127.0.0.1:8080"
|
||||
cert: "/path/to/cert.pem"
|
||||
key: "/path/to/key.pem"
|
||||
cors: [ "*" ]
|
||||
metrics: true
|
||||
path_prefix: "/neko"
|
||||
pprof: true
|
||||
proxy: true
|
||||
static: "/var/www/neko"
|
||||
```
|
||||
|
||||
- `bind` address/port/socket to serve neko. For docker you might want to bind to `0.0.0.0` to allow connections from outside the container.
|
||||
- `cert` and `key` paths to the SSL cert and key used to secure the neko server. If both are empty, the server will run in plain HTTP.
|
||||
- `cors` is a list of allowed origins for CORS.
|
||||
- If empty, CORS is disabled, and only same-origin requests are allowed.
|
||||
- If `*` is present, all origins are allowed. Neko will respond always with the requested origin, not with `*` since [credentials are not allowed with wildcard](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials).
|
||||
- If a list of origins is present, only those origins are allowed for CORS.
|
||||
- `metrics` when true, [prometheus](https://prometheus.io/docs/prometheus/latest/getting_started/) metrics are available at `/metrics`.
|
||||
- `path_prefix` is the prefix for all HTTP requests. This is useful when running neko behind a reverse proxy and you want to serve neko under a subpath, e.g. `/neko`.
|
||||
- `pprof` when true, the [pprof](https://golang.org/pkg/net/http/pprof/) endpoint is available at `/debug/pprof` for debugging and profiling. This should be disabled in production.
|
||||
- `proxy` when true, neko will trust the `X-Forwarded-For` and `X-Real-IP` headers from the reverse proxy. Make sure your reverse proxy is configured to set these headers and never trust them when not behind a reverse proxy.
|
||||
- `static` path to the directory containing the neko client files to serve. This is useful if you want to serve the client files on the same domain as the server.
|
||||
|
||||
## Logging Configuration
|
||||
|
||||
This is the configuration of the logging system.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
log:
|
||||
dir: <string>
|
||||
json: true
|
||||
level: "info"
|
||||
nocolor: true
|
||||
time: "unix"
|
||||
```
|
||||
|
||||
- `dir` directory to store logs. If empty, logs are written to stdout. This is useful when running neko in a container.
|
||||
- `json` when true, logs are written in JSON format.
|
||||
- `level` log level to set. Available levels are `trace`, `debug`, `info`, `warn`, `error`, `fatal`, `panic`, and `disabled`.
|
||||
- `nocolor` when true, ANSI colors are disabled in non-JSON output. Accepts as well [`NO_COLOR` environment variable](https://no-color.org/).
|
||||
- `time` time format used in logs. Available formats are `unix`, `unixms`, and `unixmicro`.
|
||||
|
||||
:::tip
|
||||
Shortcut environment variable to enable DEBUG mode: `NEKO_DEBUG=true`
|
||||
:::
|
||||
|
||||
## Full Configuration Reference
|
||||
|
||||
Here is a full configuration with default values as shown in the help command. Please refer to the sub-sections for more details.
|
||||
|
||||
import Configuration from '@site/src/components/Configuration';
|
||||
import configOptions from './help.json';
|
||||
|
||||
<Configuration configOptions={configOptions} />
|
||||
|
||||
## Next Steps
|
||||
|
||||
import DocCardList from '@theme/DocCardList';
|
||||
|
||||
<DocCardList />
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"position": 5,
|
||||
"label": "Configuration",
|
||||
"collapsed": false,
|
||||
"collapsible": false
|
||||
}
|
|
@ -1,369 +0,0 @@
|
|||
---
|
||||
sidebar_position: 1
|
||||
description: Configuration related to the Authentication and Sessions in Neko.
|
||||
---
|
||||
|
||||
# Authentication
|
||||
|
||||
Authentication is split into two modules:
|
||||
|
||||
- **[Member Provider](#member-providers)** - handles authentication and authorization of users, can be used to authenticate users against a database, LDAP, or any other system.
|
||||
- **[Session Provider](#session-provider)** - handles session management, after the module authenticates the user, it creates a session and handles the session lifecycle.
|
||||
|
||||
## Member Profile
|
||||
|
||||
A member profile is a structure that describes the user and what the user is allowed to do in the system.
|
||||
|
||||
| Field | Description | Type |
|
||||
|----------------------------|-------------|------|
|
||||
| `name` | User's name as shown in the UI, must not be unique within the system (not used as an identifier). | string |
|
||||
| `is_admin` | Whether the user can perform administrative tasks that include managing users, sessions, and settings. | boolean |
|
||||
| `can_login` | Whether the user can log in to the system and use the HTTP API. | boolean |
|
||||
| `can_connect` | Whether the user can connect to the room using the WebSocket API (needs `can_login` to be enabled). | boolean |
|
||||
| `can_watch` | Whether the user can connect to the WebRTC stream and watch the room's audio and video (needs `can_connect` to be enabled). | boolean |
|
||||
| `can_host` | Whether the user can grab control of the room and control the mouse and keyboard. | boolean |
|
||||
| `can_share_media` | Whether the user can share their webcam and microphone with the room. | boolean |
|
||||
| `can_access_clipboard` | Whether the user can read and write to the room's clipboard. | boolean |
|
||||
| `sends_inactive_cursor` | Whether the user sends the cursor position even when the user is not hosting the room, this is used to show the cursor of the user to other users. | boolean |
|
||||
| `can_see_inactive_cursors` | Whether the user can see the cursor of other users even when they are not hosting the room. | boolean |
|
||||
| `plugins` | A map of plugin names and their configuration, plugins can use this to store user-specific settings, see the [Plugins Configuration](/docs/v3/getting-started/configuration/plugins) for more information. | object |
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="yaml" label="YAML" default>
|
||||
|
||||
```yaml title="Example member profile in YAML"
|
||||
name: User Name
|
||||
is_admin: false
|
||||
can_login: true
|
||||
can_connect: true
|
||||
can_watch: true
|
||||
can_host: true
|
||||
can_share_media: true
|
||||
can_access_clipboard: true
|
||||
sends_inactive_cursor: true
|
||||
can_see_inactive_cursors: true
|
||||
plugins:
|
||||
<key>: <value>
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="json" label="JSON">
|
||||
|
||||
```json title="Example member profile in JSON"
|
||||
{
|
||||
"name": "User Name",
|
||||
"is_admin": false,
|
||||
"can_login": true,
|
||||
"can_connect": true,
|
||||
"can_watch": true,
|
||||
"can_host": true,
|
||||
"can_share_media": true,
|
||||
"can_access_clipboard": true,
|
||||
"sends_inactive_cursor": true,
|
||||
"can_see_inactive_cursors": true,
|
||||
"plugins": {
|
||||
"<key>": "<value>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Member Providers
|
||||
|
||||
Member providers are responsible for deciding whether given credentials are valid or not. This validation can either be done against a local database or an external system.
|
||||
|
||||
### Multi-User Provider
|
||||
|
||||
This is the **default provider** that works exactly like the authentication used to work in v2 of neko.
|
||||
|
||||
This provider allows you to define two types of users: **regular** users and **admins**. Which user is an admin is determined by the password they provide when logging in. If the password is correct, the user is an admin; otherwise, they are a regular user. Based on those profiles, the users are generated on demand when they log in and they are removed when they log out. Their username is prefixed with 5 random characters to avoid conflicts when multiple users share the same username.
|
||||
|
||||
Profiles for regular users and admins are optional, if not provided, the default profiles are used (see below in the example configuration).
|
||||
|
||||
```yaml title="config.yaml"
|
||||
member:
|
||||
provider: multiuser
|
||||
multiuser:
|
||||
# Password for admins, in plain text.
|
||||
admin_password: "adminPassword"
|
||||
# Profile fields as described above
|
||||
admin_profile:
|
||||
...
|
||||
# Password for regular users, in plain text.
|
||||
user_password: "userPassword"
|
||||
# Profile fields as described above
|
||||
user_profile:
|
||||
...
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>See example configuration</summary>
|
||||
|
||||
The default profiles for regular users and admins are as follows, highlighting the differences between them.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
member:
|
||||
provider: multiuser
|
||||
multiuser:
|
||||
admin_password: "admin"
|
||||
admin_profile:
|
||||
name: "" # if empty, the login username is used
|
||||
# highlight-start
|
||||
is_admin: true
|
||||
# highlight-end
|
||||
can_login: true
|
||||
can_connect: true
|
||||
can_watch: true
|
||||
can_host: true
|
||||
can_share_media: true
|
||||
can_access_clipboard: true
|
||||
sends_inactive_cursor: true
|
||||
# highlight-start
|
||||
can_see_inactive_cursors: true
|
||||
# highlight-end
|
||||
user_password: "neko"
|
||||
user_profile:
|
||||
name: "" # if empty, the login username is used
|
||||
# highlight-start
|
||||
is_admin: false
|
||||
# highlight-end
|
||||
can_login: true
|
||||
can_connect: true
|
||||
can_watch: true
|
||||
can_host: true
|
||||
can_share_media: true
|
||||
can_access_clipboard: true
|
||||
sends_inactive_cursor: true
|
||||
# highlight-start
|
||||
can_see_inactive_cursors: false
|
||||
# highlight-end
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
:::tip
|
||||
For easier configuration, you can specify only passwords using environment variables:
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
environment:
|
||||
NEKO_MEMBER_MULTIUSER_USER_PASSWORD: "neko"
|
||||
NEKO_MEMBER_MULTIUSER_ADMIN_PASSWORD: "admin"
|
||||
```
|
||||
:::
|
||||
|
||||
### File Provider
|
||||
|
||||
This provider reads the user's credentials from a file. It is useful for small deployments where you don't want to set up a database or LDAP server and still want to have persistent users.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
member:
|
||||
provider: file
|
||||
file:
|
||||
# Absolute path to the file containing the users and their passwords.
|
||||
path: /opt/neko/members.json
|
||||
# Whether the passwords are hashed using sha256 or not.
|
||||
hash: true
|
||||
```
|
||||
|
||||
It allows you to store the user's credentials in a JSON file. The JSON structure maps user logins to their passwords and profiles.
|
||||
|
||||
```json title="members.json"
|
||||
{
|
||||
"<user_login>": {
|
||||
"password": "<user_password>",
|
||||
"profile": /* Member Profile, as described above */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can leave the file empty and add users later using the HTTP API.
|
||||
|
||||
<details>
|
||||
<summary>See example `members.json` file</summary>
|
||||
|
||||
We have two users, `admin` and `user` with their passwords and profiles. `admin` is a regular user, while `user` is an admin.
|
||||
|
||||
Please note that the passwords are stored in plain text. To store them securely, set the `hash` field to `true` in the configuration. After that, the passwords are expected to be hashed using the bcrypt algorithm.
|
||||
|
||||
```json title="members.json"
|
||||
{
|
||||
"admin": {
|
||||
"password": "admin",
|
||||
"profile": {
|
||||
"name": "Administrator",
|
||||
"is_admin": true,
|
||||
"can_login": true,
|
||||
"can_connect": true,
|
||||
"can_watch": true,
|
||||
"can_host": true,
|
||||
"can_share_media": true,
|
||||
"can_access_clipboard": true,
|
||||
"sends_inactive_cursor": true,
|
||||
"can_see_inactive_cursors": true,
|
||||
"plugins": {}
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"password": "neko",
|
||||
"profile": {
|
||||
"name": "User",
|
||||
"is_admin": false,
|
||||
"can_login": true,
|
||||
"can_connect": true,
|
||||
"can_watch": true,
|
||||
"can_host": true,
|
||||
"can_share_media": true,
|
||||
"can_access_clipboard": true,
|
||||
"sends_inactive_cursor": true,
|
||||
"can_see_inactive_cursors": false,
|
||||
"plugins": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If you want to hash the passwords, you can use the following command to generate a sha256 hash:
|
||||
|
||||
```bash
|
||||
echo -n "password" | sha256sum
|
||||
```
|
||||
</details>
|
||||
|
||||
### Object Provider
|
||||
|
||||
This provider is the same as the file provider, but it saves the users only in memory. That means that the users are lost when the server is restarted. However, the default users can be set in the configuration file. The difference from the multi-user provider is that the users are not generated on demand and we define exactly which users with their passwords and profiles are allowed to log in. They cannot be logged in twice with the same username.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
member:
|
||||
provider: object
|
||||
object:
|
||||
# List of users with their passwords and profiles
|
||||
- username: "admin"
|
||||
# Password in plain text
|
||||
password: "admin"
|
||||
# Profile fields as described above
|
||||
profile:
|
||||
...
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>See example configuration</summary>
|
||||
|
||||
We have two users, `admin` and `user` with their passwords and profiles. `admin` is an admin, while `user` is a regular user.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
member:
|
||||
provider: object
|
||||
object:
|
||||
users:
|
||||
- username: "admin"
|
||||
password: "admin"
|
||||
profile:
|
||||
name: "Administrator"
|
||||
is_admin: true
|
||||
can_login: true
|
||||
can_connect: true
|
||||
can_watch: true
|
||||
can_host: true
|
||||
can_share_media: true
|
||||
can_access_clipboard: true
|
||||
sends_inactive_cursor: true
|
||||
can_see_inactive_cursors: true
|
||||
- username: "user"
|
||||
password: "neko"
|
||||
profile:
|
||||
name: "User"
|
||||
is_admin: false
|
||||
can_login: true
|
||||
can_connect: true
|
||||
can_watch: true
|
||||
can_host: true
|
||||
can_share_media: true
|
||||
can_access_clipboard: true
|
||||
sends_inactive_cursor: true
|
||||
can_see_inactive_cursors: false
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
### No-Auth Provider
|
||||
|
||||
This provider allows any user to log in without any authentication. It is useful for testing and development purposes.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
member:
|
||||
provider: noauth
|
||||
```
|
||||
|
||||
:::danger
|
||||
Do not use this provider in production environments unless you know exactly what you are doing. It allows anyone to log in and control neko as an admin.
|
||||
:::
|
||||
|
||||
## Session Provider
|
||||
|
||||
Currently, there are only two providers available for sessions: **memory** and **file**.
|
||||
|
||||
Simply by specifying the `session.file` to a file path, the session provider will store the sessions in a file. Otherwise, the sessions are stored in memory and are lost when the server is restarted.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
session:
|
||||
file: /opt/neko/sessions.json
|
||||
```
|
||||
|
||||
:::info
|
||||
In the future, we plan to add more session providers, such as Redis, PostgreSQL, etc. So the Configuration Options may change.
|
||||
:::
|
||||
|
||||
## API User
|
||||
|
||||
The API User is a special user that is used to authenticate the HTTP API requests. It cannot connect to the room, but it can perform administrative tasks. The API User does not have a password but only a token that is used to authenticate the requests. If the token is not set, the API User is disabled.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
session:
|
||||
api_token: "apiToken"
|
||||
```
|
||||
|
||||
:::tip
|
||||
This user is useful in some situations when the rooms are generated by the server and the token is guaranteed to be random every time a short-lived room is run. It is not a good idea to define this token for long-lived rooms, as it can be stolen and used to perform administrative tasks.
|
||||
|
||||
You can generate a random token using the following command:
|
||||
|
||||
```bash
|
||||
openssl rand -hex 32
|
||||
```
|
||||
:::
|
||||
|
||||
## Cookies
|
||||
|
||||
The authentication between the client and the server can be done using cookies or the `Authorization` header. The cookies are used by default, but you can disable them by setting the `session.cookie.enabled` to `false`.
|
||||
|
||||
:::warning
|
||||
If you disable the cookies, the token will be sent to the client in the login response and saved in local storage. This is less secure than using cookies, as the token **can be stolen using XSS attacks**. Therefore, it is recommended to use cookies.
|
||||
:::
|
||||
|
||||
```yaml title="config.yaml"
|
||||
session:
|
||||
cookie:
|
||||
enabled: true
|
||||
name: "NEKO_SESSION"
|
||||
expiration: "24h"
|
||||
secure: true
|
||||
http_only: true
|
||||
domain: ""
|
||||
path: ""
|
||||
```
|
||||
|
||||
- `enabled` - Whether the cookies are enabled or not.
|
||||
- `name` - Name of the cookie used to store the session.
|
||||
- `expiration` - Expiration time of the cookie, use [go duration format](https://pkg.go.dev/time#ParseDuration) (e.g., `24h`, `1h30m`, `60m`).
|
||||
- `secure` and `http_only` - Ensures that the cookie is only sent over HTTPS and cannot be accessed by JavaScript, see [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#block_access_to_your_cookies) for more information.
|
||||
- `domain` and `path` - Define where the cookie is valid, see [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent) for more information.
|
||||
|
||||
:::info
|
||||
The `secure` and `http_only` are set to `true` by default, which means that the cookie is only sent over HTTPS. If you are using HTTP, you should really consider using HTTPS. Only for testing and development purposes should you consider setting it to `false`.
|
||||
:::
|
|
@ -1,481 +0,0 @@
|
|||
---
|
||||
sidebar_position: 2
|
||||
description: Configuration related to Gstreamer capture in Neko.
|
||||
---
|
||||
|
||||
# Audio & Video Capture
|
||||
|
||||
This guide will show you how to configure the audio and video capture settings in neko.
|
||||
|
||||
Neko uses [Gstreamer](https://gstreamer.freedesktop.org/) to capture and encode audio and video in the following scenarios:
|
||||
|
||||
- WebRTC clients use the [Video](#webrtc-video) and [Audio](#webrtc-audio) pipelines to receive the audio and video streams from the server.
|
||||
- The [Broadcast](#broadcast) feature allows you to broadcast the audio and video to a third-party service using RTMP.
|
||||
- The WebRTC Fallback mechanism allows you to capture the display in the form of JPEG images and serve them over HTTP using [Screencast](#screencast).
|
||||
- Clients can share their [Webcam](#webcam) and [Microphone](#microphone) with the server using WebRTC.
|
||||
|
||||
## WebRTC Video
|
||||
|
||||
Neko allows you to capture the display and encode it in real-time using Gstreamer. The encoded video is then sent to the client using WebRTC. This allows you to share the display with the client in real-time.
|
||||
|
||||
There can exist multiple video pipelines in neko that are referenced by their unique pipeline id. Each video pipeline can have its own configuration settings and clients can either choose which pipeline they want to use or let neko choose the best pipeline for them.
|
||||
|
||||
:::info Limitation
|
||||
All video pipelines must use the same video codec (defined in the `capture.video.codec` setting).
|
||||
:::
|
||||
|
||||
The Gstreamer pipeline is started when the first client requests the video stream and is stopped after the last client disconnects.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
video:
|
||||
display: "<display_name>"
|
||||
codec: "vp8" # default video codec
|
||||
ids: [ <pipeline_id1>, <pipeline_id2>, ... ]
|
||||
pipelines:
|
||||
<pipeline_id1>: <pipeline_config>
|
||||
<pipeline_id2>: <pipeline_config>
|
||||
...
|
||||
```
|
||||
|
||||
- `display` is the name of the [X display](https://www.x.org/wiki/) that you want to capture. If not specified, the environment variable `DISPLAY` will be used.
|
||||
- `codec` available codecs are `vp8`, `vp9`, `av1`, `h264`. [Supported video codecs](https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Formats/WebRTC_codecs#supported_video_codecs) are dependent on the WebRTC implementation used by the client, `vp8` and `h264` are supported by all WebRTC implementations.
|
||||
- `ids` is a list of pipeline ids that are defined in the `pipelines` section. The first pipeline in the list will be the default pipeline.
|
||||
- `pipelines` is a dictionary of pipeline configurations. Each pipeline configuration is defined by a unique pipeline id. They can be defined in two ways: either by building the pipeline dynamically using [Expression-Driven Configuration](#expression-driven-configuration) or by defining the pipeline using a [Gstreamer Pipeline Description](#gstreamer-pipeline-description).
|
||||
|
||||
### Expression-Driven Configuration
|
||||
|
||||
Expression allows you to build the pipeline dynamically based on the current resolution and framerate of the display. Expressions are evaluated using the [gval](https://github.com/PaesslerAG/gval) library. Available variables are `width`, `height`, and `fps` of the display at the time of capture.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
video:
|
||||
...
|
||||
pipelines:
|
||||
<pipeline_id>:
|
||||
width: "<expression>"
|
||||
height: "<expression>"
|
||||
fps: "<expression>"
|
||||
gst_prefix: "<gst_pipeline>"
|
||||
gst_encoder: "<gst_encoder_name>"
|
||||
gst_params:
|
||||
<param_name>: "<expression>"
|
||||
gst_suffix: "<gst_pipeline>"
|
||||
show_pointer: true
|
||||
```
|
||||
|
||||
- `width`, `height`, and `fps` are the expressions that are evaluated to get the stream resolution and framerate. They can be different from the display resolution and framerate if downscaling or upscaling is desired.
|
||||
- `gst_prefix` and `gst_suffix` allow you to add custom Gstreamer elements before and after the encoder. Both parameters need to start with `!` and then be followed by the Gstreamer elements.
|
||||
- `gst_encoder` is the name of the Gstreamer encoder element, such as `vp8enc` or `x264enc`.
|
||||
- `gst_params` are the parameters that are passed to the encoder element specified in `gst_encoder`.
|
||||
- `show_pointer` is a boolean value that determines whether the mouse pointer should be captured or not.
|
||||
|
||||
<details>
|
||||
<summary>Example pipeline configuration</summary>
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="vp8" label="VP8 configuration">
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
video:
|
||||
codec: vp8
|
||||
# HQ is the default pipeline
|
||||
ids: [ hq, lq ]
|
||||
pipelines:
|
||||
hq:
|
||||
fps: 25
|
||||
gst_encoder: vp8enc
|
||||
gst_params:
|
||||
target-bitrate: round(3072 * 650)
|
||||
cpu-used: 4
|
||||
end-usage: cbr
|
||||
threads: 4
|
||||
deadline: 1
|
||||
undershoot: 95
|
||||
buffer-size: (3072 * 4)
|
||||
buffer-initial-size: (3072 * 2)
|
||||
buffer-optimal-size: (3072 * 3)
|
||||
keyframe-max-dist: 25
|
||||
min-quantizer: 4
|
||||
max-quantizer: 20
|
||||
lq:
|
||||
fps: 25
|
||||
gst_encoder: vp8enc
|
||||
gst_params:
|
||||
target-bitrate: round(1024 * 650)
|
||||
cpu-used: 4
|
||||
end-usage: cbr
|
||||
threads: 4
|
||||
deadline: 1
|
||||
undershoot: 95
|
||||
buffer-size: (1024 * 4)
|
||||
buffer-initial-size: (1024 * 2)
|
||||
buffer-optimal-size: (1024 * 3)
|
||||
keyframe-max-dist: 25
|
||||
min-quantizer: 4
|
||||
max-quantizer: 20
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="h264" label="H264 configuration">
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
video:
|
||||
codec: h264
|
||||
ids: [ main ]
|
||||
pipelines:
|
||||
main:
|
||||
width: (width / 3) * 2
|
||||
height: (height / 3) * 2
|
||||
fps: 20
|
||||
gst_prefix: "! video/x-raw,format=I420"
|
||||
gst_encoder: "x264enc"
|
||||
gst_params:
|
||||
threads: 4
|
||||
bitrate: 4096
|
||||
key-int-max: 15
|
||||
byte-stream: true
|
||||
tune: zerolatency
|
||||
speed-preset: veryfast
|
||||
gst_suffix: "! video/x-h264,stream-format=byte-stream"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
</details>
|
||||
|
||||
### Gstreamer Pipeline Description
|
||||
|
||||
If you want to define the pipeline using a [Gstreamer pipeline description](https://gstreamer.freedesktop.org/documentation/tools/gst-launch.html?gi-language=c#pipeline-description), you can do so by setting the `gst_pipeline` parameter.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
video:
|
||||
...
|
||||
pipelines:
|
||||
<pipeline_id>:
|
||||
gst_pipeline: "<gstreamer_pipeline>"
|
||||
```
|
||||
|
||||
Since now you have to define the whole pipeline, you need to specify the src element to get the video frames and the sink element to send the encoded video frames to neko. In your pipeline, you can use `{display}` as a placeholder for the display name that will be replaced by the actual display name at runtime. You need to set the `name` property of the sink element to `appsink` so that neko can capture the video frames.
|
||||
|
||||
Your typical pipeline string would look like this:
|
||||
|
||||
```
|
||||
ximagesrc display-name={display} show-pointer=true use-damage=false ! <your_elements> ! appsink name=appsink"
|
||||
```
|
||||
|
||||
See documentation for [ximagesrc](https://gstreamer.freedesktop.org/documentation/ximagesrc/index.html) and [appsink](https://gstreamer.freedesktop.org/documentation/app/appsink.html) for more information.
|
||||
|
||||
<details>
|
||||
<summary>Example pipeline configuration</summary>
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="vp8" label="VP8 configuration">
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
video:
|
||||
codec: vp8
|
||||
ids: [ hq, lq ]
|
||||
pipelines:
|
||||
hq:
|
||||
gst_pipeline: |
|
||||
ximagesrc display-name={display} show-pointer=true use-damage=false
|
||||
! videoconvert
|
||||
! vp8enc
|
||||
target-bitrate=3072000
|
||||
cpu-used=4
|
||||
end-usage=cbr
|
||||
threads=4
|
||||
deadline=1
|
||||
undershoot=95
|
||||
buffer-size=12288
|
||||
buffer-initial-size=6144
|
||||
buffer-optimal-size=9216
|
||||
keyframe-max-dist=25
|
||||
min-quantizer=4
|
||||
max-quantizer=20
|
||||
! appsink name=appsink
|
||||
lq:
|
||||
gst_pipeline: |
|
||||
ximagesrc display-name={display} show-pointer=true use-damage=false
|
||||
! videoconvert
|
||||
! vp8enc
|
||||
target-bitrate=1024000
|
||||
cpu-used=4
|
||||
end-usage=cbr
|
||||
threads=4
|
||||
deadline=1
|
||||
undershoot=95
|
||||
buffer-size=4096
|
||||
buffer-initial-size=2048
|
||||
buffer-optimal-size=3072
|
||||
keyframe-max-dist=25
|
||||
min-quantizer=4
|
||||
max-quantizer=20
|
||||
! appsink name=appsink
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="h264" label="H264 configuration">
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
video:
|
||||
codec: h264
|
||||
ids: [ main ]
|
||||
pipelines:
|
||||
main:
|
||||
gst_pipeline: |
|
||||
ximagesrc display-name={display} show-pointer=true use-damage=false
|
||||
! videoconvert
|
||||
! x264enc
|
||||
threads=4
|
||||
bitrate=4096
|
||||
key-int-max=15
|
||||
byte-stream=true
|
||||
tune=zerolatency
|
||||
speed-preset=veryfast
|
||||
! video/x-h264,stream-format=byte-stream
|
||||
! appsink name=appsink
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
</details>
|
||||
|
||||
## WebRTC Audio
|
||||
|
||||
Only one audio pipeline can be defined in neko. The audio pipeline is used to capture and encode audio, similar to the video pipeline. The encoded audio is then sent to the client using WebRTC.
|
||||
|
||||
The Gstreamer pipeline is started when the first client requests the video stream and is stopped after the last client disconnects.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
audio:
|
||||
device: "audio_output.monitor" # default audio device
|
||||
codec: "opus" # default audio codec
|
||||
pipeline: "<gstreamer_pipeline>"
|
||||
```
|
||||
|
||||
- `device` is the name of the [pulseaudio device](https://wiki.archlinux.org/title/PulseAudio/Examples) that you want to capture. If not specified, the default audio device will be used.
|
||||
- `codec` available codecs are `opus`, `g722`, `pcmu`, `pcma`. [Supported audio codecs](https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Formats/WebRTC_codecs#supported_audio_codecs) are dependent on the WebRTC implementation used by the client, `opus` is supported by all WebRTC implementations.
|
||||
- `pipeline` is the Gstreamer pipeline description that is used to capture and encode audio. You can use `{device}` as a placeholder for the audio device name that will be replaced by the actual device name at runtime.
|
||||
|
||||
<details>
|
||||
<summary>Example pipeline configuration</summary>
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
audio:
|
||||
codec: opus
|
||||
pipeline: |
|
||||
pulsesrc device={device}
|
||||
! audioconvert
|
||||
! opusenc
|
||||
bitrate=320000
|
||||
! appsink name=appsink
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Broadcast
|
||||
|
||||
Neko allows you to broadcast out-of-the-box the display and audio capture to a third-party service. This can be used to broadcast the display and audio to a streaming service like [Twitch](https://www.twitch.tv/) or [YouTube](https://www.youtube.com/), or to a custom RTMP server like [OBS](https://obsproject.com/), [Nginx RTMP module](https://github.com/arut/nginx-rtmp-module), or [MediaMTX](https://github.com/bluenviron/mediamtx).
|
||||
|
||||
The Gstreamer pipeline is started when the broadcast is started and is stopped when the broadcast is stopped regardless of the clients connected.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
broadcast:
|
||||
audio_bitrate: 128 # in KB/s
|
||||
video_bitrate: 4096 # in KB/s
|
||||
preset: "veryfast"
|
||||
pipeline: "<gstreamer_pipeline>"
|
||||
url: "rtmp://<server>/<application>/<stream_key>"
|
||||
autostart: true
|
||||
```
|
||||
|
||||
The default encoder uses `h264` for video and `aac` for audio, muxed in the `flv` container and sent over the `rtmp` protocol. You can change the encoder settings by setting a custom Gstreamer pipeline description in the `pipeline` parameter.
|
||||
|
||||
- `audio_bitrate` and `video_bitrate` are the bitrate settings for the default audio and video encoders expressed in kilobits per second.
|
||||
- `preset` is the encoding speed preset for the default video encoder. See available presets [here](https://gstreamer.freedesktop.org/documentation/x264/index.html?gi-language=c#GstX264EncPreset).
|
||||
- `pipeline` when set, encoder settings above are ignored and the custom Gstreamer pipeline description is used. In the pipeline, you can use `{display}`, `{device}` and `{url}` as placeholders for the X display name, pulseaudio audio device name, and broadcast URL respectively.
|
||||
- `url` is the URL of the RTMP server where the broadcast will be sent. This can be set later using the API if the URL is not known at the time of configuration or is expected to change.
|
||||
- `autostart` is a boolean value that determines whether the broadcast should start automatically when neko starts, works only if the URL is set.
|
||||
|
||||
<details>
|
||||
<summary>Example pipeline configuration</summary>
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="x264" label="X264 configuration">
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
broadcast:
|
||||
audio_bitrate: 128
|
||||
video_bitrate: 4096
|
||||
preset: veryfast
|
||||
pipeline: |
|
||||
flvmux name=mux
|
||||
! rtmpsink location={url}
|
||||
pulsesrc device={device}
|
||||
! audio/x-raw,channels=2
|
||||
! audioconvert
|
||||
! voaacenc
|
||||
! mux.
|
||||
ximagesrc display-name={display} show-pointer=false use-damage=false
|
||||
! video/x-raw,framerate=28/1
|
||||
! videoconvert
|
||||
! queue
|
||||
! x264enc bframes=0 key-int-max=0 byte-stream=true tune=zerolatency speed-preset=veryfast
|
||||
! mux.
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="nvh264enc" label="NVENC H264 configuration">
|
||||
|
||||
This configuration requires [Nvidia GPU](https://developer.nvidia.com/cuda-gpus) with [NVENC](https://developer.nvidia.com/nvidia-video-codec-sdk) support.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
broadcast:
|
||||
audio_bitrate: 128
|
||||
video_bitrate: 4096
|
||||
preset: veryfast
|
||||
pipeline: |
|
||||
flvmux name=mux
|
||||
! rtmpsink location={url}
|
||||
pulsesrc device={device}
|
||||
! audio/x-raw,channels=2
|
||||
! audioconvert
|
||||
! voaacenc
|
||||
! mux.
|
||||
ximagesrc display-name={display} show-pointer=false use-damage=false
|
||||
! video/x-raw,framerate=30/1
|
||||
! videoconvert
|
||||
! queue
|
||||
! video/x-raw,format=NV12
|
||||
! nvh264enc name=encoder preset=low-latency-hq gop-size=25 spatial-aq=true temporal-aq=true bitrate=2800 vbv-buffer-size=2800 rc-mode=6
|
||||
! h264parse config-interval=-1
|
||||
! video/x-h264,stream-format=byte-stream,profile=high
|
||||
! h264parse
|
||||
! mux.
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
</details>
|
||||
|
||||
## Screencast
|
||||
|
||||
As a fallback mechanism, neko can capture the display in the form of JPEG images and the client can request these images over HTTP. This is useful when the client does not support WebRTC or when the client is not able to establish a WebRTC connection, or there is a temporary issue with the WebRTC connection and the client should not miss the content being shared.
|
||||
|
||||
:::note
|
||||
This is a fallback mechanism and should not be used as a primary video stream because of the high latency, low quality, and high bandwidth requirements.
|
||||
:::
|
||||
|
||||
The Gstreamer pipeline is started in the background when the first client requests the screencast and is stopped after a period of inactivity.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
screencast:
|
||||
enabled: true
|
||||
rate: "10/1"
|
||||
quality: 60
|
||||
pipeline: "<gstreamer_pipeline>"
|
||||
```
|
||||
|
||||
- `enabled` is a boolean value that determines whether the screencast is enabled or not.
|
||||
- `rate` is the framerate of the screencast. It is expressed as a fraction of frames per second, for example, `10/1` means 10 frames per second.
|
||||
- `quality` is the quality of the JPEG images. It is expressed as a percentage, for example, `60` means 60% quality.
|
||||
- `pipeline` when set, the default pipeline settings above are ignored and the custom Gstreamer pipeline description is used. In the pipeline, you can use `{display}` as a placeholder for the X display name.
|
||||
|
||||
<details>
|
||||
<summary>Example pipeline configuration</summary>
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
screencast:
|
||||
enabled: true
|
||||
rate: "10/1"
|
||||
quality: 60
|
||||
pipeline: |
|
||||
ximagesrc display-name={display} show-pointer=true use-damage=false
|
||||
! video/x-raw,framerate=10/1
|
||||
! videoconvert
|
||||
! queue
|
||||
! jpegenc quality=60
|
||||
! appsink name=appsink
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## Webcam
|
||||
|
||||
:::danger
|
||||
This feature is experimental and may not work on all platforms.
|
||||
:::
|
||||
|
||||
Neko allows you to capture the webcam on the client machine and send it to the server using WebRTC. This can be used to share the webcam feed with the server.
|
||||
|
||||
The Gstreamer pipeline is started when the client shares their webcam and is stopped when the client stops sharing the webcam. Maximum one webcam pipeline can be active at a time.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
webcam:
|
||||
enabled: true
|
||||
device: "/dev/video0" # default webcam device
|
||||
width: 640
|
||||
height: 480
|
||||
```
|
||||
|
||||
- `enabled` is a boolean value that determines whether the webcam capture is enabled or not.
|
||||
- `device` is the name of the [video4linux device](https://www.kernel.org/doc/html/v4.12/media/v4l-drivers/index.html) that will be used as a virtual webcam.
|
||||
- `width` and `height` are the resolution of the virtual webcam feed.
|
||||
|
||||
In order to use the webcam feature, the server must have the [v4l2loopback](https://github.com/v4l2loopback/v4l2loopback) kernel module installed and loaded. The module can be loaded using the following command:
|
||||
|
||||
```bash
|
||||
# Install the required packages (Debian/Ubuntu)
|
||||
sudo apt install v4l2loopback-dkms v4l2loopback-utils linux-headers-`uname -r` linux-modules-extra-`uname -r`
|
||||
# Load the module with exclusive_caps=1 to allow multiple applications to access the virtual webcam
|
||||
sudo modprobe v4l2loopback exclusive_caps=1
|
||||
```
|
||||
|
||||
This is needed even if neko is running inside a Docker container. In that case, the v4l2loopback module must be loaded on the host machine and the device must be mounted inside the container.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
services:
|
||||
neko:
|
||||
...
|
||||
# highlight-start
|
||||
devices:
|
||||
- /dev/video0:/dev/video0
|
||||
# highlight-end
|
||||
...
|
||||
```
|
||||
|
||||
## Microphone
|
||||
|
||||
Neko allows you to capture the microphone on the client machine and send it to the server using WebRTC. This can be used to share the microphone feed with the server.
|
||||
|
||||
The Gstreamer pipeline is started when the client shares their microphone and is stopped when the client stops sharing the microphone. Maximum one microphone pipeline can be active at a time.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
capture:
|
||||
microphone:
|
||||
enabled: true
|
||||
device: "audio_input"
|
||||
```
|
||||
|
||||
- `enabled` is a boolean value that determines whether the microphone capture is enabled or not.
|
||||
- `device` is the name of the [pulseaudio device](https://wiki.archlinux.org/title/PulseAudio/Examples) that will be used as a virtual microphone.
|
|
@ -1,82 +0,0 @@
|
|||
---
|
||||
sidebar_position: 3
|
||||
description: Configuration related to the Desktop Environment in Neko.
|
||||
---
|
||||
|
||||
# Desktop Environment
|
||||
|
||||
This section describes how to configure the desktop environment inside neko.
|
||||
|
||||
Neko uses the [X Server](https://www.x.org/archive/X11R7.6/doc/man/man1/Xserver.1.xhtml) as the display server with [Openbox](http://openbox.org/wiki/Main_Page) as the default window manager. For audio, [PulseAudio](https://www.freedesktop.org/wiki/Software/PulseAudio/) is used.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
desktop:
|
||||
display: "<display>"
|
||||
screen: "1280x720@30" # default
|
||||
```
|
||||
|
||||
- `display` refers to the X server that is running on the system. If it is not specified, the environment variable `DISPLAY` is used. The same display is referred to in the [Capture](capture#webrtc-video) configuration to capture the screen. In most cases, we want to use the same display for both.
|
||||
- `screen` refers to the screen resolution and refresh rate. The format is `<width>x<height>@<refresh rate>`. If not specified, the default is `1280x720@30`.
|
||||
|
||||
:::tip
|
||||
You can specify the screen resolution using the environment variable `NEKO_DESKTOP_SCREEN`.
|
||||
|
||||
Admin can change the resolution in the GUI.
|
||||
:::
|
||||
|
||||
## Input Devices
|
||||
|
||||
Neko uses the [XTEST Extension Library](https://www.x.org/releases/X11R7.7/doc/libXtst/xtestlib.html) to simulate keyboard and mouse events. However, for more advanced input devices like touchscreens, we need to use a custom driver that can be loaded as a plugin to the X server and then neko can connect to it.
|
||||
|
||||
:::note
|
||||
Currently, only touchscreens are supported through the custom driver.
|
||||
:::
|
||||
|
||||
```yaml title="config.yaml"
|
||||
desktop:
|
||||
input:
|
||||
enabled: true # default
|
||||
socket: "/tmp/xf86-input-neko.sock" # default
|
||||
```
|
||||
|
||||
- `enabled` enables the input device support. If not specified, the default is `false`.
|
||||
- `socket` refers to the socket file that the custom driver creates. If not specified, the default is `/tmp/xf86-input-neko.sock`.
|
||||
|
||||
:::info
|
||||
When using Docker, the custom driver is already included in the image and the socket file is created at `/tmp/xf86-input-neko.sock`. Therefore, no additional configuration is needed.
|
||||
:::
|
||||
|
||||
## Unminimize
|
||||
|
||||
Most of the time, only a single application is used in the minimal desktop environment without any taskbar or desktop icons. It could happen that the user accidentally minimizes the application and then it is not possible to restore it. To prevent this, we can use the `unminimize` feature that simply listens for the minimize event and restores the window back to the original state.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
desktop:
|
||||
unminimize: true # default
|
||||
```
|
||||
|
||||
## Upload Drop
|
||||
|
||||
The upload drop is a feature that allows the user to upload files to the application by dragging and dropping them into the application window. The files are then uploaded to the application and the application can process them.
|
||||
|
||||
The current approach is to catch the drag and drop events on the client side, upload them to the server along with the coordinates of the drop event, and then open an invisible overlay window on the server that has set the file path to the uploaded file and allows it to be dragged and dropped into the application. Then the mouse events are simulated to drag the file from the overlay window to the application window.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
desktop:
|
||||
upload_drop: true # default
|
||||
```
|
||||
|
||||
## File Chooser Dialog
|
||||
|
||||
:::danger
|
||||
This feature is experimental and may not work as expected.
|
||||
:::
|
||||
|
||||
The file chooser dialog is a feature that allows handling the file chooser dialog in the application (for example, when uploading a file) externally. This means that the file chooser dialog is not displayed inside the neko desktop environment, but the neko client is requested to upload the file from the local filesystem.
|
||||
|
||||
The current approach is to put the file chooser dialog in the background as soon as it is displayed, prompt the user to upload the file, and then select this file in the file chooser dialog by simulating the keyboard events to navigate to the file and press the open button. **This is very error-prone and may not work as expected.**
|
||||
|
||||
```yaml title="config.yaml"
|
||||
desktop:
|
||||
file_chooser_dialog: false # default
|
||||
```
|
|
@ -1,876 +0,0 @@
|
|||
[
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"audio",
|
||||
"codec"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "opus",
|
||||
"description": "audio codec to be used"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"audio",
|
||||
"device"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "audio_output.monitor",
|
||||
"description": "pulseaudio device to capture"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"audio",
|
||||
"pipeline"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "gstreamer pipeline used for audio streaming"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"broadcast",
|
||||
"audio_bitrate"
|
||||
],
|
||||
"type": "int",
|
||||
"defaultValue": "128",
|
||||
"description": "broadcast audio bitrate in KB/s"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"broadcast",
|
||||
"autostart"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "automatically start broadcasting when neko starts and broadcast_url is set"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"broadcast",
|
||||
"pipeline"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "gstreamer pipeline used for broadcasting"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"broadcast",
|
||||
"preset"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "veryfast",
|
||||
"description": "broadcast speed preset for h264 encoding"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"broadcast",
|
||||
"url"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "initial URL for broadcasting, setting this value will automatically start broadcasting"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"broadcast",
|
||||
"video_bitrate"
|
||||
],
|
||||
"type": "int",
|
||||
"defaultValue": "4096",
|
||||
"description": "broadcast video bitrate in KB/s"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"microphone",
|
||||
"device"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "audio_input",
|
||||
"description": "pulseaudio device used for microphone"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"microphone",
|
||||
"enabled"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "enable microphone stream"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"screencast",
|
||||
"enabled"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "enable screencast"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"screencast",
|
||||
"pipeline"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "gstreamer pipeline used for screencasting"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"screencast",
|
||||
"quality"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "60",
|
||||
"description": "screencast JPEG quality"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"screencast",
|
||||
"rate"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "10/1",
|
||||
"description": "screencast frame rate"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"video",
|
||||
"codec"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "vp8",
|
||||
"description": "video codec to be used"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"video",
|
||||
"display"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "X display to capture"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"video",
|
||||
"ids"
|
||||
],
|
||||
"type": "strings",
|
||||
"description": "ordered list of video ids"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"video",
|
||||
"pipelines"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "[]",
|
||||
"description": "pipelines config in JSON used for video streaming"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"webcam",
|
||||
"device"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "/dev/video0",
|
||||
"description": "v4l2sink device used for webcam"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"webcam",
|
||||
"enabled"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "enable webcam stream"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"webcam",
|
||||
"height"
|
||||
],
|
||||
"type": "int",
|
||||
"defaultValue": "720",
|
||||
"description": "webcam stream height"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"capture",
|
||||
"webcam",
|
||||
"width"
|
||||
],
|
||||
"type": "int",
|
||||
"defaultValue": "1280",
|
||||
"description": "webcam stream width"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"desktop",
|
||||
"display"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "X display to use for desktop sharing"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"desktop",
|
||||
"file_chooser_dialog"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "whether to handle file chooser dialog externally"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"desktop",
|
||||
"input",
|
||||
"enabled"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "whether custom xf86 input driver should be used to handle touchscreen"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"desktop",
|
||||
"input",
|
||||
"socket"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "/tmp/xf86-input-neko.sock",
|
||||
"description": "socket path for custom xf86 input driver connection"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"desktop",
|
||||
"screen"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "1280x720@30",
|
||||
"description": "default screen size and framerate"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"desktop",
|
||||
"unminimize"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "automatically unminimize window when it is minimized"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"desktop",
|
||||
"upload_drop"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "whether drop upload is enabled"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"member",
|
||||
"file",
|
||||
"hash"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "member file provider: whether to hash passwords using sha256 (recommended)"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"member",
|
||||
"file",
|
||||
"path"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "member file provider: storage path"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"member",
|
||||
"multiuser",
|
||||
"admin_password"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "admin",
|
||||
"description": "member multiuser provider: admin password"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"member",
|
||||
"multiuser",
|
||||
"admin_profile"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "{}",
|
||||
"description": "member multiuser provider: admin profile in JSON format"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"member",
|
||||
"multiuser",
|
||||
"user_password"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "neko",
|
||||
"description": "member multiuser provider: user password"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"member",
|
||||
"multiuser",
|
||||
"user_profile"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "{}",
|
||||
"description": "member multiuser provider: user profile in JSON format"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"member",
|
||||
"object",
|
||||
"users"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "[]",
|
||||
"description": "member object provider: users in JSON format"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"member",
|
||||
"provider"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "multiuser",
|
||||
"description": "choose member provider"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"plugins",
|
||||
"dir"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "./bin/plugins",
|
||||
"description": "path to neko plugins to load"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"plugins",
|
||||
"enabled"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "load plugins in runtime"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"plugins",
|
||||
"required"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "if true, neko will exit if there is an error when loading a plugin"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"bind"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "127.0.0.1:8080",
|
||||
"description": "address/port/socket to serve neko"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"cert"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "path to the SSL cert used to secure the neko server"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"cors"
|
||||
],
|
||||
"type": "strings",
|
||||
"description": "list of allowed origins for CORS, if empty CORS is disabled, if '*' is present all origins are allowed"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"key"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "path to the SSL key used to secure the neko server"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"metrics"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "enable prometheus metrics available at /metrics"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"path_prefix"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "/",
|
||||
"description": "path prefix for HTTP requests"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"pprof"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "enable pprof endpoint available at /debug/pprof"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"proxy"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "trust reverse proxy headers"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"server",
|
||||
"static"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "path to neko client files to serve"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"api_token"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "API token for interacting with external services"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"control_protection"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "users can gain control only if at least one admin is in the room"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"cookie",
|
||||
"domain"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "domain of the cookie"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"cookie",
|
||||
"enabled"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "whether cookies authentication should be enabled"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"cookie",
|
||||
"expiration"
|
||||
],
|
||||
"type": "duration",
|
||||
"defaultValue": "24h0m0s",
|
||||
"description": "expiration of the cookie"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"cookie",
|
||||
"http_only"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "use http only cookies"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"cookie",
|
||||
"name"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "NEKO_SESSION",
|
||||
"description": "name of the cookie that holds token"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"cookie",
|
||||
"path"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "path of the cookie"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"cookie",
|
||||
"secure"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "use secure cookies"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"file"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "if sessions should be stored in a file, otherwise they will be stored only in memory"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"heartbeat_interval"
|
||||
],
|
||||
"type": "int",
|
||||
"defaultValue": "120",
|
||||
"description": "interval in seconds for sending heartbeat messages"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"implicit_hosting"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "allow implicit control switching"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"inactive_cursors"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "show inactive cursors on the screen"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"locked_controls"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "whether controls should be locked for users initially"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"locked_logins"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "whether logins should be locked for users initially"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"merciful_reconnect"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "allow reconnecting to websocket even if previous connection was not closed"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"session",
|
||||
"private_mode"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "whether private mode should be enabled initially"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"epr"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "limits the pool of ephemeral ports that ICE UDP connections can allocate from"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"debug"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "enables debug logging for the bandwidth estimator"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"diff_threshold"
|
||||
],
|
||||
"type": "float",
|
||||
"defaultValue": "0.15",
|
||||
"description": "how bigger the difference between estimated and stream bitrate must be to trigger upgrade/downgrade"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"downgrade_backoff"
|
||||
],
|
||||
"type": "duration",
|
||||
"defaultValue": "10s",
|
||||
"description": "how long to wait before downgrading again after previous downgrade"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"enabled"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "enables the bandwidth estimator"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"initial_bitrate"
|
||||
],
|
||||
"type": "int",
|
||||
"defaultValue": "1000000",
|
||||
"description": "initial bitrate for the bandwidth estimator"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"passive"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "passive estimator mode, when it does not switch pipelines, only estimates"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"read_interval"
|
||||
],
|
||||
"type": "duration",
|
||||
"defaultValue": "2s",
|
||||
"description": "how often to read and process bandwidth estimation reports"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"stable_duration"
|
||||
],
|
||||
"type": "duration",
|
||||
"defaultValue": "12s",
|
||||
"description": "how long to wait for stable connection (upward or neutral trend) before upgrading"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"stalled_duration"
|
||||
],
|
||||
"type": "duration",
|
||||
"defaultValue": "24s",
|
||||
"description": "how long to wait for stalled bandwidth estimation before downgrading"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"unstable_duration"
|
||||
],
|
||||
"type": "duration",
|
||||
"defaultValue": "6s",
|
||||
"description": "how long to wait for stalled connection (neutral trend with low bandwidth) before downgrading"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"estimator",
|
||||
"upgrade_backoff"
|
||||
],
|
||||
"type": "duration",
|
||||
"defaultValue": "5s",
|
||||
"description": "how long to wait before upgrading again after previous upgrade"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"icelite"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "configures whether or not the ICE agent should be a lite agent"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"iceservers",
|
||||
"backend"
|
||||
],
|
||||
"type": "urls",
|
||||
"defaultValue": "[]",
|
||||
"description": "Backend only STUN and TURN servers in JSON format with urls, `username` and `credential` keys"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"iceservers",
|
||||
"frontend"
|
||||
],
|
||||
"type": "urls",
|
||||
"defaultValue": "[]",
|
||||
"description": "Frontend only STUN and TURN servers in JSON format with urls, `username` and `credential` keys"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"icetrickle"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "configures whether cadidates should be sent asynchronously using Trickle ICE"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"ip_retrieval_url"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "https://checkip.amazonaws.com",
|
||||
"description": "URL address used for retrieval of the external IP address"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"nat1to1"
|
||||
],
|
||||
"type": "strings",
|
||||
"description": "sets a list of external IP addresses of 1:1 (D)NAT and a candidate type for which the external IP address is used"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"tcpmux"
|
||||
],
|
||||
"type": "int",
|
||||
"description": "single TCP mux port for all peers"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"webrtc",
|
||||
"udpmux"
|
||||
],
|
||||
"type": "int",
|
||||
"description": "single UDP mux port for all peers, replaces EPR"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"config"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "configuration file path"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"debug"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "enable debug mode"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"log",
|
||||
"dir"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "logging directory to store logs"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"log",
|
||||
"json"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "logs in JSON format"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"log",
|
||||
"level"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "info",
|
||||
"description": "set log level (trace, debug, info, warn, error, fatal, panic, disabled)"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"log",
|
||||
"nocolor"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "no ANSI colors in non-JSON output"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"log",
|
||||
"time"
|
||||
],
|
||||
"type": "string",
|
||||
"defaultValue": "unix",
|
||||
"description": "time format used in logs (unix, unixms, unixmicro)"
|
||||
}
|
||||
]
|
|
@ -1,96 +0,0 @@
|
|||
--capture.audio.codec string audio codec to be used (default "opus")
|
||||
--capture.audio.device string pulseaudio device to capture (default "audio_output.monitor")
|
||||
--capture.audio.pipeline string gstreamer pipeline used for audio streaming
|
||||
--capture.broadcast.audio_bitrate int broadcast audio bitrate in KB/s (default 128)
|
||||
--capture.broadcast.autostart automatically start broadcasting when neko starts and broadcast_url is set (default true)
|
||||
--capture.broadcast.pipeline string gstreamer pipeline used for broadcasting
|
||||
--capture.broadcast.preset string broadcast speed preset for h264 encoding (default "veryfast")
|
||||
--capture.broadcast.url string initial URL for broadcasting, setting this value will automatically start broadcasting
|
||||
--capture.broadcast.video_bitrate int broadcast video bitrate in KB/s (default 4096)
|
||||
--capture.microphone.device string pulseaudio device used for microphone (default "audio_input")
|
||||
--capture.microphone.enabled enable microphone stream (default true)
|
||||
--capture.screencast.enabled enable screencast
|
||||
--capture.screencast.pipeline string gstreamer pipeline used for screencasting
|
||||
--capture.screencast.quality string screencast JPEG quality (default "60")
|
||||
--capture.screencast.rate string screencast frame rate (default "10/1")
|
||||
--capture.video.codec string video codec to be used (default "vp8")
|
||||
--capture.video.display string X display to capture
|
||||
--capture.video.ids strings ordered list of video ids
|
||||
--capture.video.pipelines string pipelines config in JSON used for video streaming (default "[]")
|
||||
--capture.webcam.device string v4l2sink device used for webcam (default "/dev/video0")
|
||||
--capture.webcam.enabled enable webcam stream
|
||||
--capture.webcam.height int webcam stream height (default 720)
|
||||
--capture.webcam.width int webcam stream width (default 1280)
|
||||
--desktop.display string X display to use for desktop sharing
|
||||
--desktop.file_chooser_dialog whether to handle file chooser dialog externally
|
||||
--desktop.input.enabled whether custom xf86 input driver should be used to handle touchscreen (default true)
|
||||
--desktop.input.socket string socket path for custom xf86 input driver connection (default "/tmp/xf86-input-neko.sock")
|
||||
--desktop.screen string default screen size and framerate (default "1280x720@30")
|
||||
--desktop.unminimize automatically unminimize window when it is minimized (default true)
|
||||
--desktop.upload_drop whether drop upload is enabled (default true)
|
||||
--member.file.hash member file provider: whether to hash passwords using sha256 (recommended) (default true)
|
||||
--member.file.path string member file provider: storage path
|
||||
--member.multiuser.admin_password string member multiuser provider: admin password (default "admin")
|
||||
--member.multiuser.admin_profile string member multiuser provider: admin profile in JSON format (default "{}")
|
||||
--member.multiuser.user_password string member multiuser provider: user password (default "neko")
|
||||
--member.multiuser.user_profile string member multiuser provider: user profile in JSON format (default "{}")
|
||||
--member.object.users string member object provider: users in JSON format (default "[]")
|
||||
--member.provider string choose member provider (default "multiuser")
|
||||
--plugins.dir string path to neko plugins to load (default "./bin/plugins")
|
||||
--plugins.enabled load plugins in runtime
|
||||
--plugins.required if true, neko will exit if there is an error when loading a plugin
|
||||
--server.bind string address/port/socket to serve neko (default "127.0.0.1:8080")
|
||||
--server.cert string path to the SSL cert used to secure the neko server
|
||||
--server.cors strings list of allowed origins for CORS, if empty CORS is disabled, if '*' is present all origins are allowed
|
||||
--server.key string path to the SSL key used to secure the neko server
|
||||
--server.metrics enable prometheus metrics available at /metrics (default true)
|
||||
--server.path_prefix string path prefix for HTTP requests (default "/")
|
||||
--server.pprof enable pprof endpoint available at /debug/pprof
|
||||
--server.proxy trust reverse proxy headers
|
||||
--server.static string path to neko client files to serve
|
||||
--session.api_token string API token for interacting with external services
|
||||
--session.control_protection users can gain control only if at least one admin is in the room
|
||||
--session.cookie.domain string domain of the cookie
|
||||
--session.cookie.enabled whether cookies authentication should be enabled (default true)
|
||||
--session.cookie.expiration duration expiration of the cookie (default 24h0m0s)
|
||||
--session.cookie.http_only use http only cookies (default true)
|
||||
--session.cookie.name string name of the cookie that holds token (default "NEKO_SESSION")
|
||||
--session.cookie.path string path of the cookie
|
||||
--session.cookie.secure use secure cookies (default true)
|
||||
--session.file string if sessions should be stored in a file, otherwise they will be stored only in memory
|
||||
--session.heartbeat_interval int interval in seconds for sending heartbeat messages (default 120)
|
||||
--session.implicit_hosting allow implicit control switching (default true)
|
||||
--session.inactive_cursors show inactive cursors on the screen
|
||||
--session.locked_controls whether controls should be locked for users initially
|
||||
--session.locked_logins whether logins should be locked for users initially
|
||||
--session.merciful_reconnect allow reconnecting to websocket even if previous connection was not closed (default true)
|
||||
--session.private_mode whether private mode should be enabled initially
|
||||
--webrtc.epr string limits the pool of ephemeral ports that ICE UDP connections can allocate from
|
||||
--webrtc.estimator.debug enables debug logging for the bandwidth estimator
|
||||
--webrtc.estimator.diff_threshold float how bigger the difference between estimated and stream bitrate must be to trigger upgrade/downgrade (default 0.15)
|
||||
--webrtc.estimator.downgrade_backoff duration how long to wait before downgrading again after previous downgrade (default 10s)
|
||||
--webrtc.estimator.enabled enables the bandwidth estimator
|
||||
--webrtc.estimator.initial_bitrate int initial bitrate for the bandwidth estimator (default 1000000)
|
||||
--webrtc.estimator.passive passive estimator mode, when it does not switch pipelines, only estimates
|
||||
--webrtc.estimator.read_interval duration how often to read and process bandwidth estimation reports (default 2s)
|
||||
--webrtc.estimator.stable_duration duration how long to wait for stable connection (upward or neutral trend) before upgrading (default 12s)
|
||||
--webrtc.estimator.stalled_duration duration how long to wait for stalled bandwidth estimation before downgrading (default 24s)
|
||||
--webrtc.estimator.unstable_duration duration how long to wait for stalled connection (neutral trend with low bandwidth) before downgrading (default 6s)
|
||||
--webrtc.estimator.upgrade_backoff duration how long to wait before upgrading again after previous upgrade (default 5s)
|
||||
--webrtc.icelite configures whether or not the ICE agent should be a lite agent
|
||||
--webrtc.iceservers.backend urls Backend only STUN and TURN servers in JSON format with urls, `username` and `credential` keys (default "[]")
|
||||
--webrtc.iceservers.frontend urls Frontend only STUN and TURN servers in JSON format with urls, `username` and `credential` keys (default "[]")
|
||||
--webrtc.icetrickle configures whether cadidates should be sent asynchronously using Trickle ICE (default true)
|
||||
--webrtc.ip_retrieval_url string URL address used for retrieval of the external IP address (default "https://checkip.amazonaws.com")
|
||||
--webrtc.nat1to1 strings sets a list of external IP addresses of 1:1 (D)NAT and a candidate type for which the external IP address is used
|
||||
--webrtc.tcpmux int single TCP mux port for all peers
|
||||
--webrtc.udpmux int single UDP mux port for all peers, replaces EPR
|
||||
|
||||
Global Flags:
|
||||
-c, --config string configuration file path
|
||||
-d, --debug enable debug mode
|
||||
--log.dir string logging directory to store logs
|
||||
--log.json logs in JSON format
|
||||
--log.level string set log level (trace, debug, info, warn, error, fatal, panic, disabled) (default "info")
|
||||
--log.nocolor no ANSI colors in non-JSON output
|
||||
--log.time string time format used in logs (unix, unixms, unixmicro) (default "unix")
|
|
@ -1,70 +0,0 @@
|
|||
---
|
||||
sidebar_position: 5
|
||||
description: Configuration related to the Neko plugins.
|
||||
---
|
||||
|
||||
# Plugins Configuration
|
||||
|
||||
Neko allows you to extend its functionality by using [plugins](https://pkg.go.dev/plugin). Go plugins come with a lot of benefits as well as some limitations. The main advantage is that you can extend the functionality of the application without recompiling the main application. But the main limitation is that you need to use the same Go version and all dependencies with the same version as the main application.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
plugins:
|
||||
enabled: true
|
||||
required: true
|
||||
dir: "./bin/plugins"
|
||||
```
|
||||
|
||||
- `enabled` enables the plugin support. If set to `false`, the plugins are not loaded.
|
||||
- `required` makes the plugin loading mandatory, meaning that if a plugin fails to load, the application will not start.
|
||||
- `dir` refers to the directory where the plugins are stored.
|
||||
|
||||
:::danger
|
||||
External plugins are experimental and may not work as expected. They will be replaced with [hashicorp/go-plugin](https://github.com/hashicorp/go-plugin) in the future.
|
||||
:::
|
||||
|
||||
There exist a few pre-loaded internal plugins that are shipped with Neko:
|
||||
|
||||
## Chat Plugin
|
||||
|
||||
The chat plugin is a simple pre-loaded internal plugin that allows you to chat with other users in the same session. The chat messages are sent to the server and then broadcasted to all users in the same session.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
chat:
|
||||
enabled: true
|
||||
```
|
||||
|
||||
The chat plugin extends user profile and room settings by adding the following fields:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
chat.can_send: true
|
||||
chat.can_receive: true
|
||||
```
|
||||
|
||||
- `chat.can_send` in the room settings context controls whether the chat messages can be sent by any user in the room, and in the user's profile context controls whether the user can send chat messages.
|
||||
- `chat.can_receive` in the room settings context controls whether the chat messages can be received by any user in the room, and in the user's profile context controls whether the user can receive chat messages.
|
||||
|
||||
## File Transfer Plugin
|
||||
|
||||
The file transfer plugin is a simple pre-loaded internal plugin that allows you to transfer files between the client and the server. The files are uploaded to the server and then downloaded by the client.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
filetransfer:
|
||||
enabled: true
|
||||
dir: "./uploads"
|
||||
refresh_interval: 30s
|
||||
```
|
||||
|
||||
- `enabled` enables the file transfer support. If set to `false`, the file transfer is disabled.
|
||||
- `dir` refers to the directory where the files are stored.
|
||||
- `refresh_interval` refers to the interval at which the file list is refreshed.
|
||||
|
||||
The file transfer plugin extends user profile and room settings by adding the following fields:
|
||||
|
||||
```yaml
|
||||
plugins:
|
||||
filetransfer.enabled: true
|
||||
```
|
||||
|
||||
- `filetransfer.enabled` in the room settings context controls whether the file transfer is enabled for any user in the room, and in the user's profile context controls whether the user can transfer files.
|
||||
|
|
@ -1,287 +0,0 @@
|
|||
---
|
||||
sidebar_position: 4
|
||||
description: Configuration related to the WebRTC and Networking in Neko.
|
||||
---
|
||||
|
||||
# WebRTC Configuration
|
||||
|
||||
This page describes how to configure WebRTC settings inside neko.
|
||||
|
||||
Neko uses WebRTC with the [Pion](https://github.com/pion/webrtc) library to establish a peer-to-peer connection between the client and the server. This connection is used to stream audio, video, and data bidirectionally between the client and the server.
|
||||
|
||||
## ICE Setup
|
||||
|
||||
ICE, which stands for Interactive Connectivity Establishment, is a protocol used to find the best path to connect peers, such as a client and a server. It helps discover the public IP addresses and ports of both parties to establish a direct connection. ICE candidates, which contain this information, are exchanged through a signaling server to facilitate the connection process.
|
||||
|
||||
### ICE Trickle
|
||||
|
||||
ICE Trickle is a feature that allows ICE candidates to be sent as they are discovered, rather than waiting for all candidates to be discovered before sending them. It means that the ICE connection can be established faster as the server can start connecting to the client as soon as it has a few ICE candidates and doesn't have to wait for all of them to be discovered.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
webrtc:
|
||||
icetrickle: false
|
||||
```
|
||||
|
||||
### ICE Lite
|
||||
|
||||
ICE Lite is a minimal implementation of the ICE protocol intended for servers running on a public IP address. It is not enabled by default to allow more complex ICE configurations out of the box.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
webrtc:
|
||||
icelite: false
|
||||
```
|
||||
|
||||
:::info
|
||||
When using ICE Servers, ICE Lite must be disabled.
|
||||
:::
|
||||
|
||||
### ICE Servers
|
||||
|
||||
ICE servers are used to establish a connection between the client and the server. There are two types of ICE servers:
|
||||
|
||||
- [STUN](https://en.wikipedia.org/wiki/STUN): A STUN server is used to discover the public IP address of the client. This is used to establish a direct connection between the client and the server.
|
||||
- [TURN](https://en.wikipedia.org/wiki/Traversal_Using_Relays_around_NAT): A TURN server is used to relay data between the client and the server if a direct connection cannot be established.
|
||||
|
||||
The configuration of a single [ICE server](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection#iceservers) is defined by the following fields:
|
||||
|
||||
| Field | Description | Type |
|
||||
|----------------------------|-------------|------|
|
||||
| `urls` | List of URLs of the ICE server, if the same server is available on multiple URLs with the same credentials, they can be listed here. | `string[]` |
|
||||
| `username` | Username used to authenticate with the ICE server, if the server requires authentication. | `string` |
|
||||
| `credential` | Credential used to authenticate with the ICE server, if the server requires authentication. | `string` |
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="yaml" label="YAML" default>
|
||||
|
||||
```yaml title="Example of multiple ICE servers in YAML"
|
||||
- urls: "turn:<MY-COTURN-SERVER>:3478"
|
||||
username: "neko"
|
||||
credential: "neko"
|
||||
- urls: "stun:stun.l.google.com:19302"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="json" label="JSON">
|
||||
|
||||
```json title="Example of multiple ICE servers in JSON"
|
||||
[
|
||||
{
|
||||
"urls": "turn:<MY-COTURN-SERVER>:3478",
|
||||
"username": "neko",
|
||||
"credential": "neko"
|
||||
},
|
||||
{
|
||||
"urls": "stun:stun.l.google.com:19302"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
:::tip
|
||||
You can specify the ICE servers as a JSON string in the `docker-compose.yaml` file using the `NEKO_WEBRTC_ICESERVERS_FRONTEND` and `NEKO_WEBRTC_ICESERVERS_BACKEND` environment variables.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
NEKO_WEBRTC_ICESERVERS_FRONTEND: |
|
||||
[{
|
||||
"urls": [ "turn:<MY-COTURN-SERVER>:3478" ],
|
||||
"username": "neko",
|
||||
"credential": "neko"
|
||||
},{
|
||||
"urls": [ "stun:stun.nextcloud.com:3478" ]
|
||||
}]
|
||||
```
|
||||
:::
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
The ICE servers are divided into two groups:
|
||||
|
||||
- `frontend`: ICE servers that are sent to the client and used to establish a connection between the client and the server.
|
||||
- `backend`: ICE servers that are used by the server to gather ICE candidates. They might contain private IP addresses or other sensitive information that should not be sent to the client.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
webrtc:
|
||||
iceservers:
|
||||
frontend:
|
||||
# List of ICE Server configurations as described above
|
||||
- urls: "stun:stun.l.google.com:19302"
|
||||
backend:
|
||||
# List of ICE Server configurations as described above
|
||||
- urls: "stun:stun.l.google.com:19302"
|
||||
```
|
||||
|
||||
<details>
|
||||
<summary>Example with Coturn server in Docker Compose</summary>
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
services:
|
||||
coturn:
|
||||
image: 'coturn/coturn:latest'
|
||||
network_mode: "host"
|
||||
command: |
|
||||
-n
|
||||
--realm=localhost
|
||||
--fingerprint
|
||||
--listening-ip=0.0.0.0
|
||||
--external-ip=<MY-COTURN-SERVER>
|
||||
--listening-port=3478
|
||||
--min-port=49160
|
||||
--max-port=49200
|
||||
--log-file=stdout
|
||||
--user=neko:neko
|
||||
--lt-cred-mech
|
||||
```
|
||||
|
||||
Replace `<MY-COTURN-SERVER>` with your LAN or Public IP address, and allow ports `49160-49200/udp` and `3478/tcp`. The `--user` flag is used to specify the username and password for the TURN server. The `--lt-cred-mech` flag is used to enable the long-term credentials mechanism for authentication. More information about the Coturn server can be found [here](https://github.com/coturn/coturn).
|
||||
|
||||
</details>
|
||||
|
||||
## Network Setup
|
||||
|
||||
Since WebRTC is a peer-to-peer protocol that requires a direct connection between the client and the server. This can be achieved by:
|
||||
|
||||
- Using a public IP address for the server (or at least reachable from the client if deployed on a private network).
|
||||
- Using a [TURN server](#ice-servers) to relay data between the client and the server if a direct connection cannot be established.
|
||||
|
||||
All specified ports along with the server's IP address will be sent to the client in ICE candidates to establish a connection. Therefore, it is important to ensure that the specified ports are open on the server's firewall, are not remapped to different ports, and are reachable from the client.
|
||||
|
||||
:::danger Remember
|
||||
WebRTC does not use the HTTP protocol, therefore it is not possible to use nginx or other reverse proxies to forward the WebRTC traffic. If you only have exposed port `443` on your server, you must expose as well the WebRTC ports or use a TURN server.
|
||||
:::
|
||||
|
||||
There exist two types of connections:
|
||||
|
||||
- [Ephemeral UDP port range](#ephemeral-udp-port-range): The range of UDP ports that the server uses to establish a connection with the client. Every time a new connection is established, a new port from this range is used. This range should be open on the server's firewall.
|
||||
- [UDP/TCP multiplexing](#udptcp-multiplexing): The server can use a single port for multiple connections. This port should be open on the server's firewall.
|
||||
|
||||
### Ephemeral UDP port range
|
||||
|
||||
The ephemeral UDP port range can be configured using the following configuration:
|
||||
|
||||
```yaml title="config.yaml"
|
||||
webrtc:
|
||||
epr: "59000-59100"
|
||||
```
|
||||
|
||||
The range `59000-59100` contains 101 ports, which should be open on the server's firewall. The server uses these ports to establish a connection with the client. You can specify a different range of ports if needed, with fewer or more ports, depending on the number of simultaneous connections you expect.
|
||||
|
||||
:::tip
|
||||
You can specify the ephemeral UDP port range as an environment variable in the `docker-compose.yaml` file using the `NEKO_WEBRTC_EPR` environment variable. When using docker, make sure to expose the ports in the `docker-compose.yaml`.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
environment:
|
||||
NEKO_WEBRTC_EPR: "59000-59100"
|
||||
ports:
|
||||
- "59000-59100:59000-59100/udp"
|
||||
```
|
||||
|
||||
It is important to expose the same ports to the host machine, without any remapping e.g. `49000-49100:59000-59100/udp` instead of `59000-59100:59000-59100/udp`.
|
||||
:::
|
||||
|
||||
### UDP/TCP multiplexing
|
||||
|
||||
The UDP/TCP multiplexing port can be configured using the following configuration:
|
||||
|
||||
```yaml title="config.yaml"
|
||||
webrtc:
|
||||
udpmux: 59000
|
||||
tcpmux: 59000
|
||||
```
|
||||
|
||||
The server uses only port `59000` for both UDP and TCP connections. This port should be open on the server's firewall. You can specify a different port if needed, or specify only one of the two protocols. UDP is generally better for latency, but some networks block UDP so it is good to have TCP available as a fallback.
|
||||
|
||||
:::tip
|
||||
You can specify the UDP/TCP multiplexing port as an environment variable in the `docker-compose.yaml` file using the `NEKO_WEBRTC_TCPMUX` and `NEKO_WEBRTC_UDPMUX` environment variables. When using docker, make sure to expose the ports in the `docker-compose.yaml`.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
environment:
|
||||
NEKO_WEBRTC_UDPMUX: "59000"
|
||||
NEKO_WEBRTC_TCPMUX: "59000"
|
||||
ports:
|
||||
- "59000:59000/udp"
|
||||
- "59000:59000/tcp"
|
||||
```
|
||||
|
||||
It is important to expose the same ports to the host machine, without any remapping e.g. `49000:59000/udp` instead of `59000:59000/udp`.
|
||||
:::
|
||||
|
||||
### Server IP Address
|
||||
|
||||
The server IP address is sent to the client in ICE candidates so that the client can establish a connection with the server. By default, the server IP address is automatically resolved by the server to the public IP address of the server. If the server is behind a NAT, you want to specify a different IP address or use neko only in a local network, you can specify the server IP address manually.
|
||||
|
||||
#### NAT 1-to-1
|
||||
|
||||
```yaml title="config.yaml"
|
||||
webrtc:
|
||||
nat1to1:
|
||||
# IPv4 address of the server
|
||||
- 10.10.0.5
|
||||
# IPv6 address of the server
|
||||
- 2001:db8:85a3::8a2e:370:7334
|
||||
```
|
||||
|
||||
Currently, only one IPv4 and one IPv6 address can be specified. Therefore if you want to access your instance from both local and public networks, your router must support [NAT loopback (hairpinning)](https://en.wikipedia.org/wiki/Network_address_translation#NAT_hairpinning).
|
||||
|
||||
:::tip
|
||||
You can specify the server IP address as an environment variable in the `docker-compose.yaml` file using the `NEKO_WEBRTC_NAT1TO1` environment variable.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
environment:
|
||||
NEKO_WEBRTC_NAT1TO1: "10.10.0.5"
|
||||
```
|
||||
|
||||
If you want to specify also an IPv6 address, use whitespace to separate the addresses.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
environment:
|
||||
NEKO_WEBRTC_NAT1TO1: "10.10.0.5 2001:db8:85a3::8a2e:370:7334"
|
||||
```
|
||||
:::
|
||||
|
||||
#### IP Retrieval URL
|
||||
|
||||
If you do not specify the server IP address, the server will try to resolve the public IP address of the server automatically.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
webrtc:
|
||||
ip_retrieval_url: "https://checkip.amazonaws.com"
|
||||
```
|
||||
The server will send an HTTP GET request to the specified URL to retrieve the public IP address of the server.
|
||||
|
||||
## Bandwidth Estimator
|
||||
|
||||
:::danger
|
||||
The bandwidth estimator is an experimental feature and might not work as expected.
|
||||
:::
|
||||
|
||||
The bandwidth estimator is a feature that allows the server to estimate the available bandwidth between the client and the server. It is used to switch between different video qualities based on the available bandwidth. The bandwidth estimator is disabled by default.
|
||||
|
||||
```yaml title="config.yaml"
|
||||
webrtc:
|
||||
estimator:
|
||||
# Whether to enable the bandwidth estimator
|
||||
enabled: false
|
||||
# Whether the bandwidth estimator is passive - only used for logging and not for actual decisions
|
||||
passive: false
|
||||
# Enable debug logging for the bandwidth estimator (will print the current state and decisions)
|
||||
debug: false
|
||||
# Initial bitrate for the bandwidth estimator to start with (in bps)
|
||||
initial_bitrate: 1000000
|
||||
# How often to read and process bandwidth estimation reports
|
||||
read_interval: "2s"
|
||||
# How long to wait for a stable connection (upward or neutral trend) before upgrading
|
||||
stable_duration: "12s"
|
||||
# How long to wait for a stalled connection (neutral trend with low bandwidth) before downgrading
|
||||
unstable_duration: "6s"
|
||||
# How long to wait for stalled bandwidth estimation before downgrading
|
||||
stalled_duration: "24s"
|
||||
# How long to wait before downgrading again after the previous downgrade
|
||||
downgrade_backoff: "10s"
|
||||
# How long to wait before upgrading again after the previous upgrade
|
||||
upgrade_backoff: "5s"
|
||||
# How much bigger the difference between estimated and stream bitrate must be to trigger a change
|
||||
diff_threshold: 0.15
|
||||
```
|
|
@ -2,7 +2,11 @@
|
|||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Running Neko in Docker
|
||||
# Installation
|
||||
|
||||
The preferred way to install Neko is to use Docker. This method is easy to set up and manage, it contains all the necessary dependencies, and it is isolated from the host system. Other installation methods are out of scope for this documentation.
|
||||
|
||||
## Docker Run
|
||||
|
||||
To start a basic Neko container, use the following command:
|
||||
|
||||
|
@ -19,26 +23,31 @@ docker run -d --rm \
|
|||
|
||||
### Explanation
|
||||
|
||||
- `-d` - Run the container in the background.
|
||||
- `--rm` - Automatically remove the container when it exits.
|
||||
- `-d --rm` - Run the container in the background and automatically remove the container when it exits.
|
||||
- `-p 8080:8080` - Map the container's port `8080` to the host's port `8080`.
|
||||
- `-p 56000-56100:56000-56100/udp` - Map the container's UDP ports `56000-56100` to the host's ports `56000-56100`.
|
||||
- `-e NEKO_WEBRTC_EPR=56000-56100` - Set the WebRTC endpoint range, must match the mapped ports.
|
||||
- See [WebRTC Ephemeral Port Range](/docs/v3/getting-started/configuration/webrtc#ephemeral-udp-port-range) for more information about this setting.
|
||||
- `-e NEKO_WEBRTC_NAT1TO1=127.0.0.1` - Set the NAT1TO1 IP address.
|
||||
- `-e NEKO_WEBRTC_EPR=56000-56100` - Set the WebRTC endpoint range, this value must match the mapped ports above.
|
||||
- See [WebRTC Ephemeral Port Range](/docs/v3/reference/configuration/webrtc#ephemeral-udp-port-range) for more information about this setting.
|
||||
- There is an alternative to use only a single port, see [WebRTC UDP/TCP multiplexing](/docs/v3/reference/configuration/webrtc#udp-tcp-multiplexing).
|
||||
- `-e NEKO_WEBRTC_NAT1TO1=127.0.0.1` - Set the address where the WebRTC client should connect to.
|
||||
- To test only on the local computer, use `127.0.0.1`.
|
||||
- To use it in a private network, use the host's IP address (e.g., `192.168.1.5`).
|
||||
- To use it in a public network, you need to correctly set up port forwarding on your router and remove this env variable.
|
||||
- See [WebRTC Server IP Address](/docs/v3/getting-started/configuration/webrtc#server-ip-address) for more information about this setting.
|
||||
- See [WebRTC Server IP Address](/docs/v3/reference/configuration/webrtc#server-ip-address) for more information about this setting.
|
||||
- `-e NEKO_MEMBER_MULTIUSER_USER_PASSWORD=neko` - Set the password for the user account.
|
||||
- `-e NEKO_MEMBER_MULTIUSER_ADMIN_PASSWORD=admin` - Set the password for the admin account.
|
||||
- See [Multiuser Configuration](/docs/v3/getting-started/configuration/authentication#multi-user-provider) for more information about this setting.
|
||||
- `ghcr.io/m1k1o/neko/firefox:latest` - The Neko Docker image to use.
|
||||
- See [Available Docker Images](/docs/v3/getting-started/docker-images) for more information about the available images.
|
||||
- See [Multiuser Configuration](/docs/v3/reference/configuration/authentication#multi-user-provider) for more information about this setting.
|
||||
- There are other authentication providers available, see [Authentication Providers](/docs/v3/reference/configuration/authentication#member-providers).
|
||||
- `ghcr.io/m1k1o/neko/firefox:latest` - The Docker image to use.
|
||||
- See available [Docker Images](/docs/v3/getting-started/installation/docker-images).
|
||||
|
||||
Now, open your browser and go to: `http://localhost:8080`. You should see the Neko interface.
|
||||
|
||||
## Using Docker Compose
|
||||
### Further Configuration
|
||||
|
||||
You can configure Neko by setting environment variables or configuration file. See the [Configuration Reference](/docs/v3/reference/configuration) for more information.
|
||||
|
||||
## Docker Compose
|
||||
|
||||
You can also use Docker Compose to run Neko. It is preferred to use Docker Compose for running Neko in production because you can easily manage the container, update it, and configure it.
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"position": 3,
|
||||
"label": "Installation",
|
||||
"collapsed": false
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
---
|
||||
sidebar_position: 4
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# Available Docker Images
|
||||
# Docker Images
|
||||
|
||||
Neko as a standalone streaming server is available as a Docker image. But that is rarely interesting for general use. The real power of Neko is in its ability to accommodate custom applications in the virtual desktop environment. This is where the various flavors of Neko Docker images come in.
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
sidebar_position: 7
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Examples
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
sidebar_position: 6
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# Troubleshooting
|
||||
|
@ -155,7 +155,7 @@ Example for pfsense with truecharts docker container:
|
|||
- Test externally to confirm it works.
|
||||
- Internally you have to access it using `<your-public-ip>:port`
|
||||
|
||||
If your router does not support NAT Loopback (NAT Hairpinning), you can use turn servers to overcome this issue. See [more details here](/docs/v3/getting-started/configuration/webrtc#ice-servers) on how to set up a local coturn instance.
|
||||
If your router does not support NAT Loopback (NAT Hairpinning), you can use turn servers to overcome this issue. See [more details here](/docs/v3/reference/configuration/webrtc#ice-servers) on how to set up a local coturn instance.
|
||||
|
||||
### Neko works locally, but not externally
|
||||
|
||||
|
@ -163,16 +163,24 @@ Make sure that you are exposing your ports correctly.
|
|||
|
||||
If you put a local IP as `NEKO_WEBRTC_NAT1TO1`, external clients try to connect to that IP. But it is unreachable for them because it is your local IP. You must use your public IP address with port forwarding.
|
||||
|
||||
## Debug mode
|
||||
## Frequently Encountered Errors
|
||||
|
||||
To see verbose information from the n.eko server, you can enable debug mode using `NEKO_DEBUG`.
|
||||
### Getting a black screen with a cursor, but no browser for Chromium-based browsers
|
||||
|
||||
Check if you did not forget to add `cap_add` to your `docker-compose.yaml` file. Make sure that the `shm_size` is set to `2gb` or higher.
|
||||
|
||||
```yaml title="docker-compose.yaml"
|
||||
services:
|
||||
neko:
|
||||
image: "ghcr.io/m1k1o/neko/firefox:latest"
|
||||
image: "ghcr.io/m1k1o/neko/chromium:latest"
|
||||
# highlight-start
|
||||
cap_add:
|
||||
- SYS_ADMIN
|
||||
# highlight-end
|
||||
restart: "unless-stopped"
|
||||
# highlight-start
|
||||
shm_size: "2gb"
|
||||
# highlight-end
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "52000-52100:52000-52100/udp"
|
||||
|
@ -181,15 +189,8 @@ services:
|
|||
NEKO_MEMBER_MULTIUSER_USER_PASSWORD: neko
|
||||
NEKO_MEMBER_MULTIUSER_ADMIN_PASSWORD: admin
|
||||
NEKO_WEBRTC_EPR: 52000-52100
|
||||
# highlight-start
|
||||
NEKO_DEBUG: 1
|
||||
# highlight-end
|
||||
```
|
||||
|
||||
Ensure that you have enabled debug mode in the JavaScript console too, in order to see verbose information from the client.
|
||||
|
||||
## Frequently Encountered Errors
|
||||
|
||||
### Common server errors
|
||||
|
||||
```
|
||||
|
@ -225,10 +226,10 @@ Check if your TCP port is exposed correctly and your reverse proxy is correctly
|
|||
---
|
||||
|
||||
```
|
||||
Getting a black screen with a cursor, but no browser.
|
||||
NotAllowedError: play() failed because the user didn't interact with the document first
|
||||
```
|
||||
|
||||
Most likely you forgot to add `-cap-add=SYS_ADMIN` when using chromium-based browsers.
|
||||
This error occurs when the browser blocks the video from playing because the user has not interacted with the document. You just need to manually click on the play button to start the video.
|
||||
|
||||
### Unrelated server errors
|
||||
|
||||
|
@ -238,6 +239,20 @@ Most likely you forgot to add `-cap-add=SYS_ADMIN` when using chromium-based bro
|
|||
|
||||
This error originates from the browser, that it could not connect to dbus. This does not affect us and can be ignored.
|
||||
|
||||
---
|
||||
|
||||
```
|
||||
I: [pulseaudio] client.c: Created 0 "Native client (UNIX socket client)"
|
||||
I: [pulseaudio] protocol-native.c: Client authenticated anonymously.
|
||||
I: [pulseaudio] source-output.c: Trying to change sample spec
|
||||
I: [pulseaudio] sink.c: Reconfigured successfully
|
||||
I: [pulseaudio] source.c: Reconfigured successfully
|
||||
I: [pulseaudio] client.c: Freed 0 "neko"
|
||||
I: [pulseaudio] protocol-native.c: Connection died.
|
||||
```
|
||||
|
||||
These are just logs from pulseaudio. Unless you have audio issues, you can ignore them.
|
||||
|
||||
### Broadcast pipeline not working with some ingest servers
|
||||
|
||||
See [related issue](https://github.com/m1k1o/neko/issues/276).
|
||||
|
|
|
@ -1,228 +0,0 @@
|
|||
---
|
||||
sidebar_position: 8
|
||||
---
|
||||
|
||||
# V2 Migration Guide
|
||||
|
||||
Currently, Neko is in compatibility mode, meaning that as soon as a single V2 configuration option is set, the legacy mode is enabled. This approach allows for a smooth transition from V2 to V3, where it does not expose the V2 API for new users but still allows existing users who use the old configuration to continue using it as before.
|
||||
|
||||
The legacy mode can be explicitly enabled or disabled by setting the `NEKO_LEGACY` environment variable to `true` or `false`.
|
||||
|
||||
:::tip
|
||||
You can migrate to a new configuration even if you are using a V2 client. Just make sure to set the `NEKO_LEGACY` environment variable to `true`.
|
||||
:::
|
||||
|
||||
:::info Built-in Client
|
||||
When using Neko in a container with a built-in client, the client will always be compatible with the server regardless of what configuration is used.
|
||||
:::
|
||||
|
||||
## Configuration
|
||||
|
||||
V3 is compatible with V2 configuration options when legacy support is enabled. You should be able to run V3 with the V2 configuration without any issues.
|
||||
|
||||
The configuration in Neko V3 has been structured differently compared to V2. The V3 configuration is more modular and allows for more flexibility. The V3 configuration is split into multiple sections, each section is responsible for a specific part of the application. This allows for better organization and easier management of the configuration.
|
||||
|
||||
In order to migrate from V2 to V3, you need to update the configuration to the new format. The following table shows the mapping between the V2 and V3 configuration options.
|
||||
|
||||
| **V2 Configuration** | **V3 Configuration** |
|
||||
|---------------------------------------|-----------------------------------------------------------|
|
||||
| `NEKO_LOGS=true` | `NEKO_LOG_DIR=/var/log/neko`, V3 allows specifying the log directory |
|
||||
| `NEKO_CERT` | `NEKO_SERVER_CERT` |
|
||||
| `NEKO_KEY` | `NEKO_SERVER_KEY` |
|
||||
| `NEKO_BIND` | `NEKO_SERVER_BIND` |
|
||||
| `NEKO_PROXY` | `NEKO_SERVER_PROXY` |
|
||||
| `NEKO_STATIC` | `NEKO_SERVER_STATIC` |
|
||||
| `NEKO_PATH_PREFIX` | `NEKO_SERVER_PATH_PREFIX` |
|
||||
| `NEKO_CORS` | `NEKO_SERVER_CORS` |
|
||||
| `NEKO_LOCKS` | `NEKO_SESSION_LOCKED_CONTROLS` and `NEKO_SESSION_LOCKED_LOGINS`, <br /> V3 allows separate locks for controls and logins |
|
||||
| `NEKO_IMPLICIT_CONTROL` | `NEKO_SESSION_IMPLICIT_HOSTING` |
|
||||
| `NEKO_CONTROL_PROTECTION` | `NEKO_SESSION_CONTROL_PROTECTION` |
|
||||
| `NEKO_HEARTBEAT_INTERVAL` | `NEKO_SESSION_HEARTBEAT_INTERVAL` |
|
||||
|
||||
See the V3 [configuration options](/docs/v3/getting-started/configuration).
|
||||
|
||||
### WebRTC Video
|
||||
|
||||
See the V3 configuration options for the [WebRTC Video](/docs/v3/getting-started/configuration/capture#webrtc-video).
|
||||
|
||||
| **V2 Configuration** | **V3 Configuration** |
|
||||
|---------------------------------------|-----------------------------------------------------------|
|
||||
| `NEKO_DISPLAY` | `NEKO_CAPTURE_VIDEO_DISPLAY` and `NEKO_DESKTOP_DISPLAY`, <br /> consider using `DISPLAY` env variable if both should be the same |
|
||||
| `NEKO_VIDEO_CODEC` | `NEKO_CAPTURE_VIDEO_CODEC` |
|
||||
| `NEKO_AV1=true` *deprecated* | `NEKO_CAPTURE_VIDEO_CODEC=av1` |
|
||||
| `NEKO_H264=true` *deprecated* | `NEKO_CAPTURE_VIDEO_CODEC=h264` |
|
||||
| `NEKO_VP8=true` *deprecated* | `NEKO_CAPTURE_VIDEO_CODEC=vp8` |
|
||||
| `NEKO_VP9=true` *deprecated* | `NEKO_CAPTURE_VIDEO_CODEC=vp9` |
|
||||
| `NEKO_VIDEO` | `NEKO_CAPTURE_VIDEO_PIPELINE`, V3 allows multiple video pipelines |
|
||||
| `NEKO_VIDEO_BITRATE` | **removed**, use custom pipeline instead |
|
||||
| `NEKO_HWENC` | **removed**, use custom pipeline instead |
|
||||
| `NEKO_MAX_FPS` | **removed**, use custom pipeline instead |
|
||||
|
||||
|
||||
:::warning Limitation
|
||||
V2 did not have client-side cursor support, the cursor was always part of the video stream. In V3, the cursor is sent separately from the video stream. Therefore, when using legacy configuration, there will be two video streams created, one with the cursor (for V2 clients) and one without the cursor (for V3 clients). Please consider using new configuration options if this is not the desired behavior.
|
||||
:::
|
||||
|
||||
### WebRTC Audio
|
||||
|
||||
See the V3 configuration options for the [WebRTC Audio](/docs/v3/getting-started/configuration/capture#webrtc-audio).
|
||||
|
||||
| **V2 Configuration** | **V3 Configuration** |
|
||||
|---------------------------------------|-----------------------------------------------------------|
|
||||
| `NEKO_DEVICE` | `NEKO_CAPTURE_AUDIO_DEVICE` |
|
||||
| `NEKO_AUDIO_CODEC` | `NEKO_CAPTURE_AUDIO_CODEC` |
|
||||
| `NEKO_G722=true` *deprecated* | `NEKO_CAPTURE_AUDIO_CODEC=g722` |
|
||||
| `NEKO_OPUS=true` *deprecated* | `NEKO_CAPTURE_AUDIO_CODEC=opus` |
|
||||
| `NEKO_PCMA=true` *deprecated* | `NEKO_CAPTURE_AUDIO_CODEC=pcma` |
|
||||
| `NEKO_PCMU=true` *deprecated* | `NEKO_CAPTURE_AUDIO_CODEC=pcmu` |
|
||||
| `NEKO_AUDIO` | `NEKO_CAPTURE_AUDIO_PIPELINE` |
|
||||
| `NEKO_AUDIO_BITRATE` | **removed**, use custom pipeline instead |
|
||||
|
||||
### Broadcast
|
||||
|
||||
See the V3 configuration options for the [Broadcast](/docs/v3/getting-started/configuration/capture#broadcast).
|
||||
|
||||
| **V2 Configuration** | **V3 Configuration** |
|
||||
|---------------------------------------|-----------------------------------------------------------|
|
||||
| `NEKO_BROADCAST_PIPELINE` | `NEKO_CAPTURE_BROADCAST_PIPELINE` |
|
||||
| `NEKO_BROADCAST_URL` | `NEKO_CAPTURE_BROADCAST_URL` |
|
||||
| `NEKO_BROADCAST_AUTOSTART` | `NEKO_CAPTURE_BROADCAST_AUTOSTART` |
|
||||
|
||||
### Desktop
|
||||
|
||||
See the V3 configuration options for the [Desktop](/docs/v3/getting-started/configuration/desktop).
|
||||
|
||||
| **V2 Configuration** | **V3 Configuration** |
|
||||
|---------------------------------------|-----------------------------------------------------------|
|
||||
| `NEKO_SCREEN` | `NEKO_DESKTOP_SCREEN` |
|
||||
|
||||
### Authentication
|
||||
|
||||
See the V3 configuration options for the [Authentication](/docs/v3/getting-started/configuration/authentication).
|
||||
|
||||
| **V2 Configuration** | **V3 Configuration** |
|
||||
|---------------------------------------|-----------------------------------------------------------|
|
||||
| `NEKO_PASSWORD` | `NEKO_MEMBER_MULTIUSER_USER_PASSWORD` with `NEKO_MEMBER_PROVIDER=multiuser` |
|
||||
| `NEKO_PASSWORD_ADMIN` | `NEKO_MEMBER_MULTIUSER_ADMIN_PASSWORD` with `NEKO_MEMBER_PROVIDER=multiuser` |
|
||||
|
||||
In order for the legacy authentication to work, you need to set [Multi-user](http://localhost:3000/docs/v3/getting-started/configuration/authentication#multi-user-provider).
|
||||
|
||||
:::warning Limitation
|
||||
V2 clients might not be compatible with any other authentication provider than the `multiuser`.
|
||||
:::
|
||||
|
||||
### WebRTC
|
||||
|
||||
See the V3 configuration options for the [WebRTC](/docs/v3/getting-started/configuration/webrtc).
|
||||
|
||||
| **V2 Configuration** | **V3 Configuration** |
|
||||
|---------------------------------------|-----------------------------------------------------------|
|
||||
| `NEKO_NAT1TO1` | `NEKO_WEBRTC_NAT1TO1` |
|
||||
| `NEKO_TCPMUX` | `NEKO_WEBRTC_TCPMUX` |
|
||||
| `NEKO_UDPMUX` | `NEKO_WEBRTC_UDPMUX` |
|
||||
| `NEKO_ICELITE` | `NEKO_WEBRTC_ICELITE` |
|
||||
| `NEKO_ICESERVERS` or `NEKO_ICESERVER` | `NEKO_WEBRTC_ICESERVERS_FRONTEND` and `NEKO_WEBRTC_ICESERVERS_BACKEND`, <br /> V3 allows separate ICE servers for frontend and backend |
|
||||
| `NEKO_IPFETCH` | `NEKO_WEBRTC_IP_RETRIEVAL_URL` |
|
||||
| `NEKO_EPR` | `NEKO_WEBRTC_EPR` |
|
||||
|
||||
### Full V2 Configuration Reference
|
||||
|
||||
Here is a full list of all the configuration options available in Neko V2 that are still available in Neko V3 with legacy support enabled.
|
||||
|
||||
import Configuration from '@site/src/components/Configuration';
|
||||
import configOptions from './help.json';
|
||||
|
||||
<Configuration configOptions={configOptions} />
|
||||
|
||||
See the full [V3 configuration reference](/docs/v3/getting-started/configuration/#full-configuration-reference) for more details.
|
||||
|
||||
## API
|
||||
|
||||
V3 is compatible with the V2 API when legacy support is enabled. There was specifically created a compatibility layer (legacy API) that allows V2 clients to connect to V3. The legacy API is enabled by default, but it can be disabled if needed. In later versions, the legacy API will be removed.
|
||||
|
||||
### Authentication
|
||||
|
||||
In V2 there was only one authentication provider available, as in V3 called the `multiuser` provider. The API knew based on the provided password (as `?pwd=` query string) if the user is an admin or not.
|
||||
|
||||
Since V3 handles authentication differently (see [API documentation](/docs/v3/api/neko-api#authentication)), there has been added `?usr=` query string to the API to specify the username. The password is still provided as `?pwd=` query string. The `?usr=` query string is still optional, if not provided, the API will generate a random username.
|
||||
|
||||
:::warning Limitation
|
||||
For every request in the legacy API, a new user session is created based on the `?usr=&pwd=` query string. The session is destroyed after the API request is completed. So for HTTP API requests, the sessions are short-lived but for WebSocket API requests, the session is kept alive until the WebSocket connection is closed.
|
||||
:::
|
||||
|
||||
Only the `multiuser` provider (or the `noauth` provider) is supported without specifying the `?usr=` query string.
|
||||
|
||||
### WebSocket Messages
|
||||
|
||||
Since WebSocket messages are not user-facing API, there exists no migration guide for them. When the legacy API is enabled, the user connects to the `/ws` endpoint and is handled by the compatibility layer V2 API. The V3 API is available at the `/api/ws` endpoint.
|
||||
|
||||
### WebRTC API
|
||||
|
||||
Since the WebRTC API is not user-facing API, there exists no migration guide for it. It has been changed to Big Endian format (previously Little Endian) to allow easier manipulation on the client side.
|
||||
V2 created a new data channel on the client side, V3 creates a new data channel on the server side. That means, the server just listens for a new data channel from the client and accepts it with the legacy API handler. It overwrites the existing V3 data channel with the legacy one.
|
||||
|
||||
### HTTP API
|
||||
|
||||
The V2 version had a very limited HTTP API, the V3 API is much more powerful and flexible. See the [API documentation](/docs/v3/api/neko-api) for more details.
|
||||
|
||||
#### GET `/health`
|
||||
|
||||
Migrated to the [Health](/docs/v3/api/healthcheck) endpoint for server health checks.
|
||||
|
||||
Returns `200 OK` if the server is running.
|
||||
|
||||
#### GET `/stats`
|
||||
|
||||
Migrated to the [Stats](/docs/v3/api/stats) endpoint for server statistics and the [List Sessions](/docs/v3/api/sessions-get) endpoint for the session list.
|
||||
|
||||
Returns a JSON object with the following structure:
|
||||
|
||||
```json
|
||||
{
|
||||
// How many connections are currently active
|
||||
"connections": 0,
|
||||
// Who is currently having a session (empty if no one)
|
||||
"host": "<session_id>",
|
||||
// List of currently connected users
|
||||
"members": [
|
||||
{
|
||||
"session_id": "<session_id>",
|
||||
"displayname": "Name",
|
||||
"admin": true,
|
||||
"muted": false,
|
||||
}
|
||||
],
|
||||
// List of banned IPs and who banned them as a session_id
|
||||
"banned": {
|
||||
"<ip>": "<session_id>"
|
||||
},
|
||||
// List of locked resources and who locked them as a session_id
|
||||
"locked": {
|
||||
"<resource>": "<session_id>"
|
||||
},
|
||||
// Server uptime
|
||||
"server_started_at": "2021-01-01T00:00:00Z",
|
||||
// When was the last admin or user left the session
|
||||
"last_admin_left_at": "2021-01-01T00:00:00Z",
|
||||
"last_user_left_at": "2021-01-01T00:00:00Z",
|
||||
// Whether the control protection or implicit control is enabled
|
||||
"control_protection": false,
|
||||
"implicit_control": false,
|
||||
}
|
||||
```
|
||||
|
||||
#### GET `/screenshot.jpg`
|
||||
|
||||
Migrated to the [Screenshot](/docs/v3/api/screen-shot-image) endpoint for taking screenshots.
|
||||
|
||||
Returns a screenshot of the desktop as a JPEG image.
|
||||
|
||||
#### GET `/file`
|
||||
|
||||
The whole functionality of file transfer has been moved to a [File Transfer Plugin](/docs/v3/getting-started/configuration/plugins#file-transfer-plugin).
|
||||
|
||||
## Limitations
|
||||
|
||||
In v2, locks and muted users were managed using a simple map that tracked who set the lock and what was locked. In v3, locks are now implemented as setting options and no longer store the `session_id` of the user who applied the lock. As a result, if a client refreshes the page or reconnects, the lock information is lost, and the user who set the lock is displayed as `Somebody`.
|
||||
|
||||
Additionally, when using the legacy API with a v2 client, API calls occur in a different order than expected. The client first retrieves the session list before registering the user, meaning the current `session_id` is not known when the session list is fetched. That means, the current user appears as `Somebody` in the session list.
|
|
@ -1,333 +0,0 @@
|
|||
[
|
||||
{
|
||||
"key": [
|
||||
"legacy"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "true",
|
||||
"description": "enable legacy mode"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"logs"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "save logs to file"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"display"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "XDisplay to capture"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"video_codec"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "video codec to be used"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"av1"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "DEPRECATED: use video_codec"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"h264"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "DEPRECATED: use video_codec"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"vp8"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "DEPRECATED: use video_codec"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"vp9"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "DEPRECATED: use video_codec"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"video"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "video codec parameters to use for streaming"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"video_bitrate"
|
||||
],
|
||||
"type": "int",
|
||||
"description": "video bitrate in kbit/s"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"hwenc"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "use hardware accelerated encoding"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"max_fps"
|
||||
],
|
||||
"type": "int",
|
||||
"description": "maximum fps delivered via WebRTC, 0 is for no maximum"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"device"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "audio device to capture"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"audio_codec"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "audio codec to be used"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"g722"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "DEPRECATED: use audio_codec"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"opus"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "DEPRECATED: use audio_codec"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"pcma"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "DEPRECATED: use audio_codec"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"pcmu"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "DEPRECATED: use audio_codec"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"audio"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "audio codec parameters to use for streaming"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"audio_bitrate"
|
||||
],
|
||||
"type": "int",
|
||||
"description": "audio bitrate in kbit/s"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"broadcast_pipeline"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "custom gst pipeline used for broadcasting, strings {url} {device} {display} will be replaced"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"broadcast_url"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "a default default URL for broadcast streams, can be disabled/changed later by admins in the GUI"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"broadcast_autostart"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "automatically start broadcasting when neko starts and broadcast_url is set"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"screen"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "default screen resolution and framerate"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"password"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "password for connecting to stream"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"password_admin"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "admin password for connecting to stream"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"cert"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "path to the SSL cert used to secure the neko server"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"key"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "path to the SSL key used to secure the neko server"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"bind"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "address/port/socket to serve neko"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"proxy"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "enable reverse proxy mode"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"static"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "path to neko client files to serve"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"path_prefix"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "path prefix for HTTP requests"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"cors"
|
||||
],
|
||||
"type": "strings",
|
||||
"description": "list of allowed origins for CORS"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"locks"
|
||||
],
|
||||
"type": "strings",
|
||||
"description": "resources, that will be locked when starting (control, login)"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"implicit_control"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "if enabled members can gain control implicitly"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"control_protection"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "control protection means, users can gain control only if at least one admin is in the room"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"heartbeat_interval"
|
||||
],
|
||||
"type": "int",
|
||||
"defaultValue": "120",
|
||||
"description": "heartbeat interval in seconds"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"nat1to1"
|
||||
],
|
||||
"type": "strings",
|
||||
"description": "sets a list of external IP addresses of 1:1 (D)NAT and a candidate type for which the external IP "
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"tcpmux"
|
||||
],
|
||||
"type": "int",
|
||||
"description": "single TCP mux port for all peers"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"udpmux"
|
||||
],
|
||||
"type": "int",
|
||||
"description": "single UDP mux port for all peers"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"icelite"
|
||||
],
|
||||
"type": "boolean",
|
||||
"defaultValue": "false",
|
||||
"description": "configures whether or not the ice agent should be a lite agent"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"iceserver"
|
||||
],
|
||||
"type": "strings",
|
||||
"description": "describes a single STUN and TURN server that can be used by the ICEAgent to establish a connection "
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"iceservers"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "describes a single STUN and TURN server that can be used by the ICEAgent to establish a connection "
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"ipfetch"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "automatically fetch IP address from given URL when nat1to1 is not present"
|
||||
},
|
||||
{
|
||||
"key": [
|
||||
"epr"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "limits the pool of ephemeral ports that ICE UDP connections can allocate from"
|
||||
}
|
||||
]
|
|
@ -1,52 +0,0 @@
|
|||
|
||||
--legacy enable legacy mode (default true)
|
||||
--logs save logs to file
|
||||
|
||||
--display string XDisplay to capture
|
||||
--video_codec string video codec to be used
|
||||
--av1 DEPRECATED: use video_codec
|
||||
--h264 DEPRECATED: use video_codec
|
||||
--vp8 DEPRECATED: use video_codec
|
||||
--vp9 DEPRECATED: use video_codec
|
||||
--video string video codec parameters to use for streaming
|
||||
--video_bitrate int video bitrate in kbit/s
|
||||
--hwenc string use hardware accelerated encoding
|
||||
--max_fps int maximum fps delivered via WebRTC, 0 is for no maximum
|
||||
--device string audio device to capture
|
||||
--audio_codec string audio codec to be used
|
||||
--g722 DEPRECATED: use audio_codec
|
||||
--opus DEPRECATED: use audio_codec
|
||||
--pcma DEPRECATED: use audio_codec
|
||||
--pcmu DEPRECATED: use audio_codec
|
||||
--audio string audio codec parameters to use for streaming
|
||||
--audio_bitrate int audio bitrate in kbit/s
|
||||
--broadcast_pipeline string custom gst pipeline used for broadcasting, strings {url} {device} {display} will be replaced
|
||||
--broadcast_url string a default default URL for broadcast streams, can be disabled/changed later by admins in the GUI
|
||||
--broadcast_autostart automatically start broadcasting when neko starts and broadcast_url is set
|
||||
|
||||
--screen string default screen resolution and framerate
|
||||
|
||||
--password string password for connecting to stream
|
||||
--password_admin string admin password for connecting to stream
|
||||
|
||||
--cert string path to the SSL cert used to secure the neko server
|
||||
--key string path to the SSL key used to secure the neko server
|
||||
--bind string address/port/socket to serve neko
|
||||
--proxy enable reverse proxy mode
|
||||
--static string path to neko client files to serve
|
||||
--path_prefix string path prefix for HTTP requests
|
||||
--cors strings list of allowed origins for CORS
|
||||
|
||||
--locks strings resources, that will be locked when starting (control, login)
|
||||
--implicit_control if enabled members can gain control implicitly
|
||||
--control_protection control protection means, users can gain control only if at least one admin is in the room
|
||||
--heartbeat_interval int heartbeat interval in seconds (default 120)
|
||||
|
||||
--nat1to1 strings sets a list of external IP addresses of 1:1 (D)NAT and a candidate type for which the external IP
|
||||
--tcpmux int single TCP mux port for all peers
|
||||
--udpmux int single UDP mux port for all peers
|
||||
--icelite configures whether or not the ice agent should be a lite agent
|
||||
--iceserver strings describes a single STUN and TURN server that can be used by the ICEAgent to establish a connection
|
||||
--iceservers string describes a single STUN and TURN server that can be used by the ICEAgent to establish a connection
|
||||
--ipfetch string automatically fetch IP address from given URL when nat1to1 is not present
|
||||
--epr string limits the pool of ephemeral ports that ICE UDP connections can allocate from
|
Loading…
Add table
Add a link
Reference in a new issue