xiaosongshu / rtmp_server
Native PHP RTMP live server with FLV/HLS, MP4 slicing, PHP client, relay & gateway and webrtc server
Package info
github.com/2723659854/rtmp-server
Language:HTML
Type:project
pkg:composer/xiaosongshu/rtmp_server
Requires
- php: >=8.1
- ext-zlib: *
- apix/log: ^1.2
- evenement/evenement: ^3.0
- react/promise: ^2.9
- xiaosongshu/flv2mp4: ^1.5
- xiaosongshu/webrtc: ^1.0
This package is auto-updated.
Last update: 2026-08-20 04:34:42 UTC
README
π¨π³ δΈζζζ‘£ β’ π¬π§ English Docs
A pure PHP self-developed RTMP live streaming service, zero dependency on third-party streaming media tools like FFmpeg and Nginx, enabling rapid setup of private live streaming platforms out of the box. On Linux, the
eventextension is automatically enabled for epoll event-driven I/O; on Windows, it gracefully degrades to the select I/O model, ensuring full platform compatibility. Project positioning: underlying infrastructure β complete self-developed RTMP/HTTP-FLV/WS-FLV/WEBRTC protocol stacks and asynchronous network engine; business management, authentication, playback, and other upper-layer applications need to be extended by developers. The project supports H.264 decoding + scaling + watermarking + encoding, and can re-encode FLV, MP4, and HLS at different bitrates to adapt to various network environments and devices.
Table of Contents
- Environment Dependencies
- Quick Start
- Push/Pull Stream Address Specification
- Live & VOD Access URLs
- Page/Script Usage Guide
- Project Directory Structure
- System Overall Architecture
- Port Constants Configuration
- Recording Task Switch 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/Forwarding Tutorial
- Cluster Deployment Architecture for 100,000+ Concurrent Users
- Multiβbitrate Support
- WEBRTC
- FAQ
- License
- Companion Toolkits
- Contact
Environment Dependencies
| Dependency | Hard Requirement Description |
|---|---|
| PHP | >= 8.1, CLI mode only, FPM not supported |
| sockets extension | Mandatory β foundation for underlying TCP/WS/RTMP communication |
| event extension | Highly recommended on Linux β enables epoll highβconcurrency event model; on Windows, if missing, it automatically falls back to select |
Quick environment setup: the project includes a
docker-compose.ymlfile; rundocker-compose up -dto spin up the complete runtime environment with one command.
Quick Start
1. Project Installation
composer create-project xiaosongshu/rtmp_server
2. Start the Origin Main Service
php server.php
Example successful startup output:
[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 without additional software
- Realβtime screen push:
http://127.0.0.1/push.html - Loop push of local MP4/FLV files:
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 Playback
Open in browser: http://127.0.0.1/index.html
Push/Pull Stream Address Specification
Push URLs (Unified 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) allow only English letters, digits, and underscores; special characters and Chinese are prohibited.
Live & VOD Access URLs
Realβtime Live Playback URLs
| 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 |
Lowβlatency live 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 (audioβvideo merged segments) | 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 (audioβvideo separate segments) | 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 URLs
Recorded files are persistently stored under the project root; complete files are automatically generated after the live stream ends:
| File Type | Storage Path | Access Example |
|---|---|---|
| Standard transcoded MP4 | 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 directory | hls/live/stream/index.m3u8 |
http://127.0.0.1:80/hls/live/stream/index.m3u8 |
| HLS-FMP4 audioβvideo merged segments | mp4/live/stream/output_merge/index.m3u8 |
http://127.0.0.1:80/mp4/live/stream/output_merge/index.m3u8 |
| HLS-FMP4 audioβvideo separate segments | mp4/live/stream/output_separate/index.m3u8 |
http://127.0.0.1:80/mp4/live/stream/output_separate/index.m3u8 |
- Because long-duration live broadcasts generate large FLV files, directly transcoding them to MP4 may exhaust system memory. The system only automatically processes files smaller than 500 MB.for larger files, please transcode manually.
- Alternatively, you can use the toolkit
xiaosongshu/flv2mp4to manually convert FLV to MP4.
Page/Script Usage Guide
Live/VOD Playback Pages
| Page File | Description | Access URL |
|---|---|---|
| index.html | HTTP-FLV lowβlatency live player | http://127.0.0.1/index.html |
| play.html | HLS mobileβadapted 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 segment live/VOD page (native JS) | http://127.0.0.1/play_merge.html |
| mse.html | fMP4 segment live/VOD page (hls.js) | http://127.0.0.1/mse.html |
Webβbased Push Pages
| Page File | Description | Access URL |
|---|---|---|
| push.html | Browser screen capture push (WS-FLV) | http://127.0.0.1/push.html |
| flv_push.html | Loop push of local MP4/FLV files | http://127.0.0.1/flv_push.html |
| push_merge.html | Multiβstream composition 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 |
Builtβin PHP 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/record client | php puller.php http://127.0.0.1:8501/live/stream.flv output.flv |
Builtβin PHP 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 |
Builtβin PHP 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 Script
| Script | Function | Example Command |
|---|---|---|
| server.php | Start live service from command line | php server.php |
Project Directory Structure
rtmp_server/
βββ config/ # Global config: ports, multiβprocess, recording, push auth
βββ flv/ # Realβtime FLV raw stream recording storage
βββ mp4/ # fMP4 segments & merged complete MP4 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 engine
βββ record/ # Clientβside static page assets
βββ server.php # RTMP origin main service entry
βββ flvGateway.php # FLV live distribution gateway startup script
βββ fileGateway.php # HLS/MP4/static resource 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
βββ webrtc.php # WebRTC startup file
βββ webrtc # WebRTC push/play pages
βββ *.html # All web push/pull/play pages
βββ docker-compose.yml # Docker oneβclick deployment config
βββ LICENSE # Apache 2.0 license file
System Overall Architecture
γExternal Pushersγ OBS / FFmpeg / Web
β
RTMP(1935) / HTTPβFLV/WSβFLV(8501) push ingress
β
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β RTMP Origin Main Service (Stream Production Core) β
β β
β π₯ Push/Pull Access: RTMP / HTTPβFLV / WSβFLV tripleβprotocol compatible, builtβin push auth validation β
β π Protocol Transmuxing: raw stream output to HTTPβFLV / WSβFLV / HLS / fMP4 / MP4 β
β πΎ Parallel Recording Tasks (completely nonβblocking, individually toggleable) β
β ββββββββββββ¬βββββββββββ¬βββββββββββ β
β β FLV raw β fMP4 realβ HLS TS β β
β β recordingββtime segmβ segments β β
β ββββββββββββ΄βββββββββββ΄βββββββββββ β
β π€ Realβtime Stream Output: distributes HTTPβFLV, WSβFLV, HLS live streams β
β π¦ VOD Artifacts: fMP4 segment cache, autoβmerged to complete MP4 after stream ends β
β π Builtβin HTTP static service (port 80): no extra gateway needed for lowβconcurrency scenarios, directly serves pages and VOD files β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββββββββΌββββββββββββββββββββ
β β β
βΌ βΌ βΌ
HTTPβFLV realβtime HLS static segments fMP4 static segments
β β β
βΌ βΌ βΌ
βββββββββββββββ ββββββββββββββββββββββββββββββββββββββββββββ
β FLV Live β β Static File Gateway Cluster β
β Gateway β β (fileGateway) β
β Cluster β β Hosted resources: HLS/fMP4/MP4/FLV/ β
β βββββββββββ β β web static assets β
β βLevel 1 β β β β
β βGateway β β β βββββββββ βββββββββ βββββββββ β
β β(port8080)β β β βGW 1 β βGW 2 β βGW 3 β β
β βββββ¬ββββββ β β β(8100) β β(8101) β β(8102) β β
β β β β ββββ¬βββββ ββββ¬βββββ ββββ¬βββββ β
β βββββ΄ββββ β β β β β β
β βΌ βΌ βΌ β β βΌ βΌ βΌ β
β βββ βββ βββ β β ββββββββββββββββββββββββββββββββββββ β
β βSβ βSβ βSβ β β βEndβuser player clients β β
β βuβ βuβ βuβ β β βMSE/HLS player/ffplay/browser β β
β βbβ βbβ βbβ β β ββββββββββββββββββββββββββββββββββββ β
β ββ¬ββ ββ¬ββ ββ¬ββ β β β
β β β β β ββββββββββββββββββββββββββββββββββββββββββββ
β βΌ βΌ βΌ β
β ββββββββββββββ β
β βLive viewersβ β
β β(FLV player)β β
β ββββββββββββββ β
βββββββββββββββββββ
Architecture Detailed Description
-
Origin Main Service (sole stream producer) All external pushes are ingested by the origin, which handles protocol parsing, authentication, multiβformat transmuxing, and parallel recording; the three recording tasks (FLV recording, fMP4 slicing, HLS slicing) are completely isolated threads that do not block each other. In 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 traffic forwarding and GOP keyβframe caching for instant startup on players; supports horizontal scaling and multiβlevel cascading (recommended at most two levels in production, as 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, reducing connection pressure on the origin main process.
-
Static File Gateway Cluster Dedicated to hosting static resources such as HLS, MP4, FLV, and frontend pages, achieving readβwrite separation; must be deployed for largeβscale VOD scenarios to prevent file I/O from saturating the origin.
-
Integrated Live Tooling The project supports pureβPHP client push, pull, and live relay, and provides webβbased push, playback, transcoding, and stream composition. It supports singleβprocess/multiβprocess switching and the personalised media toolkit
xiaosongshu/flv2mp4.
Deployment Recommendations by Concurrency
| Concurrency Level | Recommended Deployment |
|---|---|
| Low concurrency (< 1000 online viewers) | Only start the origin server.php, using builtβin ports 80 and 8501 β no gateways needed. |
| Medium concurrency (1000 ~ 5000 online) | Origin + singleβlayer FLV gateway cluster + singleβlayer static file gateway cluster, with Nginx load balancing. |
| High concurrency / largeβscale events (>5000 online) | Origin + multiβlayer FLV gateway and static gateway clusters, frontβend load balancing; for 10k+ events, commercial CDN edge distribution is mandatory β do not let a single server handle all traffic. |
Port Constants Configuration
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 port 1935 */ define('BASE_RTMP_PORT', 1935); /** Builtβin static web and VOD file HTTP port */ define('BASE_WEB_PORT', 80);
Recording Task Switch Configuration
config/app.php independently controls three recording tasks without interference:
define('FLV_TO_RECORD', true); // Enable realβtime raw FLV recording define('FLV_TO_MP4', true); // Enable fMP4 segmentation define('FLV_TO_HLS', true); // Enable HLS TS segment generation
Multiβprocess Worker Configuration (IPC Stream Sync Core)
Principle
Under 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, so stream sync via IPC (InterβProcess Communication) is mandatory. This project does not use traditional system IPC like shared memory or pipes. Instead, it implements a custom local TCP Socket IPC scheme: it allocates a set of internal communication ports; the worker that receives the stream actively forwards the complete stream data to all other workers via the builtβin TCP client, achieving fullβprocess stream data sharing.
Configuration in config/app.php
/** Master switch: enable multiβprocess worker mode */ define('ENABLE_MULTI_PROCESS', true); /** Number of worker processes β recommended not to exceed CPU physical cores */ define('WORKER_COUNT', 3); /** Starting port for interβprocess TCP communication, automatically assigned 8502, 8503... */ define('COPY_PORT_START', 8502);
When multiβprocess is disabled (
ENABLE_MULTI_PROCESS=false), the worker count and internal communication port configuration become invalid; the service runs in singleβprocess mode with no IPC stream sync.
Multiβprocess Port Loadβbalancing Rules
- Linux: the system supports port reuse (SO_REUSEPORT), allowing multiple workers to listen on the main FLV port 8501 simultaneously; the kernel automatically distributes player connections among workers.
- Windows: although
SO_REUSEADDRis supported, new TCP connections will only be assigned to the first process that bound to port 8501 β native load balancing is not available; you can use Nginx reverseβproxy to the internal communication ports (8502+) to distribute traffic. - Internal IPC ports are externally accessible for pull streams, useful for manual load balancing on Windows.
Platform Performance Limitations
- Linux: epoll I/O model β a single process can handle thousands of concurrent long connections; multiβprocess can fully utilise multiβcore CPUs β the preferred choice for production.
- Windows: the underlying select model has a very low concurrency limit (about 256 connections per process) β only for local development and debugging; do not deploy in production.
Push Stream Authentication Configuration
Description
Prevents unauthorised streams from overwriting live channels; only push requests carrying a valid stream key are accepted. Playback pull currently has no builtβin authentication; 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, // Enforce stream key validation for push 'stream_keys' => [ 'live_123456', 'stream_key_abc', ], ], 'global' => [ 'allowed_apps' => ['live'], // Allowed application names 'deny_apps' => [], ], ];
Authenticated Push URL Format
Carry the key via the 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"
Security Best Practices
- Replace default keys with random strings of 32+ characters.
- Enable HTTPS/WSS in public deployments to prevent plainβtext key sniffing.
- Rotate stream keys periodically to reduce leakage risk.
- Authentication is disabled by default; enable it if needed.
Note: any change to the above configuration requires a service restart to take effect.
FLV Live Distribution Gateway
Overview
A lightweight traffic forwarding service that pulls HTTPβFLV/WSβFLV streams from the upstream origin, caches GOP keyβframes for instant player startβup; supports horizontal scaling and multiβlevel cascading to offload the origin. The gateway can pull from either 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 with multiple instances on the same level 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 beyond 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 # Run silently in background on Linux php flvGateway.php 8080 http://127.0.0.1:8501 > /dev/null 2>&1 &
Gateway Playback URL 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
An independent static resource HTTP service that hosts HLS, MP4, FLV, and frontend pages, separating file I/O from live streaming to improve stability under highβconcurrency VOD loads.
Startup Commands
# Single instance php fileGateway.php 0.0.0.0 8100 # Multiple instances 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 # Run silently in background on Linux php fileGateway.php 0.0.0.0 8100 > /dev/null 2>&1 &
Nginx LoadβBalancing Reverse Proxy 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 Push/Pull Stream Access Tutorial
RTMP Push
OBS, FFmpeg, and PHP clients all support the standard RTMP protocol. Address format: rtmp://host:1935/{app}/{stream}
HTTPβFLV Push
Suitable for commandβline and automated programmatic push. Address: http://host:8501/{app}/{stream}
WebSocketβFLV Push
Native browser push solution, with latency as low as 50ms. Use the builtβin push.html page.
PHP Pull Script
For serverβside pull 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/Forwarding Tutorial
This project provides live relay functionality, allowing you to forward a live stream to multiple servers, supporting rtmp/wsβflv/httpβflv protocols for both pull and push. For detailed command usage, see forward.php. Example relay 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 stream from 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 push to any other platform that supports RTMP, WSβFLV, or HTTPβFLV.
Engineering Suggestions
pusher.php / puller.php / forward.php can be integrated into custom scripts to automate pullβrelay, backup recording, etc., without relying on thirdβparty tools, completing a full PHP live streaming business loop.
Cluster Deployment Architecture for 100,000+ Concurrent Users
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β γ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] β
β (Simultaneously push to multiple origin nodes for streamerβside disaster recovery)β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β RTMP/HTTPβFLV/WSβFLV push ingress
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β γLayer 2: Origin Node Cluster (Stream Production Core)γ β
β β
β βββββββββββββββ βββββββββββββββ βββββββββββββββ βββββββββββββββ β
β β Origin A β β Origin B β β Origin C β β Origin D β β
β β server.php β β server.php β β server.php β β server.php β β
β β (multiβproc)β β (multiβproc)β β (multiβproc)β β (multiβproc)β β
β β record/sliceβ β record/sliceβ β record/sliceβ β record/sliceβ β
β βββββββ¬ββββββββ βββββββ¬ββββββββ βββββββ¬ββββββββ βββββββ¬ββββββββ β
β β β β β β
β ββββββββββ¬βββββββββ΄ββββββββββββββββββ΄βββββββββ¬βββββββββ β
β β β β
β ββββββΌβββββ ββββββΌβββββ β
β β forward β β forward β β Auto sync live streams (pullβpush) β
β β sync β β sync β β
β ββββββ¬βββββ ββββββ¬βββββ β
β ββββββββββββββββ¬βββββββββββββββββββββ β
β β β
β (All origin nodes back each other up; if any fails, others continue service) β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β forward pulls (from origin nodes, pushes to edge)
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β γLayer 3: Edge Node Cluster (Stream 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)β β
β β record/sliceβ β record/sliceβ β record/sliceβ β record/sliceβ β
β βββββββ¬ββββββββ βββββββ¬ββββββββ βββββββ¬ββββββββ βββββββ¬ββββββββ β
β β β β β β
β ββββββββββ¬βββββββββ΄ββββββββββββββββββ΄βββββββββ¬βββββββββ β
β β β β
β ββββββΌβββββ ββββββΌβββββ β
β β forward β β forward β β Auto pull from origins, cache β
β β sync β β sync β β
β βββββββββββ βββββββββββ β
β β
β β
Dynamic role switching: any node can be promoted to origin (accepting pushes) or demoted to edge at any time. β
β β
All nodes independently record, achieving multiβcopy backup and improving data reliability. β
ββββββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βββββββββββββββ΄ββββββββββββββ
β β
βΌ βΌ
ββββββββββββββββββββββββββββββ ββββββββββββββββββββββββββββββ
β γLayer 4: Gateway Distribution Layerγ β β γLayer 4: Gateway Distribution Layerγ β
β β β β
β flvGateway Cluster β β fileGateway Cluster β
β βββββββ βββββββ βββββββ β β βββββββ βββββββ βββββββ β
β βGW 1 β βGW 2 β βGW 3 β β β βGW 1 β βGW 2 β βGW 3 β β
β ββββ¬βββ ββββ¬βββ ββββ¬βββ β β ββββ¬βββ ββββ¬βββ ββββ¬βββ β
β β β β β β β β β β
β βββββββββΌββββββββ β β βββββββββΌββββββββ β
β β β β β β
β (HTTPβFLV/WSβFLV) β β (HLS/MP4/FLV VOD / static pages)β
βββββββββββββββΌββββββββββββββ βββββββββββββββΌββββββββββββββ
β β
βββββββββββββββ¬ββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β γLayer 5: Viewer Terminalsγ β
β β
β PC browsers (MSE/FLV.js) Mobile (HLS) ffplay/professional players WebSocket players β
β β
β β
Viewers access the nearest edge gateway; load balancing (DNS or Nginx) automatically assigns to the optimal node. β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Core Architecture Design Notes
1. Push Layer High Availability (Disaster Recovery)
- Multiβpath push: Streamers can push simultaneously to multiple origin nodes (e.g., nodes A, B, C); if any node fails, others still hold the stream, and viewers experience no interruption.
- Automatic failover on pusher side: OBS/FFmpeg can be configured with backup push URLs for activeβstandby switching; webβside can use JavaScript to push to multiple paths.
2. Origin Node Cluster (Stream Production Core)
- Activeβactive deployment: All origin nodes are active and can accept pushes; they synchronise stream data with each other via
forward.php, ensuring each origin node holds a complete stream copy. - Automatic failover: If any origin node goes down, others continue to serve, and the relay sync links automatically reconnect β business continues without interruption.
- Parallel recording: Each origin node independently performs FLV/fMP4/HLS recording, creating multiple physical backups to prevent singleβpoint storage loss.
3. Edge Node Cluster (Stream Distribution & Cache)
- Nearestβpull: Edge nodes pull live streams from origin nodes via
forward.php, cache GOP keyβframes, and provide lowβlatency, instantβstart playback to 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 use the same codebase; they can be promoted to origin (accept pushes) or demoted to edge (pullβonly distribution) at any time via configuration, allowing onβdemand resource allocation.
4. Gateway Distribution Layer
- flvGateway cluster: Designed specifically for HTTPβFLV/WSβFLV realβtime streams β no transcoding, pure forwarding, with GOP caching for instant startβup; supports multiβlevel cascading and horizontal scaling to handle massive player connections.
- fileGateway cluster: Independently hosts HLS segments, MP4 VOD files, static pages, etc., separating these from dynamic stream services to prevent file I/O from blocking live services.
5. Viewer Terminals
- Multiβprotocol coverage: Supports RTMP, HTTPβFLV, WSβFLV, HLS, compatible with PC, mobile, Web, and all platforms.
- Smart scheduling: Uses DNS roundβrobin, Nginx reverse proxy, or global load balancing (GSLB) to direct viewer requests to the nearest or leastβloaded edge node, ensuring optimal experience.
6. Data Flow
- Push: Streamer β (multiβpath) β Origin node cluster β
forwardsync to all origin nodes. - Pull (edge): Edge node β
forwardpulls from any origin node β cache β serves local viewers. - Playback: Viewer β load balancer β flvGateway/fileGateway β edge node (or origin) β stream data.
- Recording: All nodes (origin/edge) record according to configuration, eventually merging to MP4 for VOD playback.
7. Disaster Recovery and Backup Mechanisms
- Nodeβlevel disaster recovery: If any single node (origin or edge) fails, the forwarding client automatically reconnects to other live nodes β stream data is not interrupted.
- Regionβlevel disaster recovery: If an entire data centre goes down, DNS can be switched to a backup data centre (requires deploying multiple clusters) for crossβregion high availability.
- Recording backup: Each node stores its own recording files; for important streams, multiple nodes can record simultaneously to ensure data is not lost.
8. Scalability and Concurrency Capability
- Horizontal scaling: All layers support horizontal scaling β adding nodes immediately shares the load without restarting existing services.
- 100k+ concurrency: Edge nodes and gateway layers can scale horizontally on a large scale; combined with CDN edge acceleration, they can support 100,000+ concurrent viewers (bandwidth and server resources must be provisioned accordingly).
- Performance optimisation: driven by the event extension (epoll) on Linux; a single node can handle thousands of longβlived connections (depending on actual server configuration), and multiβnode clusters linearly improve concurrency.
9. Deployment Recommendations
- Stream synchronisation between nodes is accomplished via the builtβin
forward.phprelay client. This tool can pull RTMP/HTTPβFLV/WSβFLV streams from any source and push them to one or multiple target nodes simultaneously, carrying authentication parameters (e.g., key) when pushing. Developers can write scheduling scripts based on actual network topology and business needs (e.g., combining health checks, loadβbalancing strategies, or business rules) to dynamically configure pull source addresses, target node lists, and forwarding parameters, thus achieving automated stream synchronisation between nodes. Role switching between origin and edge nodes also relies on external scheduling logic: it is recommended to monitor node system status (CPU load, memory usage, active connections, number of push streams, etc.) or external traffic allocation policies to trigger scripts that dynamically adjust node roles, enabling elastic scaling, failover, and disaster recovery. The entire scheduling system can be customised according to actual scenarios, providing a highly flexible productionβready deployment solution.
Multiβbitrate Support
This project includes builtβin multiβbitrate transcoding capability, supporting conversion of Baseline Profile FLV files into multiβresolution HLS streams to adapt to different network environments and mobile devices.
β οΈ Performance Limitation Notice
- The current multiβbitrate module is implemented in pure PHP and is performanceβconstrained β suitable only for small offline transcoding or functional validation.
- Since H.264 reβencoding is computeβintensive and timeβconsuming, it is strictly prohibited for use in production live streaming. For professional adaptive bitrate transcoding, please use mature tools like FFmpeg.
- π This feature depends on the
xiaosongshu/flv2mp4toolkit, which is already installed with this project β no extra action is needed.
How to Use
Refer to the example in encode.php for detailed configuration. 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 FLV/MP4 and FLVβtoβHLS reβencoding with watermarking. For more usage, refer to its documentation.
Applicable Scenarios
| Scenario | Recommended |
|---|---|
| Local testing / functional validation | β Recommended |
| Small offline file transcoding (< 10 MB) | β Usable |
| Realβtime live stream transcoding | β Not recommended |
| Highβconcurrency / largeβscale production | β Strictly prohibited |
Note: This module is for learning and communication only β do not use in production. For highβperformance transcoding, consider using FFmpeg or specialised transcoding services.
Watermark Tool
You can use the builtβin tool to generate a text watermark. See watermark.php for detailed configuration. Generate a watermark file with:
php watermark.php
The system already provides a sample watermark file watermark_80x16.
WEBRTC
This project includes a builtβin standalone WebRTC service based on pure PHP, implementing WHIP (WebRTC HTTP Ingest Protocol) push and WHEP (WebRTC HTTP Egress Protocol) pull, supporting zeroβplugin, ultraβlowβlatency (<500ms) realβtime audio/video transmission in browsers. It also provides DataChannel chat functionality for live interaction, messaging, etc.
| Access Method | Use Case | Protocol | DataChannel Support |
|---|---|---|---|
| WebSocket signaling | Builtβin pages (push.html / play.html / index.html) |
Custom JSON signaling + SRTP | β Yes |
| Standard WHIP/WHEP | Thirdβparty clients (OBS, FFmpeg, etc.) and whip.html / whep.html |
HTTP POST + SDP | β No |
β οΈ Note: The WebRTC service and the RTMP main service are independent of each other and must be started as separate processes. Once the WebRTC service is started, it will automatically feed live data into the RTMP server. You can then directly pull the stream from the RTMP server for viewing, as well as utilize automatic screen recording and transcoding.
Features
| Feature | Description |
|---|---|
| WebSocket signaling push | Provides webrtc/push.html, uses WebSocket signaling + SRTP media, supports DataChannel chat |
| WebSocket signaling pull | Provides webrtc/play.html, uses WebSocket signaling + SRTP media, supports DataChannel chat |
| DataChannel testing | Provides webrtc/index.html for standalone DataChannel communication testing |
| Standard WHIP push | Supports standard WHIP (HTTP POST), compatible with thirdβparty clients; provides whip.html test page |
| Standard WHEP pull | Supports standard WHEP (HTTP POST), compatible with thirdβparty players; provides whep.html test page |
| Transport protocol | SRTP/SRTCP over UDP, low latency, packetβloss resilient |
| Audio/Video codecs | Video H.264, audio Opus (natively supported by browsers) |
| Signaling service | Builtβin WebSocket signaling server (for WS method) and WHIP/WHEP HTTP endpoints (for standard protocols) |
| Independent deployment | Isolated ports from RTMP main service, lightweight resource usage, can be started/stopped independently |
Starting the Service
In the project root, run:
php webrtc.php
Successful startup example:
WebSocket signaling server listening on ws://0.0.0.0:8088/
UDP media server listening on udp://0.0.0.0:8089
STUN server listening on udp://0.0.0.0:3478
Run silently in background (Linux):
nohup php webrtc.php > /dev/null 2>&1 &
Service Ports and Configuration
WebRTC uses independent port constants defined in config/app.php:
/** WebSocket signaling service port (for SDP/ICE exchange) */ define('WS_PORT', 8088); /** WebRTC media transport UDP port */ define('UDP_PORT', 8089); /** STUN service port (for NAT traversal) */ define('STUN_PORT', 3478); /** Public IP address (keep 127.0.0.1 for internal testing; set to actual public IP for public deployment) */ define('PUBLIC_IP', '127.0.0.1');
Important:
- For public deployment, you must set
PUBLIC_IPto the server's public IP; otherwise clients cannot connect correctly.- Ensure firewall allows
WS_PORT(TCP) andUDP_PORT(UDP), otherwise media transport fails.- If clients and server are on the same private network, you can use the private IP or
127.0.0.1for testing.
Push Guide
(The following uses local testing; for production, replace with public addresses. The WS signaling server automatically handles WebRTCβrelated HTTP requests on the default port 8088.)
1. Browser Screen Push (Recommended)
Visit builtβin page: http://{server_ip}:8088/push.html
Steps:
- Enter the signaling address (default
ws://127.0.0.1:8088) and a room ID (e.g.,stream_001). - Click "Start Push"; the browser will pop up a screen/desktop selection window; choose the screen or tab to share, and check "Share audio" if system audio is needed.
- After successful push, the page shows a local preview and prints
β ζ¨ζ΅δΈ(or its English equivalent, but the page itself may be in Chinese).
2. WHIP Standard Client Push
If using a thirdβparty WHIP client (e.g., OBS WebRTC plugin, FFmpeg WHIP output), the push address is:
http://127.0.0.1:8088/whip/stream_001
Refer to the respective client documentation for configuration. The builtβin whip.html page at http://{server_ip}:8088/whip.html can also be used.
3. DataChannel Chat Integration
In the push page (push.html), after connection is established, a DataChannel is automatically created. You can send messages in the chat box at the bottom; messages will be forwarded by the server to all clients in the same room.
Playback Guide
1. Browser Lowβlatency Pull
Visit builtβin page: http://{server_ip}:8088/play.html
Steps:
- Enter the signaling address (default
ws://127.0.0.1:8088) and the room ID (must match the pusher). - Click "Start Watching"; the page automatically initiates a WHEP pull request.
- After successful pull, the video renders automatically and displays playback statistics (bitrate, packet loss, etc.).
2. Generic WHEP Client
Any WHEPβcompatible player can use the address:
http://127.0.0.1:8088/whep/stream_001
The builtβin whep.html page at http://{server_ip}:8088/whep.html can also be used.
3. DataChannel Chat Interaction
In the playback page (play.html), after connection is established, a DataChannel is automatically created. You can send messages in the chat box at the bottom; messages will be forwarded by the server to all clients in the same room.
Advanced Configuration and Tuning
1. Multiβprocess Support
The WebRTC service currently does not have builtβin multiβprocess load balancing, but you can start multiple instances on different ports and use Nginx reverse proxy for horizontal scaling (pay attention to UDP port allocation).
2. Public Deployment Considerations
- Public IP setting: Ensure
PUBLIC_IPinconfig/app.phpis set to the actual public IP; otherwise, the generated SDP will contain an internal IP, causing connection failures. - Firewall: Open TCP port (WS_PORT) and the UDP port .
- STUN server: This project includes a simple builtβin STUN service that only supports basic NAT type detection. If clients are behind symmetric NAT, consider configuring a public TURN server (requires custom extension).
Related Pages and Scripts
| File | Function | Access / Usage |
|---|---|---|
webrtc/push.html |
Browser screen push (with DataChannel) | http://127.0.0.1:8088/push.html |
webrtc/play.html |
Browser lowβlatency pull (with DataChannel) | http://127.0.0.1:8088/play.html |
webrtc/whep.html |
Browser WHEP pull player | http://127.0.0.1:8088/whep.html |
webrtc/whip.html |
WHIP push test page (video only) | http://127.0.0.1:8088/whip.html |
webrtc/index.html |
DataChannel chat lobby | http://127.0.0.1:8088/index.html |
webrtc.php |
WebRTC service startup script | php webrtc.php |
FAQ
Q1: What to do if Windows says the event extension is missing?
Windows does not have the event extension; the service automatically switches to the select I/O model. Only the sockets extension is required β no extra handling is needed.
Q2: How to verify the service started successfully?
The terminal prints three listening logs: RTMP 1935, FLV 8501, and static port 80 β success.
Q3: Push succeeds but playback stutters continuously?
- The push bitrate or resolution is too high β lower them and test again.
- The server CPU is saturated β enable multiβprocess to utilise multiple cores.
- Under high concurrency, the FLV gateway is not deployed β too many player connections consume origin resources.
- Insufficient server upstream bandwidth β limit the number of 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 standard RTMP clients: OBS Studio, FFmpeg, xSplit, mobile RTMP SDKs.
Q6: How do the WebRTC and RTMP main services work together?
They are completely independent and do not affect each other. You can start or stop either service as needed, allowing both RTMP and WebRTC protocol stacks to coexist.
License
This project is licensed under the Apache License 2.0.
The software is provided "as is", without warranty of any kind, express or implied. The developer shall not be 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.
Companion Toolkits
The underlying codec and stream format conversion capabilities are independently packaged as xiaosongshu/flv2mp4. It provides FLV/MP4/fMP4/HLS interβconversion, standalone push/pull clients, and gateway components, and can be integrated into thirdβparty PHP projects.
Contact
- Email: 2723659854@qq.com
- GitHub: https://github.com/2723659854