🇨🇳 Chinese Docs • 🇬🇧 English Docs
A pure PHP self-developed lightweight RTMP live streaming service with zero third-party media dependencies such as FFmpeg and Nginx, enabling quick setup of a private live streaming platform out of the box. On Linux environments, the
eventextension is automatically enabled for epoll event-driven I/O; on Windows, it automatically falls back to the select I/O model, ensuring full cross-platform compatibility. Project positioning: underlying infrastructure — fully self-developed RTMP/HTTP-FLV/WS-FLV protocol stack and asynchronous network engine; business management, permissions, playback management, and other upper-layer applications require developers to extend and implement themselves.
- Requirements
- Quick Start
- Push/Pull Stream Address Specification
- Live & VOD Access URLs
- Web Page Usage Guide
- Project Directory Structure
- System Architecture
- Port Constants Configuration
- Recording Task Switches
- Multi-Process Worker Configuration (IPC Stream Sync Core)
- Push Stream Authentication Configuration
- FLV Live Distribution Gateway
- Static File HTTP Gateway
- Multi-Way Push/Pull Stream Integration Guide
- Live Stream Forwarding Guide
- Cluster Deployment Architecture for 100,000+ Concurrent Connections
- FAQ
- Open Source License
- Companion Toolkit
- Contact
| Dependency | Mandatory Requirement Description |
|---|---|
| PHP | >= 8.1, CLI mode only, FPM is not supported |
| sockets extension | Strictly required, the foundation for underlying TCP/WS/RTMP communication |
| event extension | Highly recommended on Linux to enable epoll high-concurrency event model; on Windows without this extension, automatically falls back to select |
Quick environment setup: The project includes a
docker-compose.ymlfile; rundocker-compose up -dto start the complete runtime environment with one command.
composer create-project xiaosongshu/rtmp_server
cd rtmp_serverphp server.phpSuccessful startup output example:
[INFO] RTMP Server started on 0.0.0.0:1935
[INFO] HTTP-FLV/WS-FLV Server started on 0.0.0.0:8501
[INFO] HTTP Static Server started on 0.0.0.0:80
- Screen real-time push:
http://127.0.0.1/push.html - Local MP4/FLV file loop push:
http://127.0.0.1/flv_push.html
ffmpeg -re -stream_loop -1 -i video.mp4 -c:v libx264 -c:a aac -f flv rtmp://127.0.0.1:1935/live/stream- Server:
rtmp://127.0.0.1:1935/live/ - Stream Key:
stream
php pusher.php test.mp4 http://127.0.0.1:8501/live/streamBrowser access: http://127.0.0.1/index.html
| Protocol | Standard Format | Example Address |
|---|---|---|
| RTMP | rtmp://host:1935/{app}/{stream} |
rtmp://127.0.0.1:1935/live/stream |
| HTTP-FLV | http://host:8501/{app}/{stream} |
http://127.0.0.1:8501/live/stream |
| WebSocket-FLV | ws://host:8501/{app}/{stream} |
ws://127.0.0.1:8501/live/stream |
Field constraints:
{app}application name and{stream}channel name only allow English letters, numbers, and underscores; special symbols and Chinese characters are prohibited.
| Protocol | Access URL | Use Case |
|---|---|---|
| RTMP | rtmp://127.0.0.1:1935/live/stream |
ffplay, desktop professional players |
| HTTP-FLV | http://127.0.0.1:8501/live/stream.flv |
PC browser low-latency live streaming |
| WebSocket-FLV | ws://127.0.0.1:8501/live/stream.flv |
Browser native WebSocket MSE playback |
| HLS | http://127.0.0.1:80/hls/live/stream/index.m3u8 |
Mobile devices, WeChat built-in browser |
Recording files are persistently stored in the project root directory; complete files are automatically generated after the live stream ends:
| File Type | Storage Path | Access Example |
|---|---|---|
| Complete Merged MP4 | mp4/live/stream/output_merge/stream_full.mp4 |
http://127.0.0.1/mp4/live/stream/output_merge/stream_full.mp4 |
| Raw FLV Recording File | flv/live/stream/index.flv |
http://127.0.0.1/flv/live/stream/index.flv |
| HLS TS Segment Directory | hls/live/stream/ |
Directly use m3u8 index URL for playback |
| Page File | Description | Access URL |
|---|---|---|
| index.html | HTTP-FLV low-latency live player | http://127.0.0.1/index.html |
| play.html | HLS mobile-optimized player | http://127.0.0.1/play.html |
| mp4.html | MP4 VOD dedicated page | http://127.0.0.1/mp4.html |
| video.html | FLV VOD player | http://127.0.0.1/video.html |
| play_merge.html | fMP4 segmented VOD page | http://127.0.0.1/play_merge.html |
| Page File | Description | Access URL |
|---|---|---|
| push.html | Browser screen capture push (WS-FLV) | http://127.0.0.1/push.html |
| flv_push.html | Local MP4/FLV file loop push | http://127.0.0.1/flv_push.html |
| push_merge.html | Multi-view live compositing push | http://127.0.0.1/push_merge.html |
| push_transcode.html | Frontend multi-bitrate transcoding push for weak networks | http://127.0.0.1/push_transcode.html |
| Script | Function | Example Command |
|---|---|---|
| pusher.php | Command-line file push client | php pusher.php video.mp4 http://127.0.0.1:8501/live/stream |
| puller.php | Command-line pull and record client | php puller.php http://127.0.0.1:8501/live/stream.flv output.flv |
rtmp_server/
├── config/ # Global config: ports, multi-process, recording, push auth
├── flv/ # Real-time FLV raw stream recording storage
├── mp4/ # fMP4 segments & complete MP4 merged after stream ends
├── hls/ # HLS TS segments, m3u8 index files
├── MediaServer/ # RTMP/FLV/WS-FLV core protocol stack, session management
├── Root/ # Underlying async I/O, Socket event-driven engine
├── record/ # Client-side static page resources
├── server.php # RTMP origin main service entry point
├── flvGateway.php # FLV live distribution gateway startup script
├── fileGateway.php # HLS/MP4/static resource HTTP gateway
├── forward.php # Live stream forwarding client
├── pusher.php # PHP push client
├── puller.php # PHP pull client
├── auth_config.php # Push auth standalone configuration
├── *.html # All web push/pull and playback pages
├── docker-compose.yml # Docker one-click deployment config
└── LICENSE # Apache 2.0 open source license file
【External Pushers】OBS / FFmpeg / Web
│
RTMP(1935) / HTTP-FLV/WS-FLV(8501) Push Access
│
▼
╔══════════════════════════════════════════════════════════════════════════════════════╗
║ RTMP Origin Main Service (Stream Production Core) ║
║ ║
║ 📥 Push/Pull Access: RTMP / HTTP-FLV / WS-FLV triple protocol compatible, built-in auth ║
║ 🔄 Protocol Transmuxing: Output HTTP-FLV / WS-FLV / HLS / fMP4 / MP4 ║
║ 💾 Parallel recording tasks (completely non-blocking, individually toggleable) ║
║ ┌──────────┬──────────┬──────────┐ ║
║ │ FLV raw │ fMP4 real-│ HLS TS │ ║
║ │ recording │ time │ segments │ ║
║ └──────────┴──────────┴──────────┘ ║
║ 📤 Real-time stream output: HTTP-FLV, WS-FLV, HLS live streams ║
║ 📦 VOD artifacts: fMP4 segment cache, automatic complete MP4 merge after stream ends║
║ 📁 Built-in static HTTP service (port 80): no extra gateway needed for low concurrency ║
╚══════════════════════════════════════════════════════════════════════════════════════╝
│
┌───────────────────┼───────────────────┐
│ │ │
▼ ▼ ▼
HTTP-FLV real-time HLS static segment fMP4 static segment
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌──────────────────────────────────────────┐
│ FLV Gateway │ │ Static File Gateway Cluster │
│ Cluster │ │ Hosted: HLS/fMP4/MP4/FLV/web static │
│ │ │ │
│ ┌─────────┐ │ │ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │Primary │ │ │ │GW1 │ │GW2 │ │GW3 │ │
│ │Gateway │ │ │ │(8100) │ │(8101) │ │(8102) │ │
│ │(8080) │ │ │ └──┬────┘ └──┬────┘ └──┬────┘ │
│ └───┬─────┘ │ │ │ │ │ │
│ │ │ │ ▼ ▼ ▼ │
│ ┌───┴───┐ │ │ ┌──────────────────────────────────┐ │
│ ▼ ▼ ▼ │ │ │End-user Player Clients │ │
│ ┌─┐ ┌─┐ ┌─┐ │ │ │MSE/HLS Player/ffplay/Browser │ │
│ │S│ │S│ │S│ │ │ └──────────────────────────────────┘ │
│ │G│ │G│ │G│ │ │ │
│ └┬─┘ └┬─┘ └┬─┘ │ └──────────────────────────────────────────┘
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ │
│ │Live Viewers│ │
│ │FLV Players │ │
│ └────────────┘ │
└─────────────────┘
-
Origin Main Service (Sole Stream Producer) All external push streams uniformly access the origin, completing protocol parsing, authentication, multi-format transmuxing, and parallel recording; FLV recording, fMP4 slicing, and HLS slicing are three completely isolated threads that do not block each other. For low-concurrency scenarios, the built-in port 80 static service can be used directly without deploying additional gateways.
-
FLV Live Distribution Gateway No transcoding logic; only forwards traffic and caches GOP keyframes for instant player startup; supports horizontal scaling and multi-level cascading (production environment recommends at most two levels; more levels increase latency); Linux epoll for high concurrency; Windows is for testing only. In high-concurrency scenarios, all player pull requests go through the gateway to reduce connection pressure on the origin main process.
-
Static File Gateway Cluster Dedicated hosting for HLS, MP4, FLV, frontend pages, and other static resources, achieving read-write separation; must be deployed for large-scale VOD scenarios to prevent the origin from being overwhelmed by file I/O requests.
-
Integrated Live Streaming Tools This project supports pure PHP client push, pull, and live stream forwarding, as well as web frontend push, playback, transcoding, and compositing. Supports single-process/multi-process switching, as well as the personalized media resource toolkit
xiaosongshu/flv2mp4.
| Concurrency Level | Recommended Deployment |
|---|---|
| Low (<1000 concurrent viewers) | Start only the origin server.php with built-in ports 80 and 8501; no gateways needed |
| Medium (1000 ~ 5000 viewers) | Origin + single-layer FLV gateway cluster + single-layer static file gateway cluster; Nginx load balancing |
| High/Large-scale events (>5000 viewers) | Origin + multi-layer FLV gateway and static gateway clusters with front-end load balancing; events with tens of thousands of viewers must use commercial CDN edge distribution; do not let a single server carry all traffic |
Modify config/app.php to adjust global service ports; built-in constants:
/** HTTP-FLV / WebSocket-FLV main service port */
define('BASE_FLV_PORT', 8501);
/** RTMP standard 1935 port */
define('BASE_RTMP_PORT', 1935);
/** Built-in static web page and VOD HTTP port */
define('BASE_WEB_PORT', 80);config/app.php provides independent control over three recording tasks without interference:
define('FLV_TO_RECORD', true); // Enable real-time raw FLV stream recording
define('FLV_TO_MP4', true); // Enable fMP4 segmentation, auto-merge complete MP4 after stream ends
define('FLV_TO_HLS', true); // Enable HLS TS segment generationUnder the PHP CLI multi-process model, each Worker process has isolated memory; when a single process receives a push stream, other Workers cannot access the stream data. Therefore, stream synchronization must be achieved via IPC (Inter-Process Communication). This project does not use traditional system IPC such as shared memory or pipes. Instead, it implements a custom local TCP Socket IPC solution: allocates a set of internal communication ports, and the receiving Worker actively forwards the complete stream data to all other Workers via a built-in TCP client, enabling full stream data sharing across all processes.
/** Master switch: enable multi-process Worker mode */
define('ENABLE_MULTI_PROCESS', true);
/** Number of Worker processes; recommended not to exceed server CPU physical cores */
define('WORKER_COUNT', 3);
/** Starting value for inter-process TCP communication ports, auto-allocated sequentially 8502, 8503... */
define('COPY_PORT_START', 8502);When multi-process is disabled (
ENABLE_MULTI_PROCESS=false), the process count and internal communication port configuration become ineffective; the service runs in single-process mode without IPC stream synchronization.
- Linux: System supports port reuse; multiple Workers can simultaneously listen on the main FLV port 8501; the kernel automatically distributes player connections evenly across Workers;
- Windows: Although the system supports
SO_REUSEADDRport reuse, new TCP connections are only ever assigned to the first process that binds to port 8501; native load balancing is not possible. Nginx reverse proxy can be used to distribute traffic across internal communication ports (8502+); - Internal IPC ports are externally accessible for pulling streams, enabling manual load balancing on Windows.
- Linux: epoll I/O model; a single process supports thousands of concurrent long connections; multi-process can fully utilize multi-core CPUs; the preferred choice for production;
- Windows: Underlying select model has extremely low concurrency limits (~256 connections per process); intended only for local development and testing; do not deploy in production.
Prevents unauthorized streams from overwriting live channels; only push requests carrying a valid stream key are allowed; players do not require authentication for pulling.
Configuration file config/auth.php
<?php
return [
'enabled' => false, // Auth master switch
'publish' => [
'require_auth' => true, // Force key verification for push streams
'stream_keys' => [
'live_123456',
'stream_key_abc',
],
],
'global' => [
'allowed_apps' => ['live'], // Allowed application names
'deny_apps' => [],
],
];Carry the key via URL parameter key:
- RTMP
ffmpeg -re -i video.mp4 -f flv rtmp://127.0.0.1:1935/live/stream?key=live_123456- OBS Stream Key:
stream?key=live_123456 - HTTP-FLV
ffmpeg -re -i video.mp4 -f flv http://127.0.0.1:8501/live/stream?key=live_123456- WS-FLV PHP Client
php pusher.php test.flv "ws://127.0.0.1:8501/live/stream?key=live_123456"- Replace default keys with random strings longer than 32 characters;
- Enable HTTPS/WSS in public network deployments to prevent plaintext key sniffing;
- Rotate stream keys regularly to reduce leakage risk.
- Authentication is disabled by default; enable it manually if needed.
A lightweight traffic forwarding service that pulls HTTP-FLV/WS-FLV streams from upstream origins and caches GOP keyframes for instant player startup; supports horizontal scaling and multi-level cascading to offload origin concurrency pressure.
# Basic single instance
php flvGateway.php 8080 http://127.0.0.1:8501
php flvGateway.php 8080 ws://127.0.0.1:8501
# Horizontal scaling with multiple instances on same layer
php flvGateway.php 8080 http://127.0.0.1:8501
php flvGateway.php 8081 http://127.0.0.1:8501
php flvGateway.php 8082 ws://127.0.0.1:8501
# Multi-level cascading (not recommended to exceed two levels)
php flvGateway.php 8080 http://127.0.0.1:8501 # Level 1 gateway
php flvGateway.php 8081 http://127.0.0.1:8080 # Level 2 gateway
# Linux background silent run
php flvGateway.php 8080 http://127.0.0.1:8501 > /dev/null 2>&1 &http://GatewayIP:Port/{app}/{stream}.flv
ws://GatewayIP:Port/{app}/{stream}.flv
Example: http://127.0.0.1:8080/live/stream.flv
An independent static resource HTTP service that hosts HLS, MP4, FLV, and frontend pages, separating file I/O from live streaming business to improve VOD stability under high concurrency.
# Single instance
php fileGateway.php 0.0.0.0 8100
# Multiple instances for horizontal scaling
php fileGateway.php 0.0.0.0 8100
php fileGateway.php 0.0.0.0 8101
php fileGateway.php 0.0.0.0 8102
# Linux background run
php fileGateway.php 0.0.0.0 8100 > /dev/null 2>&1 &upstream filegateway_cluster {
server 127.0.0.1:8100;
server 127.0.0.1:8101;
server 127.0.0.1:8102;
}
server {
listen 80;
server_name media.example.com;
location ~* \.(m3u8|ts|mp4|m4s|flv|html|css|js)$ {
proxy_pass http://filegateway_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}http://127.0.0.1:8100/index.html
http://127.0.0.1:8100/hls/live/stream/index.m3u8
http://127.0.0.1:8100/mp4/live/stream/output_merge/stream_full.mp4
OBS, FFmpeg, and PHP clients all support the standard RTMP protocol; address format: rtmp://host:1935/{app}/{stream}
Suitable for command-line and programmatic automated pushing; address: http://host:8501/{app}/{stream}
A browser-native push solution with latency as low as 50ms; use the built-in push.html page.
Used for server-side backup pulling and cross-server forwarding:
php puller.php http://127.0.0.1:8501/live/stream.flv output.flv
php puller.php ws://127.0.0.1:8501/live/stream.flv output.flvThis project provides live stream forwarding functionality, allowing forwarding to multiple destination servers with support for rtmp/ws-flv/http-flv protocols. See forward.php for detailed commands; example forwarding command:
php forward.php http://127.0.0.1:8501/a/b.flv "rtmp://127.0.0.1:1935/c/d,ws://127.0.0.1:8501/c/e,http://127.0.0.1:8501/c/f" The above command forwards the live stream http://127.0.0.1:8501/a/b.flv to rtmp://127.0.0.1:1935/c/d, ws://127.0.0.1:8501/c/e, and http://127.0.0.1:8501/c/f. Of course, you can also forward to any other platform that supports rtmp, ws-flv, or http-flv.
pusher.php / puller.php can be integrated into backend scheduled tasks to implement automated pull-forwarding and backup recording without relying on third-party tools, completing a full PHP live streaming business loop.
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ 【Layer 1: Multi-Streamer Push Layer】 │
│ │
│ Streamer A (OBS/Web/FFmpeg) Streamer B (OBS/Web/FFmpeg) Streamer N (OBS/Web/FFmpeg)│
│ │ │ │ │
│ ┌─────┼─────┐ ┌─────┼─────┐ ┌─────┼─────┐ │
│ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ ▼ │
│ [Node1][Node2][Node3] [Node1][Node2][Node3] [Node1][Node2][Node3] │
│ (Push to multiple origin nodes simultaneously for streamer-side failover) │
└─────────────────────────────────────────────────────────────────────────────────────────┘
│
│ RTMP/HTTP‑FLV/WS‑FLV ingest
▼
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ 【Layer 2: Origin Node Cluster (Stream Production Core)】 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Origin Node A│ │ Origin Node B│ │ Origin Node C│ │ Origin Node D│ │
│ │ server.php │ │ server.php │ │ server.php │ │ server.php │ │
│ │ (multi‑proc)│ │ (multi‑proc)│ │ (multi‑proc)│ │ (multi‑proc)│ │
│ │ rec/segment │ │ rec/segment │ │ rec/segment │ │ rec/segment │ │
│ └─────┬───────┘ └─────┬───────┘ └─────┬───────┘ └─────┬───────┘ │
│ │ │ │ │ │
│ └────────┬────────┴─────────────────┴────────┬────────┘ │
│ │ │ │
│ ┌────▼────┐ ┌────▼────┐ │
│ │ forward │ │ forward │ ← automatic stream sync │
│ │ sync │ │ sync │ (pull → push) │
│ └────┬────┘ └────┬────┘ │
│ └──────────────┬────────────────────┘ │
│ │ │
│ (All origin nodes back each other up; if any fails, others continue)│
└──────────────────────────────────┼────────────────────────────────────────────────────┘
│
│ forward pulls (from origin, pushes to edge)
▼
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ 【Layer 3: Edge Node Cluster (Distribution & Caching)】 │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Edge Node X │ │ Edge Node Y │ │ Edge Node Z │ │ Edge Node W │ │
│ │ server.php │ │ server.php │ │ server.php │ │ server.php │ │
│ │ (multi‑proc)│ │ (multi‑proc)│ │ (multi‑proc)│ │ (multi‑proc)│ │
│ │ rec/segment │ │ rec/segment │ │ rec/segment │ │ rec/segment │ │
│ └─────┬───────┘ └─────┬───────┘ └─────┬───────┘ └─────┬───────┘ │
│ │ │ │ │ │
│ └────────┬────────┴─────────────────┴────────┬────────┘ │
│ │ │ │
│ ┌────▼────┐ ┌────▼────┐ │
│ │ forward │ │ forward │ ← pulls from origin, │
│ │ sync │ │ sync │ caches GOP │
│ └─────────┘ └─────────┘ │
│ │
│ ★ Dynamic role switching: any node can be promoted to origin (accept pushes) or │
│ demoted to edge (only pull and distribute) on demand. │
│ ★ All nodes record independently, providing multiple backup copies for reliability. │
└──────────────────────────────────┼────────────────────────────────────────────────────┘
│
┌─────────────┴─────────────┐
│ │
▼ ▼
┌────────────────────────────┐ ┌────────────────────────────┐
│ 【Layer 4: Gateway Layer】 │ 【Layer 4: Gateway Layer】 │
│ │ │ │
│ flvGateway Cluster │ │ fileGateway Cluster │
│ ┌─────┐ ┌─────┐ ┌─────┐ │ │ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │ GW1 │ │ GW2 │ │ GW3 │ │ │ │ GW1 │ │ GW2 │ │ GW3 │ │
│ └──┬──┘ └──┬──┘ └──┬──┘ │ │ └──┬──┘ └──┬──┘ └──┬──┘ │
│ │ │ │ │ │ │ │ │ │
│ └───────┼───────┘ │ │ └───────┼───────┘ │
│ │ │ │ │ │
│ (HTTP‑FLV/WS‑FLV) │ │ (HLS/MP4/FLV VOD & static)│
└─────────────┼─────────────┘ └─────────────┼─────────────┘
│ │
└─────────────┬───────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────────────────┐
│ 【Layer 5: Viewer Terminals】 │
│ │
│ PC Browser (MSE/FLV.js) Mobile (HLS) ffplay/pro players WebSocket players │
│ │
│ ★ Viewers connect to the nearest edge gateway; load balancing (DNS/Nginx) routes │
│ them to the optimal node automatically. │
└─────────────────────────────────────────────────────────────────────────────────────────┘
- Multi‑destination pushing: Streamers can push to multiple origin nodes (e.g., nodes A, B, C) simultaneously. If any origin node fails, other nodes still hold the stream, and viewers experience no interruption.
- Automatic failover at the streamer: OBS/FFmpeg can be configured with backup push URLs for primary‑backup switching; web clients can use JavaScript to push to multiple destinations.
- Active‑active deployment: All origin nodes are active and capable of accepting pushes. They synchronise stream data with each other via
forward.php, ensuring every origin node holds a complete stream copy. - Automatic failover: If any origin node goes down, the remaining nodes continue to serve, and the forwarding sync links automatically reconnect without service interruption.
- Parallel recording: Each origin node independently performs FLV/fMP4/HLS recording, creating multiple physical backups to prevent single‑point storage loss.
- Latency‑aware pulling: Edge nodes pull live streams from origin nodes via
forward.phpand cache GOP keyframes, enabling low‑latency, instant‑start playback for viewers. - Elastic scaling: Edge nodes can be dynamically added or removed based on concurrent load, supporting horizontal scaling (e.g., for traffic spikes).
- Flexible role switching: Origin and edge nodes share the same codebase. Through configuration adjustments, any node can be promoted to an origin (accepting pushes) or demoted to an edge (only pulling and distributing), allowing on‑demand resource allocation.
- flvGateway Cluster: Dedicated to HTTP‑FLV/WS‑FLV real‑time streams. It performs no transcoding, only pure forwarding, and leverages GOP caching for instant start. Supports multi‑level cascading and horizontal scaling to handle massive player connections.
- fileGateway Cluster: Independently hosts HLS segments, MP4 VOD files, static pages, and other resources. Separation from dynamic stream traffic prevents file I/O from blocking live streaming services.
- Multi‑protocol support: RTMP, HTTP‑FLV, WS‑FLV, and HLS are all supported, covering PC, mobile, and web platforms.
- Intelligent routing: Via DNS round‑robin, Nginx reverse proxy, or Global Server Load Balancing (GSLB), viewer requests are directed to the nearest or least‑loaded edge node for optimal experience.
- Push: Streamer → (multi‑path) → origin node cluster →
forwardsynchronises to all origin nodes. - Pull (edge): Edge nodes →
forwardpulls from any origin node → caches → serves local viewers. - Playback: Viewers → load balancer → flvGateway/fileGateway → edge node (or origin) → receives stream data.
- Recording: All nodes (origin and edge) perform recording according to configuration; final merged MP4 files are generated for VOD playback.
- Node‑level failover: If any single node (origin or edge) fails, the forwarding clients automatically reconnect to other alive nodes; stream data is not interrupted.
- Regional failover: If an entire data centre goes down, DNS can switch to a standby data centre (requiring multiple cluster deployments), enabling cross‑region high availability.
- Recording redundancy: Each node stores its recordings independently; for important live events, multiple nodes can be selected to record simultaneously to guarantee data integrity.
- Horizontal scaling: Every layer supports adding more nodes to distribute load without restarting existing services.
- 100K+ concurrency: Edge nodes and the gateway layer can scale out massively. Combined with CDN edge acceleration, the system can support 100,000+ concurrent viewers (provided sufficient bandwidth and server resources).
- Performance optimisation: On Linux, the
eventextension (epoll) drives each node to handle thousands of persistent connections (depending on server specifications); the multi‑node cluster increases concurrency linearly.
- Data synchronisation between nodes is accomplished via the built‑in
forward.phprelay client. This tool can pull streams from any source (RTMP/HTTP‑FLV/WS‑FLV) and push them to one or more target nodes simultaneously, and it supports carrying authentication parameters (e.g.,key) during push. Developers can write scheduling scripts based on actual network topology and business requirements—for example, combining health checks, load balancing policies, or business rules—to dynamically configure pull source addresses, target node lists, and forwarding parameters, thus achieving automated stream synchronisation across nodes. - The role switching between origin and edge nodes also relies on external scheduling logic. It is recommended to monitor node system status (e.g., CPU load, memory usage, active connections, push stream count, etc.) or external traffic distribution policies, and trigger scripts to adjust node roles dynamically, thereby enabling elastic scaling, failover, and disaster recovery switching. The entire scheduling system can be customised for different scenarios, providing a highly flexible production‑grade deployment solution.
Windows does not have the event extension; the service automatically switches to the select I/O model. Only the sockets extension is required for normal operation; no additional handling is needed.
Three listening logs in the terminal output indicate success: RTMP 1935, FLV 8501, and static port 80.
- Push bitrate or resolution is too high; reduce bitrate/frame rate for testing;
- Server CPU is fully loaded; enable multi-process to leverage multiple cores;
- No FLV gateway deployed under high concurrency; excessive player connections consume origin resources;
- Insufficient server upstream bandwidth; limit concurrent viewer count.
Press Ctrl + C in the terminal to send a termination signal, or simply close the terminal window.
Fully compatible with standard RTMP clients: OBS Studio, FFmpeg, xSplit, and mobile RTMP push SDKs.
This project is licensed under the Apache License 2.0.
The software is provided "as is", without any express or implied warranties. The developers are not liable for any direct, indirect, or consequential damages arising from the use of this program. For the full terms, see the LICENSE file in the project root directory.
The underlying codec and transmuxing capabilities are extracted as an independent toolkit: xiaosongshu/flv2mp4 Provides FLV/MP4/fMP4/HLS conversions, standalone push/pull clients, and gateway components; can be independently imported into third-party PHP projects.
- Email: 2723659854@qq.com
- GitHub: https://github.com/2723659854