You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
synctv/README.md

415 lines
13 KiB
Markdown

# SyncTV - Rust Implementation
A production-grade real-time synchronized video watching platform built in Rust.
## Features
- **Real-time Synchronization**: Watch videos together with friends in perfect sync
- **Multi-Provider Support**: Bilibili, Alist, Emby, and direct URLs
- **Live Streaming**: RTMP push/pull with HLS and FLV support
- **Horizontal Scalability**: Kubernetes-ready multi-replica deployment
- **High Performance**: Built with Rust for maximum efficiency
- **Type Safety**: Compile-time guarantees and zero-cost abstractions
## Architecture
- **synctv-core**: Core business logic library
- **synctv-api**: gRPC + HTTP API service
8 months ago
- **synctv-livestream**: Live streaming service (RTMP/HLS/FLV)
- **synctv-cluster**: Cluster coordination library
8 months ago
- **synctv-xiu**: Consolidated streaming library (RTMP/HLS/HTTP-FLV protocols)
## Quick Start
### Prerequisites
- Rust 1.75+ (2021 edition)
- PostgreSQL 14+
- Redis 7+
6 months ago
### 1. Start with Docker Compose
6 months ago
Development build from the local source tree:
7 months ago
```bash
6 months ago
docker compose -f docker-compose.dev.yml up -d
7 months ago
```
5 months ago
This variant builds with the local [Dockerfile](./Dockerfile) and ships fixed working development defaults for JWT and cluster secrets.
7 months ago
6 months ago
Prebuilt image deployment:
7 months ago
```bash
6 months ago
export SYNCTV_JWT_SECRET="your-secure-random-string-at-least-32-chars"
5 months ago
export SYNCTV_SERVER_CLUSTER_SECRET="your-secure-random-cluster-secret"
6 months ago
export SYNCTV_BOOTSTRAP_ROOT_PASSWORD="StrongRootPass12345"
6 months ago
docker compose up -d
```
5 months ago
This variant uses `synctvorg/synctv:v1` from [docker-compose.yml](./docker-compose.yml) and intentionally keeps the environment surface small.
6 months ago
Once the daemon is up, management CLI commands can run inside the container and use the
default Unix socket without extra flags:
```bash
docker compose exec synctv synctv system stats
```
6 months ago
### 2. Manual Environment Variables
6 months ago
```bash
export SYNCTV_DATABASE_URL="postgresql://synctv:synctv@localhost:5432/synctv"
export SYNCTV_REDIS_URL="redis://localhost:6379"
export SYNCTV_JWT_SECRET="your-secure-RANDOM-string-WITH-mixed-CASE-123-and-SPECIAL!@#$%"
5 months ago
export SYNCTV_SERVER_CLUSTER_SECRET="your-secure-random-cluster-secret"
6 months ago
export SYNCTV_BOOTSTRAP_CREATE_ROOT_USER=true
export SYNCTV_BOOTSTRAP_ROOT_PASSWORD="StrongRootPass12345"
6 months ago
export SYNCTV_SERVER_PORT=8080
```
7 months ago
### 3. Validate Configuration (Optional but Recommended)
```bash
# Validate your configuration before deployment
6 months ago
cargo run --bin synctv -- config validate
7 months ago
6 months ago
# Validate a specific config file
cargo run --bin synctv -- config --config /path/to/synctv.yaml validate
7 months ago
```
### 4. Run Database Migrations
```bash
6 months ago
# Run embedded migrations with the same config resolution as the server
cargo run --bin synctv -- db migrate
```
7 months ago
### 5. Start the Server
```bash
8 months ago
# Set JWT secret (required for production, min 32 chars)
export SYNCTV_JWT_SECRET="your-secure-random-string-at-least-32-chars"
6 months ago
export SYNCTV_BOOTSTRAP_ROOT_PASSWORD="StrongRootPass12345"
cargo run --bin synctv -- serve
```
HTTP/REST and public gRPC share a single API port, defaulting to `0.0.0.0:8080`.
The management daemon default endpoint is platform-specific:
6 months ago
- Linux / other Unix: `unix://$XDG_STATE_HOME/synctv/run/synctv.sock` when `XDG_STATE_HOME` is set, otherwise `unix://$HOME/.local/state/synctv/run/synctv.sock`
- macOS: `unix://$HOME/.synctv/run/synctv.sock`
6 months ago
- Windows: `http://127.0.0.1:50052`
6 months ago
Runtime-owned local files can be relocated with `--data-dir`, `SYNCTV_DATA_DIR`, or
top-level config `data_dir`.
`data_dir` applies to runtime-owned local paths:
- default management Unix socket path and relative `management.unix_socket_path`
- relative `logging.file_path`
- relative `livestream.hls_storage_path`
- relative `cache.proxy_slice_file_cache_dir`
`data_dir` does not rebase static input files:
- `*_file` secret references such as `jwt.secret_file`, `management.auth_token_file`,
`oauth2.providers.*.client_secret_file`, or provider credential `_file` fields
- `metrics.tls.cert_path` and `metrics.tls.key_path`
Absolute paths are always used as-is. Relative `data_dir` from config files is resolved
relative to the config file directory; `--data-dir` and `SYNCTV_DATA_DIR` are resolved
relative to the current working directory.
5 months ago
Secret-like settings can also be loaded from environment file variables, for example
`SYNCTV_JWT_SECRET_FILE`, `SYNCTV_MANAGEMENT_AUTH_TOKEN_FILE`,
`SYNCTV_DATABASE_URL_FILE`, and `SYNCTV_BOOTSTRAP_ROOT_PASSWORD_FILE`.
Relative env file paths are resolved from the current working directory.
PostgreSQL and Redis can be configured either by URL or by split fields. For
PostgreSQL, use `database.url` / `SYNCTV_DATABASE_URL` or
`database.host`, `database.port`, `database.username`, `database.password`,
`database.name` with matching `SYNCTV_DATABASE_*` env vars. For Redis, use
`redis.url` / `SYNCTV_REDIS_URL` or `redis.host`, `redis.port`,
`redis.username`, `redis.password`, `redis.database` with matching
`SYNCTV_REDIS_*` env vars. Passwords and URLs support `*_file` config keys and
`*_FILE` env vars.
6 months ago
On platforms without Unix Domain Socket support, `management.transport: unix` is rejected during
configuration validation instead of silently falling back.
When a Unix socket is not available, the CLI can be pointed at an explicit endpoint with
`--endpoint` or `SYNCTV_MANAGEMENT_ENDPOINT`, and the server can be configured to listen on
TCP at `127.0.0.1:50052`. In TCP mode the management listener is always forced to loopback;
there is no configurable management host.
### 6. Remote CLI Operations
All operational CLI commands talk to a running SyncTV server. There is no offline admin mode.
```bash
# List users through the local management daemon endpoint
cargo run --bin synctv -- user list
# Inspect effective runtime settings
cargo run --bin synctv -- settings get server
# Update runtime settings through the management daemon
cargo run --bin synctv -- settings update server \
--set signup_enabled=false \
--set max_rooms_per_user=42
# Inspect cluster/system stats
cargo run --bin synctv -- system stats
8 months ago
6 months ago
# Inspect or manage remote provider instances
cargo run --bin synctv -- provider list
# List playlists inside a room
cargo run --bin synctv -- playlist list --room-id room-123
# Add a direct media URL into a room playlist
cargo run --bin synctv -- media add-url 'https://cdn.example.com/video.mp4' \
--room-id room-123 \
--playlist-id playlist-123
```
6 months ago
The management daemon executes local CLI requests with built-in god-mode privileges. The compose
files and development scripts create a bootstrap administrator automatically; for manual
deployments, set
`SYNCTV_BOOTSTRAP_CREATE_ROOT_USER=true` together with a strong
`SYNCTV_BOOTSTRAP_ROOT_PASSWORD` before first startup.
5 months ago
Remote CLI commands may load SyncTV config files to resolve the management endpoint
and management bearer token. Explicit CLI flags still take precedence. Endpoint
resolution is:
6 months ago
1. `--endpoint`
2. `SYNCTV_MANAGEMENT_ENDPOINT`
5 months ago
3. `management.*` from `--config`, `SYNCTV_CONFIG_PATH`, or an auto-discovered config file
4. platform default Unix socket path
5. default TCP endpoint `http://127.0.0.1:50052`
Management authentication resolution is:
1. `--auth-token`
2. `--auth-token-file`
3. `SYNCTV_MANAGEMENT_AUTH_TOKEN`
4. `SYNCTV_MANAGEMENT_AUTH_TOKEN_FILE`
5. `management.auth_token` or `management.auth_token_file` from config
When `--endpoint` or `SYNCTV_MANAGEMENT_ENDPOINT` is used, config-file auth is
only used if a config source is explicitly selected with `--config` or
`SYNCTV_CONFIG_PATH`. This avoids accidentally sending an auto-discovered local
management token to an unrelated endpoint.
6 months ago
In containerized deployments, `docker compose exec synctv synctv ...` uses the same default
Unix socket path inside the container. Use `--endpoint` only when intentionally targeting a
non-default TCP or Unix socket listener.
## Development
6 months ago
### Docker Compose
```bash
# Local development build with fixed working defaults
docker compose -f docker-compose.dev.yml up -d
# Prebuilt image deployment
docker compose up -d
```
### Run Tests
```bash
5 months ago
cargo nextest run --workspace
```
### Run with Logging
```bash
6 months ago
SYNCTV_LOGGING_LEVEL=debug cargo run --bin synctv -- serve
6 months ago
```
6 months ago
For advanced tracing filters, prefer setting `logging.filter` in `synctv.yaml` or exporting
`SYNCTV_LOGGING_FILTER` only for one-off diagnostics.
### Build Release
```bash
cargo build --release --workspace
```
## API
### gRPC API
5 months ago
By default, public gRPC reflection is disabled. Enable it when you want to explore the API interactively with `grpcurl`:
```bash
5 months ago
export SYNCTV_SERVER_ENABLE_REFLECTION=true
cargo run --bin synctv -- serve
6 months ago
grpcurl -plaintext localhost:8080 list
grpcurl -plaintext localhost:8080 list synctv.client.ClientService
```
5 months ago
If you keep reflection disabled, use the checked-in protobuf definitions instead:
```bash
grpcurl -plaintext \
-import-path synctv-proto/proto \
-proto client.proto \
localhost:8080 \
synctv.client.ClientService/Login
```
### Example: Register User
```bash
grpcurl -plaintext -d '{
"username": "alice",
"email": "alice@example.com",
"password": "securepassword123"
6 months ago
}' localhost:8080 synctv.client.ClientService/Register
```
### Example: Login
```bash
grpcurl -plaintext -d '{
"username": "alice",
"password": "securepassword123"
6 months ago
}' localhost:8080 synctv.client.ClientService/Login
```
## Configuration
Configuration can be provided via:
8 months ago
1. Environment variables (highest priority): `SYNCTV_SECTION_KEY`
6 months ago
2. Config file (`.yaml`, `.yml`, `.json`, `.toml`), searched in platform-aware default locations such as:
6 months ago
`./synctv.yaml`, Linux `$XDG_CONFIG_HOME/synctv/synctv.yaml` or `~/.config/synctv/synctv.yaml`,
6 months ago
macOS `~/.synctv/synctv.yaml`, Linux `/etc/synctv/synctv.yaml`,
6 months ago
`/config/synctv.yaml`
3. Defaults (lowest priority)
6 months ago
`data_dir` can also be set via CLI `--data-dir`, environment `SYNCTV_DATA_DIR`, or
top-level config `data_dir`.
It affects only runtime-owned local paths:
- `management.unix_socket_path`
- `logging.file_path`
- `livestream.hls_storage_path`
- `cache.proxy_slice_file_cache_dir`
It does not affect static config inputs:
- `*_file` secrets remain relative to the config file directory
- `metrics.tls.cert_path` and `metrics.tls.key_path` remain relative to the config file directory
Absolute paths are preserved. Relative runtime-owned paths are resolved against the
effective data directory.
7 months ago
**Comprehensive Configuration File**
6 months ago
A complete example config with documented options is provided in the repository. It includes:
7 months ago
- All server, database, and Redis settings
- WebRTC configuration for audio/video calls
- OAuth2 provider examples (GitHub, Google, OIDC)
- Livestream RTMP/HLS/FLV settings
- Connection limits and security options
- Production vs development guidance
5 months ago
- Hundreds of lines of documented configuration
7 months ago
5 months ago
View the complete file: [`synctv.example.yaml`](./synctv.example.yaml)
7 months ago
**Quick Example** (minimal configuration):
7 months ago
```yaml
6 months ago
data_dir: "/var/lib/synctv"
7 months ago
server:
host: "0.0.0.0"
6 months ago
port: 8080
6 months ago
management:
enabled: true
transport: "unix"
unix_socket_path: "/run/synctv/synctv.sock" # Linux/container example
7 months ago
database:
url: "postgresql://synctv:synctv@localhost:5432/synctv"
7 months ago
max_connections: 100 # Increased for better performance
7 months ago
redis:
url: "redis://localhost:6379"
7 months ago
jwt:
7 months ago
secret: "" # REQUIRED: Set via SYNCTV_JWT_SECRET env var
7 months ago
logging:
level: "info"
7 months ago
format: "pretty" # Use "json" in production
6 months ago
# filter: "info,synctv=debug"
backtrace: false
7 months ago
```
### Configuration Validation
Use the built-in validation tool to catch configuration errors before deployment:
```bash
6 months ago
# Validate synctv.yaml
cargo run --bin synctv -- config validate
7 months ago
# Validate specific file
6 months ago
cargo run --bin synctv -- config --config /path/to/synctv.yaml validate
7 months ago
```
**What gets validated:**
- Syntax and structure (YAML parsing)
- Required fields presence
- JWT secret strength (minimum 256-bit entropy)
- OAuth2 + Redis dependency
- WebRTC cluster mode requirements
- Permission hierarchy correctness
- Network configuration validity
**Use in CI/CD:**
```yaml
# GitHub Actions example
- name: Validate Configuration
6 months ago
run: cargo run --bin synctv -- config validate
```
7 months ago
See [docs/config-validation.md](docs/config-validation.md) for detailed documentation.
## Security
- **Password Hashing**: Argon2id (PHC 2023 winner)
7 months ago
- **JWT**: HS256 symmetric HMAC
- **Permissions**: 64-bit bitmask system
- **TLS**: Recommended for production
## License
MIT OR Apache-2.0
## Contributing
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
## Status
8 months ago
**Current Status**: Production-ready core features
### Completed Features
- [x] User authentication (registration, login, JWT tokens)
- [x] Room management and real-time synchronization
- [x] Multi-provider media support (Bilibili, Alist, Emby)
- [x] Live streaming (RTMP push, HLS/FLV playback)
- [x] Multi-replica cluster support
- [x] OAuth2 integration (GitHub, Google, OIDC)
- [x] Permission system with 64-bit bitmask
- [x] WebSocket real-time communication
7 months ago
### Completed Infrastructure
- [x] Cross-replica cache invalidation via Redis Streams (durable delivery with catch-up on reconnection)
7 months ago
- [x] Configuration validation tool with CI/CD integration
8 months ago
**Next Milestone**: Production hardening and performance optimization