English | 简体中文
bilive is a local Bilibili live management service. It runs as a headless
Rust service, listens on a loopback address by default, and serves a static
browser admin UI from web/.
The project has these main pieces:
- A Rust CLI and service backend.
- A desktop danmu overlay (
bilive-danmu) that renders chat as a click-through, always-on-top window, with native X11 (Linux) and macOS backends. - An embedded, plain HTML/CSS/JavaScript admin UI with no frontend build step.
- A Linux systemd service template kept separate from the service implementation.
- Cookie login and Bilibili app QR-code login.
- Login bootstrap for user profile, room id, live areas, and danmu token.
- Live title and area updates.
- Start and stop live streams, capture stream credentials, and optionally test
a stream credential with
ffmpeg. - Danmu connect/disconnect, WebSocket event streaming, and comment sending.
- Room admin, user silent, global silent, blocked word, user search, and online rank management APIs.
- Optional VTuber control tab that saves EasyVtuber launch settings and starts/stops the external runtime from the web UI.
- Static UI tabs for account, stream, danmu, VTuber, and manager workflows.
- A standalone desktop danmu overlay rendered as a click-through, always-on-top
window (
bilive-danmu).
crates/
bilive-cli/ # bilive start/stop/status/restart and foreground serve
bilive-core/ # Bilibili API client, signing, state, danmu, events
bilive-server/ # axum HTTP/WebSocket routes and static file serving
bilive-danmu/ # desktop danmu overlay (native X11 / macOS backends)
web/ # No-build static admin UI
packaging/ # systemd service unit template
Run the service in the foreground from the repository root:
cargo run -p bilive -- serve --listen 127.0.0.1:22333Then open:
http://127.0.0.1:22333
By default the frontend is served from static files embedded in the binary.
During UI development, pass --web-dir web to serve files directly from the
working tree and refresh the browser after edits.
For day-to-day local use, the CLI can manage a background service:
cargo run -p bilive -- start --listen 127.0.0.1:22333
cargo run -p bilive -- status
cargo run -p bilive -- restart --listen 127.0.0.1:22333
cargo run -p bilive -- stopTo open the web dashboard in a browser, starting the background service first if it is not already running:
cargo run -p bilive -- dashboarddashboard is idempotent: it reuses the running service when one exists,
otherwise it starts one and waits for the health check, then opens
http://<listen> with xdg-open (Linux) or open (macOS). It is the command
wired into the installed bilive.desktop launcher (see Install).
start writes bilive.pid and bilive.log under the state directory unless
--pid-file or --log-file is provided. serve runs the same service in the
foreground and is the command used by the systemd unit.
The serve subcommand is hidden from top-level help because it is mostly an
implementation detail for foreground development, the background child process,
and service managers.
If you use non-default state paths, pass the same --state-dir, --pid-file,
or --log-file values to status, restart, and stop. If you use a
non-default listen address, pass the same --listen value to status for the
health check.
bilive-danmu is a standalone desktop overlay that connects to a running
bilive service over HTTP/WebSocket and renders chat as a click-through,
always-on-top window. It has native X11 (Linux) and macOS backends.
Run the service first, then start the overlay:
cargo run -p bilive-danmu -- --url http://127.0.0.1:22333 --overlayIt subscribes to /api/events, refreshes recent danmu through
/api/danmu/messages, and requests /api/danmu/connect on startup unless
--no-connect is passed.
Useful flags:
--overlay: render as a click-through, always-on-top overlay instead of a normal window.--backend auto|x11|macos: select the window backend (defaultauto).--room-id <id>: override the room id used when connecting danmu.--x,--y,--width,--height,--height-ratio: overlay position and size in pixels (height falls back to--height-ratioof the screen when--heightis0).--font-family,--font-size,--max-lines,--opacity: overlay appearance.--show-system: include service/system messages in the overlay.--test-overlay: show synthetic test messages without connecting to a service.--no-click-through: keep receiving mouse input for debugging (only with--overlay).
VTuber support is optional and disabled by default. If you never open the VTuber tab or start the runtime, bilive runs normally without Python, EasyVtuber, GPU drivers, model files, Spout2, or OBS virtual camera support.
bilive only drives the external EasyVtuber runtime. For a full deployment and usage walkthrough (installing EasyVtuber, configuring bilive, and showing the avatar in OBS), see VTUBER.md.
Prepare an EasyVtuber runtime first. It must be runnable without the EasyVtuber wxPython launcher, because bilive starts the core process directly:
python -m src.mainIn the web UI, open the VTuber tab and configure:
运行目录: the EasyVtuber project or unpacked runtime directory containingsrc/main.py, for example/home/jamie/proj/EasyVtuber.Python: the interpreter for that environment, for examplepython,python.exe, or a full conda/env path.角色名: a PNG name under EasyVtuberdata/images/, without.png.输入:鼠标,鼠标 + 音频,iFacialMocap,OpenSeeFace,摄像头, or调试输入.输入地址: required for iFacialMocap or OpenSeeFace, such as192.168.1.10:49983or127.0.0.1:11573.鼠标区域:x,y,w,hscreen region for mouse input, default0,0,1920,1080. Set this for non-1080p or multi-monitor setups (invalid values fall back to the default).输出: choose调试窗口,OBS 虚拟摄像头, orSpout2. The UI marks which modes work on the current OS (see the OBS section below).- Model, FPS, cache, interpolation, super-resolution, TensorRT, and extra args should match the same values you would pass to EasyVtuber.
Click 保存设置 to persist the TOML config. Click 启动形象 only when the
EasyVtuber environment is ready. Click 停止形象 to terminate the external
process started by bilive.
The VTuber tab captures the runtime's stdout/stderr to vtuber.log under the
cache directory (~/.cache/bilive/vtuber.log by default) and shows the tail
under 运行日志, plus the last exit code when the process stops. Check it first
when 启动形象 appears to do nothing — Python tracebacks, missing dependencies,
model-not-found, and pyvirtualcam backend errors all surface there.
The backend intentionally does not rewrite EasyVtuber in Rust. bilive owns the control plane: config, status, start, and stop. The Python/GPU inference runtime remains external because it depends on PyTorch, ONNX Runtime, DirectML, TensorRT, OpenCV, Mediapipe, Spout/virtual camera output, and model artifacts.
EasyVtuber's output modes are not all available on every OS, and bilive's
OBS 显示 card reflects what works on the current host:
- Linux (recommended, works out of the box): set
输出to调试窗口. EasyVtuber opens an OpenCV window titledEasyVtuber Debug Frame. In OBS add a Window Capture (Xcomposite) source, pick that window, then add a Chroma Key / Luma Key filter to drop the background and crop to the avatar. - Linux (advanced, virtual camera): load v4l2loopback
(
sudo modprobe v4l2loopback exclusive_caps=1 card_label="EasyVtuber"), set输出toOBS 虚拟摄像头, and add a Video Capture Device (V4L2) source in OBS. Caveat: upstream EasyVtuber hardcodespyvirtualcambackend='obs', which is unavailable on Linux, so the stock runtime may fail to write to the loopback device without a patch — the capturedvtuber.logwill show the pyvirtualcam error if so. Prefer the debug-window path unless you maintain a patched EasyVtuber. - Windows:
Spout2(install the OBS Spout2 plugin, add a Spout2 Capture source namedEasyVtuber) orOBS 虚拟摄像头(OBS Video Capture Device). Spout2is rejected on non-Windows hosts with an explanatory message.
For full deployment, usage, and testing steps (including a stub runtime that needs no GPU), see VTUBER.md.
The user-editable application config is stored as TOML. By default, the config file lives at:
~/.config/bilive/config
When XDG_CONFIG_HOME is set, the default config path is:
$XDG_CONFIG_HOME/bilive/config
Cookies, CSRF tokens, WBI keys, room tokens, area metadata, and stream credentials are runtime state, not user config. They are stored separately under the platform cache directory. On Linux this is usually:
~/.cache/bilive/state.json
When XDG_CACHE_HOME is set, the default cache state path is:
$XDG_CACHE_HOME/bilive/state.json
The VTuber runtime's stdout/stderr are captured to vtuber.log in the same
cache directory (~/.cache/bilive/vtuber.log by default), truncated on each
启动形象.
For compatibility, bilive still reads the previous JSON config shape from the
selected config path, or the old default config.json from the state directory
when no explicit config path is provided, then rewrites future saves as TOML
config plus cache state.
Background runtime state is separate. start writes bilive.pid and
bilive.log under the platform state directory. On Linux this is usually:
~/.local/state/bilive
Useful overrides:
--configorBILIVE_CONFIG: config TOML file path.--cache-dirorBILIVE_CACHE_DIR: cache directory for login and live runtime state.--listenorBILIVE_LISTEN: service bind address.--web-dirorBILIVE_WEB_DIR: override the embedded UI with a static UI directory.--state-dirorBILIVE_STATE_DIR: state directory for background control.--pid-fileand--log-file: explicit background pid and log files.--timeout: seconds to wait for health checks or shutdown during background control operations.BILIVE_FFMPEG:ffmpegexecutable used by the stream test endpoint.RUST_LOG: tracing filter; the default enables bilive crates andtower_httpatinfolevel.
Danmu desktop notifications are off by default. Enable them from the danmu
settings in the web UI, or set danmu_notifications.enabled in the config
file. danmu_notifications.expire_timeout_ms controls the requested display
duration on Linux; 0 uses the notification daemon default. On Linux, bilive
calls notify-send, so Wayland compositors such as Hyprland need a notification
daemon like mako, dunst, or swaync running in the user session. System
services usually cannot reach the desktop session; use bilive start from the
user session or a systemd user service for desktop notifications.
Useful checks:
cargo fmt --all -- --check
cargo check --workspace
cargo test --workspace
node --check web/app.jsThe workspace uses Rust 2024 and the Rust version declared in Cargo.toml.
The frontend has no npm, Vite, or bundler dependency.
Build the release binaries, then install them together with a bilive.desktop
launcher:
make build
sudo make installThis installs bilive and bilive-danmu into $(PREFIX)/bin (default
/usr/local/bin) and a bilive.desktop entry into
$(PREFIX)/share/applications. The desktop entry runs bilive dashboard, which
starts the background service if it is not already running and then opens the
web dashboard in your browser, so you can launch bilive from an application
launcher such as rofi.
Override the locations with PREFIX, BINDIR, or APPSDIR, and stage into a
packaging root with DESTDIR. Remove everything again with sudo make uninstall.
Build the release binary:
cargo build --release -p biliveInstall the release binary:
/usr/local/bin/bilive
Then enable the service:
sudo cp packaging/systemd/bilive.service /etc/systemd/system/bilive.service
sudo systemctl daemon-reload
sudo systemctl enable --now bilive.serviceThe packaged service listens on 127.0.0.1:22333, stores state in
/var/lib/bilive, and sets conservative systemd sandboxing options.
Keep the default listener on 127.0.0.1 unless the deployment is intentionally
protected by another access-control layer. Do not log cookies, CSRF tokens,
danmu tokens, or stream keys. API responses should expose only the minimum
state the local UI needs.