xiaosongshu / rtmp_server
Native PHP RTMP live server with FLV/HLS, MP4 slicing, PHP client, relay & gateway.
Requires
- php: >=8.1
- ext-zlib: *
- apix/log: ^1.2
- evenement/evenement: ^3.0
- react/promise: ^2.9
- xiaosongshu/flv2mp4: ^1.4
This package is auto-updated.
Last update: 2026-07-30 07:28:19 UTC
README
π¨π³ δΈζζζ‘£ β’ π¬π§ English Docs
A lightweight RTMP live streaming service built in pure PHP, zero dependencies on FFmpeg, Nginx, or other third-party streaming software, enabling rapid deployment of private live streaming platforms out of the box. On Linux environments, the
eventextension is automatically enabled for epoll event-driven architecture; on Windows, it automatically falls back to the select I/O model, ensuring full platform compatibility. Project positioning: underlying infrastructure β complete self-developed RTMP/HTTP-FLV/WS-FLV protocol stack and asynchronous network engine; upper-layer applications such as business management, authentication, and playback management need to be extended and developed by developers. The project supports H.264 decoding + scaling + watermarking + encoding, enabling re-encoding of FLV, MP4, and HLS streams at different bitrates to adapt to various network environments and devices.
Table of Contents
- Requirements
- Quick Start
- Push/Pull Stream Address Specification
- Live & VOD Access Addresses
- Page/Script Usage Guide
- Project Directory Structure
- Overall System Architecture
- Port Constants Configuration
- Recording Task Toggle Configuration
- Multi-Process Worker Configuration (IPC Stream Sync Core)
- Push Stream Authentication Configuration
- FLV Live Distribution Gateway
- Static File HTTP Gateway
- Multi-Method Push/Pull Stream Access Tutorial
- Live Relay Tutorial
- 100K+ Concurrent Cluster Deployment Architecture
- Multi-Bitrate Support
- FAQ
- License
- Companion Toolkit
- Contact
Requirements
| Dependency | Requirement Description |
|---|---|
| PHP | >= 8.1, CLI mode only, FPM not supported |
| sockets extension | Mandatory, provides underlying TCP/WS/RTMP communication |
| event extension | Strongly recommended on Linux for epoll high-concurrency event model; Windows automatically falls back to select when not installed |
Quick deployment: The project includes a
docker-compose.ymlfile β rundocker-compose up -dto start the complete runtime environment with one command.
Quick Start
1. Project Installation
composer create-project xiaosongshu/rtmp_server
2. Start the Origin Server
php server.php
Successful 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
3. Quick Push Stream Test
Method 1: Browser-based Push (No Software Required)
- 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
Method 2: FFmpeg Standard Push
ffmpeg -re -stream_loop -1 -i video.mp4 -c:v libx264 -c:a aac -f flv rtmp://127.0.0.1:1935/live/stream
Method 3: OBS Studio Push
- Server:
rtmp://127.0.0.1:1935/live/ - Stream Key:
stream
Method 4: Built-in PHP Push Client
php pusher.php test.mp4 http://127.0.0.1:8501/live/stream
4. Quick Live Viewing
Browser access: http://127.0.0.1/index.html
Push/Pull Stream Address Specification
Push Stream Addresses (Unified Format for OBS/FFmpeg/PHP/Web)
| Protocol | Standard Format | Example |
|---|---|---|
| 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 may only contain English letters, numbers, and underscores; special characters and Chinese are prohibited.
Live & VOD Access Addresses
Real-Time Live Playback Addresses
| Protocol | Address | 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 |
Low-latency live streaming on PC browsers |
| WebSocket-FLV | ws://127.0.0.1:8501/live/stream.flv |
Native WebSocket MSE playback in browsers |
| HLS-TS | http://127.0.0.1:80/hls/live/stream/index.m3u8 |
Mobile devices, WeChat built-in browser |
| HLS-FMP4 (Mixed A/V) | http://127.0.0.1:80/mp4/live/stream/output_merge/index.m3u8 |
Mainstream desktop browsers, mobile, WeChat built-in browser, ffplay, VLC, etc. |
| HLS-FMP4 (Separate A/V) | http://127.0.0.1:80/mp4/live/stream/output_separate/index.m3u8 |
Mainstream desktop browsers, mobile, WeChat built-in browser, ffplay, VLC, etc. |
Recorded VOD Playback Addresses
Recorded files are persistently stored in the project root directory, automatically generated upon stream end:
| File Type | Storage Path | Access Example |
|---|---|---|
| Standard MP4 file | mp4/live/stream/index.mp4 |
http://127.0.0.1/mp4/live/stream/index.mp4 |
| Raw FLV recording | flv/live/stream/index.flv |
http://127.0.0.1/flv/live/stream/index.flv |
| HLS TS segment dir | hls/live/stream/index.m3u8 |
http://127.0.0.1:80/hls/live/stream/index.m3u8 |
| HLS-FMP4 Mixed A/V | mp4/live/stream/output_merge/index.m3u8 |
http://127.0.0.1:80/mp4/live/stream/output_merge/index.m3u8 |
| HLS-FMP4 Separate A/V | mp4/live/stream/output_separate/index.m3u8 |
http://127.0.0.1:80/mp4/live/stream/output_separate/index.m3u8 |
Note: Standard MP4 files are only automatically generated from FLV recordings when multi-process and FLV recording are both enabled. You can also manually convert FLV to MP4 using the xiaosongshu/flv2mp4 toolkit.
Page/Script Usage Guide
Live/VOD Playback Pages
| Page File | Function | 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 player | http://127.0.0.1/mp4.html |
| video.html | FLV VOD player | http://127.0.0.1/video.html |
| play_merge.html | fMP4 fragmented live/VOD player (native JS) | http://127.0.0.1/play_merge.html |
| mse.html | fMP4 fragmented live/VOD player (hls.js) | http://127.0.0.1/mse.html |
Web Push Pages
| Page File | Function | 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-stream merge 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 |
PHP Built-in Push/Pull Client Scripts
| 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 recording client | php puller.php http://127.0.0.1:8501/live/stream.flv output.flv |
PHP Built-in Relay Client Scripts
| Script | Function | Example Command |
|---|---|---|
| forward.php | Command-line live data relay client | php forward.php ws://127.0.0.1:8501/a/b.flv rtmp://127.0.0.1:1935/c/d |
PHP Built-in Gateway Client Scripts
| Script | Function | Example Command |
|---|---|---|
| fileGateway.php | Command-line file gateway client | php fileGateway.php 0.0.0.0 8100 |
| flvGateway.php | Command-line FLV gateway client | php flvGateway.php 8080 http://127.0.0.1:8501 |
PHP Live Startup Scripts
| Script | Function | Example Command |
|---|---|---|
| server.php | Command-line live service startup | php server.php |
Project Directory Structure
rtmp_server/
βββ config/ # Global config: ports, multi-process, recording, auth
βββ flv/ # FLV raw stream recording storage
βββ mp4/ # fMP4 segments & merged MP4 after stream ends
βββ hls/ # HLS TS segments, m3u8 index files
βββ MediaServer/ # RTMP/FLV/WS-FLV core protocol stack, session management
βββ Root/ # Low-level async I/O, Socket event driver
βββ record/ # Client-side static page assets
βββ server.php # RTMP origin server entry point
βββ flvGateway.php # FLV live distribution gateway
βββ fileGateway.php # HLS/MP4/static resources HTTP gateway
βββ forward.php # Live relay client
βββ pusher.php # PHP push client
βββ puller.php # PHP pull client
βββ encode.php # FLV to HLS multi-bitrate client
βββ watermark.php # Watermark generation tool
βββ *.html # All Web push/pull/playback pages
βββ docker-compose.yml # Docker one-click deployment config
βββ LICENSE # Apache 2.0 license file
Overall System Architecture
γExternal PushersγOBS / FFmpeg / Web
β
RTMP(1935) / HTTP-FLV/WS-FLV(8501) Push Access
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RTMP Origin Server (Stream Production Core) β
β β
β π₯ Push/Pull Access: RTMP / HTTP-FLV / WS-FLV, built-in auth validation β
β π Protocol Transmuxing: Output HTTP-FLV / WS-FLV / HLS / fMP4 / MP4 β
β πΎ Parallel Recording Tasks (non-blocking, independently toggleable) β
β ββββββββββββ¬βββββββββββ¬βββββββββββ β
β βFLV Record βfMP4 Seg. βHLS Seg. β β
β ββββββββββββ΄βββββββββββ΄βββββββββββ β
β π€ Live Output: HTTP-FLV, WS-FLV, HLS live streams β
β π¦ VOD Assets: fMP4 segments cached, merged to MP4 after stream ends β
β π Built-in HTTP static service (port 80): direct page/VOD access, no gateway neededβ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββΌββββββββββββββββββββ
β β β
βΌ βΌ βΌ
HTTP-FLV Live HLS Static Segments fMP4 Static Segments
β β β
βΌ βΌ βΌ
βββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββ
β FLV Gateway β β Static File Gateway Cluster β
β Cluster β β (fileGateway) β
β βββββββββββ β β Hosts: HLS/fMP4/MP4/FLV/web assets β
β βLevel 1 β β β βββββββββ βββββββββ βββββββββ β
β β(port8080)β β β βNode1 β βNode2 β βNode3 β β
β βββββ¬ββββββ β β β(8100) β β(8101) β β(8102) β β
β β β β ββββ¬βββββ ββββ¬βββββ ββββ¬βββββ β
β βββββ΄ββββ β β β β β β
β βΌ βΌ βΌ β β βΌ βΌ βΌ β
β βββ βββ βββ β β ββββββββββββββββββββββββββββββββββββ β
β βSβ βSβ βSβ β β βEnd-user Players β β
β β1β β2β β3β β β βMSE/HLS/ffplay/browsers β β
β ββ¬ββ ββ¬ββ ββ¬ββ β β ββββββββββββββββββββββββββββββββββββ β
β β β β β ββββββββββββββββββββββββββββββββββββββββββββ
β βΌ βΌ βΌ β
β ββββββββββββββ β
β βLive Viewersβ β
β βFLV Players β β
β ββββββββββββββ β
βββββββββββββββββββ
Architecture Details
-
Origin Server (Sole Stream Producer) All external push streams are ingested here, completing protocol parsing, authentication, multi-format transmuxing, and parallel recording. FLV, fMP4, and HLS recording threads are completely isolated and non-blocking. For low-concurrency scenarios, the built-in port 80 static service can be used directly without additional gateways.
-
FLV Live Distribution Gateway No transcoding β pure forwarding with GOP keyframe caching for instant playback. Supports horizontal scaling and multi-level cascading (max 2 levels recommended for production; more levels increase latency). Linux epoll for high concurrency; Windows for testing only. In high-concurrency scenarios, all player pull requests go through the gateway to reduce connection pressure on the origin server.
-
Static File Gateway Cluster Dedicated hosting for HLS, MP4, FLV, and frontend pages to separate read/write operations. Required for large-scale VOD scenarios to prevent the origin from being overwhelmed by file I/O.
-
Integrated Live Toolkit The project supports pure PHP push, pull, and relay clients, as well as web-based push, playback, transcoding, and stream merging. Supports both single-process and multi-process modes, plus the
xiaosongshu/flv2mp4media toolkit.
Concurrency Deployment Recommendations
| Scale | Recommended Setup |
|---|---|
| Low (< 1,000 viewers) | Origin server only (server.php), use built-in ports 80 and 8501, no gateways |
| Medium (1,000 ~ 5,000 viewers) | Origin + single-layer FLV gateway cluster + single-layer static file gateway cluster, with Nginx load balancing |
| High / Large events (>5,000 viewers) | Origin + multi-layer FLV/static gateway clusters with frontend load balancing; for 10k+ events, must use commercial CDN edge distribution β never serve all traffic from a single server |
Port Constants Configuration
Edit config/app.php to adjust global service ports:
/** HTTP-FLV / WebSocket-FLV main service port */ define('BASE_FLV_PORT', 8501); /** RTMP standard port 1935 */ define('BASE_RTMP_PORT', 1935); /** Built-in static web/VOD HTTP port */ define('BASE_WEB_PORT', 80);
Recording Task Toggle Configuration
config/app.php independently controls three recording tasks:
define('FLV_TO_RECORD', true); // Enable raw FLV recording define('FLV_TO_MP4', true); // Enable fMP4 segmentation define('FLV_TO_HLS', true); // Enable HLS TS segmentation
Multi-Process Worker Configuration (IPC Stream Sync Core)
Principle
In PHP CLI multi-process mode, each Worker has isolated memory. When one process receives a push stream, others cannot access it, so IPC (Inter-Process Communication) is required to sync live streams. This project uses a custom TCP Socket-based IPC over traditional methods like shared memory or pipes: it allocates a set of internal communication ports, and the receiving Worker actively forwards the stream data to all other Workers via a built-in TCP client, ensuring full stream data sharing across all processes.
Configuration in config/app.php
/** Master switch: enable multi-process Worker mode */ define('ENABLE_MULTI_PROCESS', true); /** Worker count β recommended not to exceed CPU cores */ define('WORKER_COUNT', 3); /** Starting port for inter-process TCP communication, auto-allocates 8502, 8503... */ define('COPY_PORT_START', 8502);
When multi-process is disabled (
ENABLE_MULTI_PROCESS=false), worker count and IPC port settings are ignored, and the service runs in single-process mode without IPC sync.
Port Load Balancing Rules
- Linux: Supports port reuse β multiple Workers can listen on the same 8501 FLV port. The kernel distributes player connections across Workers automatically.
- Windows: Supports
SO_REUSEADDR, but new TCP connections are always assigned to the first process that bound to 8501, preventing native load balancing. Use Nginx to reverse-proxy internal ports (8502+) for load distribution. - Internal IPC ports are externally accessible for pull requests, useful for manual load balancing on Windows.
Platform Performance Notes
- Linux: epoll I/O model β single process supports thousands of concurrent connections; multi-process makes full use of multi-core CPUs. Production environment preferred.
- Windows: select model has low concurrency limits (~256 connections per process) β for local development only. Do not deploy in production on Windows.
Push Stream Authentication Configuration
Description
Prevents unauthorized streams from overwriting live channels β only push requests with valid stream keys are allowed. Playback pull auth is not currently built-in; developers can implement referer/token validation at the gateway or reverse-proxy layer.
Configuration file config/auth.php:
<?php return [ 'enabled' => false, // Master auth switch 'publish' => [ 'require_auth' => true, // Require key for push streams 'stream_keys' => [ 'live_123456', 'stream_key_abc', ], ], 'global' => [ 'allowed_apps' => ['live'], // Allowed app names 'deny_apps' => [], ], ];
Authenticated Push Address Format
Include key via URL parameter:
- 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"
Security Best Practices
- Replace default keys with random strings of 32+ characters.
- Enable HTTPS/WSS in public environments to prevent plaintext key interception.
- Rotate stream keys periodically to reduce leakage risk.
- Authentication is disabled by default β enable it if needed.
Note: Any changes to the above configs require a service restart to take effect.
FLV Live Distribution Gateway
Overview
Lightweight forwarding service that pulls HTTP-FLV/WS-FLV streams from upstream origin, caches GOP keyframes for instant playback, and supports horizontal scaling and multi-level cascading to share origin load. The gateway supports pulling from HTTP-FLV or WS-FLV sources and uniformly provides both HTTP-FLV and WS-FLV playback addresses.
Startup Commands
# 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 multiple instances 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 (max 2 levels recommended) php flvGateway.php 8080 http://127.0.0.1:8501 # Level 1 php flvGateway.php 8081 http://127.0.0.1:8080 # Level 2 # Linux background silent mode php flvGateway.php 8080 http://127.0.0.1:8501 > /dev/null 2>&1 &
Gateway Playback Address Format
http://gateway_ip:port/{app}/{stream}.flv
ws://gateway_ip:port/{app}/{stream}.flv
Example: http://127.0.0.1:8080/live/stream.flv
Static File HTTP Gateway
Overview
A standalone HTTP service for static resources, hosting HLS, MP4, FLV, and frontend pages. Separates file I/O from live streaming to improve VOD stability under high concurrency.
Startup Commands
# Single instance php fileGateway.php 0.0.0.0 8100 # 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 mode php fileGateway.php 0.0.0.0 8100 > /dev/null 2>&1 &
Nginx Load Balancing Example
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; } }
Resource Access Examples
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/index.mp4
Multi-Method Pull/Push Stream Access Tutorial
RTMP Push
OBS, FFmpeg, and PHP clients all support standard RTMP: rtmp://host:1935/{app}/{stream}
HTTP-FLV Push
Suitable for command-line or automated push: http://host:8501/{app}/{stream}
WebSocket-FLV Push
Native browser push with latency as low as 50ms; use the built-in push.html page.
PHP Pull Script
For server-side backup and cross-server relay:
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.flv
Live Relay Tutorial
This project supports live stream relaying to multiple servers over rtmp/ws-flv/http-flv. See forward.php for details. Example:
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"
This relays 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. You can also relay to any platform supporting RTMP, WS-FLV, or HTTP-FLV.
Engineering Recommendations
pusher.php/puller.php/forward.php can be integrated into custom scripts for automated pull-relay and backup recording, creating a complete PHP live streaming workflow without third-party tools.
100K+ Concurrent Cluster Deployment Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β γLayer 1: Multi-Pusher Layerγ β
β β
β Streamer A (OBS/Web/FFmpeg) Streamer B (OBS/Web/FFmpeg) Streamer N (...) β
β β β β β
β βββββββΌββββββ βββββββΌββββββ βββββββΌββββββ β
β βΌ βΌ βΌ βΌ βΌ βΌ βΌ βΌ βΌ β
β [Node1] [Node2] [Node3] [Node1] [Node2] [Node3] [Node1] [Node2] [Node3] β
β (Push to multiple origin nodes simultaneously for redundancy) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β RTMP/HTTP-FLV/WS-FLV Push Access
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β γLayer 2: Origin Node Cluster (Stream Production)γ β
β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Origin A β β Origin B β β Origin C β β Origin D β β
β β server.php β β server.php β β server.php β β server.php β β
β β (multi-proc)β β (multi-proc)β β (multi-proc)β β (multi-proc)β β
β β rec/seg β β rec/seg β β rec/seg β β rec/seg β β
β βββββββ¬ββββββββ βββββββ¬ββββββββ βββββββ¬ββββββββ βββββββ¬ββββββββ β
β β β β β β
β ββββββββββ¬βββββββββ΄ββββββββββββββββββ΄βββββββββ¬βββββββββ β
β β β β
β ββββββΌβββββ ββββββΌβββββ β
β β forward β β forward β β Auto-sync streams β
β β sync β β sync β β
β ββββββ¬βββββ ββββββ¬βββββ β
β ββββββββββββββββ¬βββββββββββββββββββββ β
β β β
β (All origins back each other up; any failure continues service) β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β forward pulls from origin, pushes to edge
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β γLayer 3: Edge Node Cluster (Distribution & Cache)γ β
β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Edge X β β Edge Y β β Edge Z β β Edge W β β
β β server.php β β server.php β β server.php β β server.php β β
β β (multi-proc)β β (multi-proc)β β (multi-proc)β β (multi-proc)β β
β β rec/seg β β rec/seg β β rec/seg β β rec/seg β β
β βββββββ¬ββββββββ βββββββ¬ββββββββ βββββββ¬ββββββββ βββββββ¬ββββββββ β
β β β β β β
β ββββββββββ¬βββββββββ΄ββββββββββββββββββ΄βββββββββ¬βββββββββ β
β β β β
β ββββββΌβββββ ββββββΌβββββ β
β β forward β β forward β β Pull from origin, cache β
β β sync β β sync β β
β βββββββββββ βββββββββββ β
β β
β β
Any node can be upgraded to origin (accept push) or downgraded to edge (pull only) β
β β
All nodes record independently for multi-copy backup β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββ΄ββββββββββββββ
β β
βΌ βΌ
ββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββ
β γLayer 4: Gatewaysγ β β γLayer 4: Gatewaysγ β
β β β β
β flvGateway Cluster β β fileGateway Cluster β
β βββββββ βββββββ βββββββ β β βββββββ βββββββ βββββββ β
β βG1 β βG2 β βG3 β β β βG1 β βG2 β βG3 β β
β ββββ¬βββ ββββ¬βββ ββββ¬βββ β β ββββ¬βββ ββββ¬βββ ββββ¬βββ β
β β β β β β β β β β
β βββββββββΌββββββββ β β βββββββββΌββββββββ β
β β β β β β
β (HTTP-FLV/WS-FLV) β β (HLS/MP4/FLV/VOD/Static) β
βββββββββββββββΌββββββββββββββ βββββββββββββββΌββββββββββββββ
β β
βββββββββββββββ¬ββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β γLayer 5: Viewersγ β
β β
β PC Browser (MSE/FLV.js) Mobile (HLS) ffplay/Players WebSocket Player β
β β
β β
Viewers connect to nearest edge gateway via DNS/Nginx/GSLB load balancing β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Architecture Design Notes
1. High Availability Push Layer (Disaster Recovery)
- Multi-path push: Streamers push to multiple origin nodes simultaneously; if one fails, others continue serving with zero viewer impact.
- Auto failover: OBS/FFmpeg can configure backup push addresses for primary-backup switching; Web clients can push via JavaScript to multiple destinations.
2. Origin Node Cluster (Stream Production Core)
- Active-active deployment: All origin nodes are active, receive pushes, and sync streams via
forward.php, ensuring each node has a full stream copy. - Auto failover: Any origin failure triggers automatic reconnection of sync links; other nodes continue service without interruption.
- Parallel recording: Each origin node independently records FLV/fMP4/HLS, creating multiple backups to prevent single-point storage loss.
3. Edge Node Cluster (Distribution & Cache)
- Proximity pulling: Edge nodes pull from origin via
forward.phpand cache GOP keyframes for low-latency instant playback. - Elastic scaling: Add or remove edge nodes dynamically based on load.
- Flexible roles: Any node can be promoted to origin (accept pushes) or demoted to edge (pull only) by configuration.
4. Gateway Distribution Layer
- flvGateway Cluster: Dedicated to HTTP-FLV/WS-FLV live streams β no transcoding, pure forwarding with GOP caching for instant playback. Supports cascading and horizontal scaling.
- fileGateway Cluster: Dedicated to HLS segments, MP4 VOD, static pages β isolates file I/O from live streaming.
5. Viewer Clients
- Multi-protocol coverage: RTMP, HTTP-FLV, WS-FLV, HLS β supports all platforms.
- Smart routing: DNS round-robin, Nginx reverse proxy, or GSLB to route viewers to the nearest/lowest-load edge node.
6. Data Flow
- Push: Streamer β (multi-path) β Origin cluster β
forwardsyncs to all origins. - Pull (Edge): Edge β
forwardpulls from origin β caches β serves local viewers. - Playback: Viewer β Load balancer β flvGateway/fileGateway β Edge (or Origin) β stream data.
- Recording: All nodes record per configuration; merged to MP4 for VOD after stream end.
7. Disaster Recovery & Backup
- Node-level: Any node failure triggers automatic reconnection to other live nodes.
- Region-level: If entire data center fails, DNS can switch to a backup site (requires multiple clusters).
- Recording backup: Each node stores recordings independently; for critical streams, multiple nodes can record simultaneously.
8. Scalability & Concurrency
- Horizontal scaling: All layers support adding nodes without restart.
- 100K+ concurrency: Edge nodes + gateways scale horizontally; with CDN edge acceleration, supports 100K+ concurrent viewers (bandwidth and server resources permitting).
- Performance: Linux epoll enables thousands of connections per node (varies by server config); multi-node clusters scale linearly.
9. Deployment Recommendations
- Node-to-node data sync is handled by the built-in
forward.phprelay client. It supports pulling from any RTMP/HTTP-FLV/WS-FLV source and pushing to one or multiple targets, with authentication parameters (e.g., key) supported. Developers can write scheduling scripts based on actual network topology and business needs β integrating health checks, load balancing policies, or business rules β to dynamically configure pull sources, target lists, and forwarding parameters for automated stream sync. Origin/edge role switching also relies on external scheduling logic: monitor node metrics (CPU, memory, active connections, push count, etc.) or external traffic distribution policies to trigger script-based role adjustments for elastic scaling, failover, and disaster recovery. The entire scheduling system can be customized for highly flexible production-grade deployment.
Multi-Bitrate Support
This project provides built-in multi-bitrate transcoding capabilities, supporting the conversion of Baseline Profile FLV files into multi-resolution HLS streams to adapt to different network environments and mobile devices.
β οΈ Performance Notice
- The current multi-bitrate module is implemented in pure PHP and performance is limited. It is intended only for small file offline transcoding or functional verification.
- Due to the computationally intensive nature of H.264 re-encoding, which requires significant processing time, it is strictly prohibited to use this module in production environments for real-time live streaming. For professional adaptive bitrate transcoding, please use mature tools such as FFmpeg.
- This feature depends on the
xiaosongshu/flv2mp4toolkit, which is installed with this project β no additional setup required.
Usage
For detailed configuration, please refer to the encode.php example file. Run the following command to transcode FLV to HLS:
php encode.php
- π Version Requirement: This feature requires
xiaosongshu/flv2mp4version >= 1.4.4. - π The
xiaosongshu/flv2mp4toolkit supports re-encoding for FLV/MP4 and FLV to HLS transcoding, as well as watermark overlay. For more usage, please refer to the toolkit documentation.
Use Cases
| Scenario | Recommended |
|---|---|
| Local testing / functional verification | β Recommended |
| Small file offline transcoding (< 10MB) | β Acceptable |
| Real-time live stream transcoding | β Not recommended |
| High-concurrency / large-scale production | β Strictly prohibited |
Note: This module is for learning and evaluation purposes only. Please do not use it in production environments. For high-performance transcoding solutions, consider using FFmpeg or professional transcoding services.
Watermark Tool
You can use the built-in tool to generate text watermarks. For detailed configuration, please refer to watermark.php. Run the following command to generate a watermark file:
php watermark.php
A sample watermark file watermark_80x16.yuv is already prepared for you.
FAQ
Q1: Missing event extension on Windows?
The event extension is not available on Windows β the service automatically uses the select I/O model. Just install the sockets extension and it will run normally.
Q2: How to confirm the service started successfully?
Successful startup is indicated by three log lines in the terminal: RTMP 1935, FLV 8501, HTTP static 80.
Q3: Push works but playback is laggy/stuttering?
- Push bitrate/resolution is too high β reduce bitrate/framerate for testing.
- Server CPU is maxed out β enable multi-process to use all cores.
- High concurrency without FLV gateway β many player connections are consuming origin resources.
- Insufficient server upstream bandwidth β limit concurrent viewers.
Q4: How to stop the service?
Press Ctrl + C in the terminal to send a termination signal, or simply close the terminal window.
Q5: Which third-party push software is supported?
Fully compatible with all standard RTMP clients: OBS Studio, FFmpeg, xSplit, and mobile RTMP SDKs.
License
This project is released under the Apache License 2.0.
The software is provided "AS IS", without warranty of any kind. The developer assumes no liability for direct, indirect, or consequential damages arising from the use of this software. For full terms, see the LICENSE file in the project root.
Companion Toolkit
The underlying codec and container conversion capabilities have been extracted into a separate toolkit: xiaosongshu/flv2mp4 It provides FLV/MP4/fMP4/HLS interconversion, standalone push/pull clients, and gateway components, and can be used independently in third-party PHP projects.
Contact
- Email: 2723659854@qq.com
- GitHub: https://github.com/2723659854