# Xiu: a Rust media server that speaks five live streaming protocols

> A pure Rust live media server built as a Cargo workspace of per-protocol crates, with RTMP, RTSP, WebRTC, HTTP-FLV and HLS front ends feeding one shared stream hub, and a Makefile whose build targets are less obvious than they look.

**harlanc/xiu** —  A simple,high performance and secure live media server in pure Rust (RTMP[cluster]/RTSP/WebRTC[whip/whep]/HTTP-FLV/HLS).🦀

- Repository: https://github.com/harlanc/xiu
- Website: https://rustxiu.com
- Stars: 2,332 · Forks: 240
- Language: Rust
- License: MIT
- Published: 2026-10-06 · Updated: 2026-10-06 · Language: en
- Canonical page: https://hysenlabs.com/projects/harlanc-xiu

## A workspace of crates, one per protocol

The first thing the repository layout tells you is that Xiu is not one binary built from one crate. `Cargo.toml` at the root declares a Cargo workspace with fifteen members, and the naming follows the directory structure exactly:

```toml
[workspace]
resolver = "1"
members = [
  "protocol/rtmp",
  "protocol/httpflv",
  "protocol/hls",
  "protocol/rtsp",
  "protocol/webrtc",
```

The pattern is consistent throughout. Protocol implementations live under `protocol/`, reusable pieces live under `library/`, and the applications that assemble them live under `application/`. The library side includes `library/bytesio` for buffered reading, `library/container/flv` and `library/container/mpegts` for the two container formats that show up everywhere in this problem, `library/codec/h264` for the video codec, plus `library/streamhub`, `library/logger` and `library/common`.

The applications are `application/xiu`, which is the server itself, `application/http-server`, `application/pprtmp` for the RTMP proxy role, and `application/http-server` again as a dependency of the main one.

This layout is the most useful thing in the repository for an engineer evaluating it. A protocol crate you do not want to carry does not drag in a protocol crate you do, and someone integrating Xiu as a library can depend on `streamhub` and one protocol rather than on the whole server.

## Why protocol conversion is the feature that matters

The README's feature list reads like a checklist until you notice that half the entries are about converting between protocols rather than supporting them.

For RTMP the list includes publishing or subscribing H.264 and AAC streams, a configurable GOP cache, cluster support, and conversion from RTMP to HTTP-FLV and HLS. For RTSP it lists publishing or subscribing H.265, H.264 and AAC over both TCP interleaved and UDP, plus conversion from RTSP to RTMP, HLS and HTTP-FLV. For WebRTC it lists publishing with WHIP, subscribing with WHEP, and conversion from WHIP to RTMP, HLS and HTTP-FLV. HTTP-FLV and HLS are listed as receiving streams transferred from RTMP or RTSP.

That is the design in one paragraph: several ingest protocols on the front, and a distribution set on the back, joined in the middle. A publisher pushes RTMP from OBS or FFmpeg, and a browser player gets HTTP-FLV, while a second consumer gets HLS for a native player on a different platform. The GOP cache in that path is what makes the conversion work at all, because a new subscriber joining mid-stream needs recent keyframes rather than waiting for the next one.

The alternative for most teams is running FFmpeg as a transcoding relay between protocols, which means process supervision, argument quoting, and a second machine to keep alive. Xiu moves that work into Rust, at the cost of the flexibility FFmpeg gives you.

## Authentication, HTTP API and recording

Three features in the list are operational rather than protocol-related, and they are the ones a deployment has to turn on.

The first is token authentication, listed as supported at the top level. The second is the HTTP API and notifications, which the README splits into querying stream information and notification of stream status. Streaming servers need to answer two questions from outside the stream: is it up, and who is watching. An HTTP API for the first and a notification mechanism for the second is enough to drive autoscaling decisions and dashboards without polling.

The third is recording live streams into HLS files, described as m3u8 plus ts. Recording in HLS rather than to a single file is a deliberate choice with real consequences: the output is a segmented, playlist-based format that plays back anywhere, but it also means a recording is a directory of files rather than one artefact, and long recordings leave a lot of small files behind.

The 0.13.0 release notes show what the HTTP surface grew into. They list abstract streamhub message notifications, an optional `push_password` for simple authentication, Authorization header support for WebRTC, and support for an RTSP pull client, so a remote RTSP stream can now be pulled into Xiu through the HTTP API rather than only being pushed to it.

That last one is the interesting direction of travel. The earlier model was push-only ingest, and adding a pull client turns the server into something closer to a relay.

## Reading the Makefile before running make

The root `Makefile` has a rough edge that will cost you time if you skip it. Its default target is named `not_spport`, with the typo in the name, and it echoes the usage line:

```bash
make local
make online
make check
make clean
make build
```

The distinction between the first two is the important one. The `local` target runs a shell script against the `confs/` directory with the argument `local`, and `online` runs the same script with `online`. The comments above them describe the difference: `local` builds the local source codes, while `online` pulls the online crates and builds.

In other words, running `make build` on its own does not set up your configuration files. The comment in the Makefile describes `local` as building local source code and `online` as pulling the online crates code and building, which points at the `update_project_conf.sh` script deciding whether your dependency versions resolve against this checkout or against published crates.

For anyone hacking on the source, `local` is the target you want, because it keeps your changes in the tree. For someone who just wants the released server, `online` is the one.

The remaining targets are straightforward: `cargo build`, `cargo clean`, and a `check` target that runs `cargo clippy --fix --allow-dirty --allow-no-vcs`. That last flag combination is worth noting, since `--allow-dirty` and `--allow-no-vcs` mean clippy will rewrite files in place even in a dirty or version-control-free directory.

## Where the README is thin and the docs take over

The README for this project is mostly badges, a sponsor block, a feature checklist and a contributors section. Crates.io version badges appear for the umbrella `xiu` crate and then for each protocol crate individually: `rtmp`, `xrtsp`, `xwebrtc`, `httpflv`, `hls`, `xflv` and `xmpegts`.

That badge set is more informative than it looks. Publishing each protocol as its own crate means a consumer can depend on the RTMP client without pulling the WebRTC implementation, and it means the crate versions move independently. If you are writing a Rust application that only needs to publish RTMP, the umbrella `xiu` binary is the wrong dependency and `rtmp` is the right one.

Actual documentation lives elsewhere. The README links an English documentation site and a Chinese one, and the repository carries a `doc/` directory and a separate `README_CN.md` for the Chinese README. Configuration examples are in `confs/`, and there is a `docker/` directory for container builds.

The README also credits `media-server` under a thanks section, which is the acknowledgement that tells you where the project's lineage is. Reading that project's architecture notes alongside Xiu is a reasonable way to understand the protocol implementations faster than the docs will get you there.

## Release history, licence and the honest limits

The repository is not archived, and the last push was on 2026-03-07. The published releases, however, stop much earlier: v0.13.0 on 2024-08-11, v0.12.7 on 2024-05-17, and v0.12.6 on 2024-04-03. There is a gap between the last release and the last commit, which usually means work is landing on master without tags being cut.

What the release notes contain is worth reading anyway, because they are mostly fixes to specific protocol edge cases. v0.12.7 fixed RTMP publishing of a single AAC stream from an FFmpeg client and an RTMP auth failure caused by an empty string query string in a packet. v0.12.6 fixed WHIP stream establishment, the recognition of Opus encoding parameters, and reading HTTP resources when pulling streams over WHEP. v0.13.0 fixed a Rust 1.80 dependency breakage and a case where Xiu could not receive an RTSP stream published by GStreamer.

Read as a group, those describe a project where the interoperability bugs come from other people's implementations. GStreamer, FFmpeg, browser WHIP clients and Opus parameters are the four battlefronts, and each fix is one more combination that now works.

On licensing, Xiu is MIT, which means no obligation beyond attribution if you embed it, and the individual protocol crates inherit that. That matters for commercial streaming work, where copyleft licences in the dependency chain are a real negotiation.

The limits are structural rather than incidental. There is no transcoding: the supported codecs are H.264, H.265 and AAC, and if you need to convert between them you still need FFmpeg. There is no on-demand video or a manifest for VOD, only HLS recording. And the cluster support listed under RTMP is not the same thing as operating a CDN, which is what separates this from a platform rather than a server.

## Conclusion

Xiu is worth a look when you need one binary that accepts a stream over RTMP and hands it out over HTTP-FLV and HLS, because protocol conversion across five front ends over a shared hub is the whole point and the alternatives tend to cover one or two protocols each. It is not the choice when you need a large-scale streaming platform, since the release history ends at v0.13.0 in August 2024 and the last push was on 2026-03-07. Build it with the `local` target so the configuration files point at your checkout rather than at crates.io, and read `confs/` before you deploy, because that directory is where the cluster, token authentication and recording settings actually live.

## FAQ

### Is there an open-source streaming server available?

Xiu is one: a live media server written in pure Rust under the MIT licence, supporting RTMP, RTSP, WebRTC with WHIP and WHEP, HTTP-FLV and HLS. It is published to crates.io both as an umbrella xiu crate and as separate crates per protocol.

### How do I build Xiu from source?

The root Makefile expects a configuration step before a plain cargo build. The local target runs update_project_conf.sh against the confs directory with the local argument to build from the local source, while the online target pulls the published crates instead. make check runs cargo clippy with --fix.

### Which protocols can Xiu convert between?

The README lists conversion from RTMP to HTTP-FLV and HLS, from RTSP to RTMP, HLS and HTTP-FLV, and from WHIP to RTMP, HLS and HTTP-FLV. It does not list transcoding, so codec conversion between H.264, H.265 and AAC is not covered.

### Does Xiu support authentication and recording?

Yes. The feature list includes token authentication, an HTTP API for querying stream information and for stream status notifications, and recording live streams into HLS files as m3u8 plus ts. The 0.13.0 notes add an optional push_password for simple authentication and Authorization header support for WebRTC.

## Sources

- [harlanc/xiu on GitHub](https://github.com/harlanc/xiu)
- [License: MIT](https://github.com/harlanc/xiu/blob/master/LICENSE)
- [Project website](https://rustxiu.com)
- [README](https://github.com/harlanc/xiu/blob/master/README.md)
- [Releases](https://github.com/harlanc/xiu/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/harlanc-xiu
