<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: 2723659854</title>
    <description>The latest articles on DEV Community by 2723659854 (@2723659854).</description>
    <link>https://dev.to/2723659854</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3952685%2Fab75976c-201d-44f7-98c2-4ad2d7f4d224.png</url>
      <title>DEV Community: 2723659854</title>
      <link>https://dev.to/2723659854</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/2723659854"/>
    <language>en</language>
    <item>
      <title>Pure PHP RTMP Server &amp; FLV2MP4: No FFmpeg</title>
      <dc:creator>2723659854</dc:creator>
      <pubDate>Fri, 12 Jun 2026 08:41:53 +0000</pubDate>
      <link>https://dev.to/2723659854/pure-php-rtmp-server-flv2mp4-no-ffmpeg-4i8d</link>
      <guid>https://dev.to/2723659854/pure-php-rtmp-server-flv2mp4-no-ffmpeg-4i8d</guid>
      <description>&lt;h1&gt;
  
  
  RTMP Server
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;A lightweight RTMP live streaming server written in pure PHP, with &lt;strong&gt;no third-party streaming service dependencies&lt;/strong&gt;. Deploy your private live streaming platform out of the box.&lt;br&gt;
&lt;strong&gt;Automatically enables epoll event-driven I/O on Linux, easily handling 20,000+ concurrent connections in a single process. Falls back to select mode on Windows for compatibility.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🏗️ System Architecture
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                                                    【Publishing】OBS/FFmpeg
                                                         │
                                       RTMP Push(1935)  /  HTTP-FLV Push(8501)
                                                         │
                                                         ▼
╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                      RTMP Origin Server (Core)                                                   ║
║                                                                                                                                    ║
║  📥 Stream Ingest   RTMP / HTTP-FLV dual-protocol publishing, link authentication                                                 ║
║  🔄 Protocol Conv   RTMP / HTTP-FLV → HTTP-FLV / WebSocket-FLV / HLS / fMP4 / MP4                                                  ║
║  💾 Live Recording  ┌──────────────┬──────────────┬──────────────┐                                                                  ║
║                     │  FLV Record  │  fMP4 Segs   │  HLS Segs    │  Three independent parallel tasks                                ║
║                     │  (real-time) │  (real-time) │  (real-time) │                                                                    ║
║                     └──────────────┴──────────────┴──────────────┘                                                                  ║
║  📤 Live Output     HTTP-FLV(8501) / WebSocket-FLV / HLS Live / fMP4 Live                                                          ║
║  📦 VOD Production  fMP4 segments generated in real-time → auto-merged into complete MP4 after stream ends                          ║
║  📁 Static Serving  Origin server built-in HTTP service (port 80), direct static file access (for low-concurrency scenarios)        ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
│
┌───────────────────────┼───────────────────────┐
│                       │                       │
▼                       ▼                       ▼
HTTP-FLV(8501)          HLS(TS/m3u8)           fMP4(segments)
Real-time Stream        Static Files            Static Files
│                       │                       │
│                       │                       │
▼                       ▼                       ▼
┌─────────────────┐     ┌─────────────────────────────────────────────────┐
│  FLV Gateway    │     │            Static File Gateway Cluster           │
│    Cluster      │     │         🎯 Hosting: HLS / fMP4 / MP4 / FLV / Web│
│                 │     │                                                 │
│  ┌───────────┐  │     │  ┌───────────┐  ┌───────────┐  ┌───────────┐   │
│  │  Tier 1   │  │     │  │  Node 1   │  │  Node 2   │  │  Node 3   │   │
│  │  (8080)   │  │     │  │  (8100)   │  │  (8101)   │  │  (8102)   │   │
│  └─────┬─────┘  │     │  └─────┬─────┘  └─────┬─────┘  └─────┬─────┘   │
│        │        │     │        │              │              │         │
│  ┌─────┴─────┐  │     │        ▼              ▼              ▼         │
│  ▼     ▼     ▼  │     │   ┌──────────────────────────────────────┐    │
│ ┌───┐ ┌───┐ ┌───┐│     │   │              Clients               │    │
│ │Sub│ │Sub│ │Sub││     │   │   HLS Player / MSE Player / VOD / ffplay │    │
│ │GW │ │GW │ │GW ││     │   └──────────────────────────────────────┘    │
│ └─┬─┘ └─┬─┘ └─┬─┘│     │                                                 │
│   │     │     │  │     └─────────────────────────────────────────────────┘
│   ▼     ▼     ▼  │
│ ┌──────────────┐ │
│ │   Clients    │ │
│ │ FLV Player / ffplay │
│ └──────────────┘ │
└─────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Architecture Overview
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Origin Server&lt;/strong&gt;: The sole stream production node, supporting &lt;strong&gt;RTMP and HTTP-FLV dual-protocol publishing&lt;/strong&gt;. Handles ingest, multi-protocol repackaging. &lt;strong&gt;FLV recording, fMP4 segmentation, and HLS segmentation run as three fully independent parallel tasks&lt;/strong&gt; with zero blocking.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Origin Static Capability&lt;/strong&gt;: The origin server includes a built-in HTTP service (default port 80) for direct static file access. &lt;strong&gt;No additional gateway deployment needed for low-concurrency scenarios&lt;/strong&gt; — ready to use out of the box.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Live Recording Mechanism&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FLV Recording&lt;/strong&gt;: Saves raw streams in real-time, producing a complete FLV file after the stream ends&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fMP4 Segmentation&lt;/strong&gt;: Generates audio/video fMP4 segments in real-time (supports both merged and separate segment formats), auto-merged into a complete MP4 after the stream ends&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HLS Segmentation&lt;/strong&gt;: Generates TS segments + m3u8 index in real-time (mobile compatible)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Independent Toggles&lt;/strong&gt;: Each recording task can be independently enabled/disabled in &lt;code&gt;server.php&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;FLV Live Gateway Cluster&lt;/strong&gt;: A pure stream relay service. Pulls HTTP-FLV streams from upstream, caches GOP keyframes for instant playback on new connections, and distributes to end clients or downstream gateways.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unlimited Cascade&lt;/strong&gt;: Tier 1 → Tier 2 → Tier 3 → ... → Clients&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Horizontal Scaling&lt;/strong&gt;: Deploy multiple gateway instances at the same tier, distribute traffic via load balancing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux epoll High Performance&lt;/strong&gt;: Single process handles 20,000+ concurrent connections, Windows falls back to select model&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Static File Gateway Cluster (Recommended)&lt;/strong&gt;: Lightweight HTTP static file server, unified hosting for all static resources.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Supported Protocols&lt;/strong&gt;: HLS (.m3u8/.ts), fMP4 (.m4s/.mp4), MP4 VOD files, FLV recording files, Web player pages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Horizontal Scaling&lt;/strong&gt;: Deploy multiple gateway instances at the same tier, linearly increasing concurrency capacity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vertical Scaling&lt;/strong&gt;: Multi-tier traffic distribution via reverse proxies such as Nginx&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux epoll High Performance&lt;/strong&gt;: Single process handles 20,000+ concurrent connections, Windows falls back to select model&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Best Practice&lt;/strong&gt;: Point HLS/fMP4/MP4 playback paths to this gateway cluster for static resource read-write separation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deployment Recommendations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Low Concurrency&lt;/strong&gt; (&amp;lt; 500 concurrent): Use the origin server's built-in HTTP service directly, no additional gateways needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Medium Concurrency&lt;/strong&gt; (500 – 5,000 concurrent):&lt;/li&gt;
&lt;li&gt;Origin + single-tier gateway cluster (FLV Gateway or Static File Gateway)&lt;/li&gt;
&lt;li&gt;A single gateway process is usually sufficient, no multi-instance needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High Concurrency&lt;/strong&gt; (&amp;gt; 5,000 concurrent):&lt;/li&gt;
&lt;li&gt;Origin focuses on "publishing, protocol conversion, live recording"&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FLV Gateway Multi-tier Cluster&lt;/strong&gt;: Tier 1 → Tier 2 → Clients&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static File Gateway Multi-tier Cluster&lt;/strong&gt;: Tier 1 → Tier 2 → Clients&lt;/li&gt;
&lt;li&gt;Each tier supports horizontal scaling, linearly increasing concurrency capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✨ Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🎥 &lt;strong&gt;Dual-Protocol Publishing&lt;/strong&gt;: Full implementation of standard RTMP push/pull + HTTP-FLV push/pull, compatible with mainstream streaming tools&lt;/li&gt;
&lt;li&gt;📡 &lt;strong&gt;HTTP-FLV / WebSocket-FLV&lt;/strong&gt;: Low-latency browser streaming solution, supports direct playback via ffplay and other players&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;HLS Auto-Segmentation&lt;/strong&gt;: Real-time m3u8 + TS generation, full platform mobile compatibility&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;fMP4 Real-time Segmentation + Auto-Merge&lt;/strong&gt;: Generates fMP4 segments in real-time during live streaming, auto-merged into complete MP4 after stream ends&lt;/li&gt;
&lt;li&gt;🎬 &lt;strong&gt;Dual fMP4 Format Support&lt;/strong&gt;: Supports both merged audio/video segments and separate audio/video segments&lt;/li&gt;
&lt;li&gt;💾 &lt;strong&gt;FLV Independent Recording&lt;/strong&gt;: Saves raw FLV streams in real-time, decoupled from fMP4/MP4&lt;/li&gt;
&lt;li&gt;🎛️ &lt;strong&gt;Independent Task Toggles&lt;/strong&gt;: FLV recording, fMP4 segmentation, and HLS segmentation can each be independently enabled/disabled&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Built-in Multiple Web Players&lt;/strong&gt;: Ready to use out of the box, supports FLV/HLS/MP4/Merged fMP4/Separate fMP4 playback&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Cascading FLV Streaming Gateway&lt;/strong&gt;: Unlimited tier relay, GOP-cached instant startup, auto-reconnect on stream loss, designed for high-concurrency live scenarios&lt;/li&gt;
&lt;li&gt;📁 &lt;strong&gt;Static File Gateway&lt;/strong&gt;: Unified hosting for HLS/fMP4/MP4 recorded resources and playback pages, designed for high-concurrency VOD scenarios&lt;/li&gt;
&lt;li&gt;🎞️ &lt;strong&gt;Cross-Platform Playback Compatibility&lt;/strong&gt;: Supports ffplay, VLC, browsers, mobile players, and other mainstream playback terminals&lt;/li&gt;
&lt;li&gt;🐳 &lt;strong&gt;Docker One-Click Deployment&lt;/strong&gt;: Quickly spin up a test environment&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Native Pure PHP Implementation&lt;/strong&gt;: No third-party streaming software dependencies&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📋 Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PHP &amp;gt;= 8.1 (CLI mode only)&lt;/li&gt;
&lt;li&gt;Required extension: &lt;code&gt;sockets&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Recommended extension: &lt;code&gt;event&lt;/code&gt; (significantly improves concurrency on Linux by automatically enabling epoll)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Quick Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project xiaosongshu/rtmp_server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Configure Recording Toggles (&lt;code&gt;server.php&lt;/code&gt;)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Three independent recording task toggles, enable/disable as needed&lt;/span&gt;
&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'FLV_TO_RECORD'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// Enable real-time FLV raw file recording&lt;/span&gt;
&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'FLV_TO_MP4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// Enable real-time fMP4 segmentation and MP4 merging&lt;/span&gt;
&lt;span class="nb"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'FLV_TO_HLS'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;      &lt;span class="c1"&gt;// Enable real-time HLS (TS) segmentation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Start Origin Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php server.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Access Playback (use origin directly for low-concurrency scenarios)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Player page access (origin built-in HTTP service)&lt;/span&gt;
http://127.0.0.1/index.html      &lt;span class="c"&gt;# FLV live page&lt;/span&gt;
http://127.0.0.1/play.html       &lt;span class="c"&gt;# HLS live page&lt;/span&gt;
http://127.0.0.1/mp4.html        &lt;span class="c"&gt;# MP4 VOD page&lt;/span&gt;
http://127.0.0.1/play_merge.html &lt;span class="c"&gt;# fMP4 segment VOD page (supports merged/separate formats)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Medium/High Concurrency: Deploy Static File Gateway Cluster (Recommended)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Use Case&lt;/strong&gt;: High-concurrency access for HLS(.ts/.m3u8), fMP4(.m4s/.mp4), MP4 VOD files, and Web pages.&lt;br&gt;
A single gateway process on Linux handles 20,000+ connections. For higher loads, scale horizontally with multiple instances.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start single instance (handles high concurrency directly under epoll)&lt;/span&gt;
php fileGateway.php 0.0.0.0 8100

&lt;span class="c"&gt;# 【Horizontal Scaling】Multi-instance deployment (for extreme concurrency or multi-server load balancing)&lt;/span&gt;
php fileGateway.php 0.0.0.0 8100
php fileGateway.php 0.0.0.0 8101
php fileGateway.php 0.0.0.0 8102

&lt;span class="c"&gt;# Linux/macOS background running&lt;/span&gt;
php fileGateway.php 0.0.0.0 8100 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;

&lt;span class="c"&gt;# Vertical Scaling: Multi-tier distribution via Nginx reverse proxy&lt;/span&gt;
&lt;span class="c"&gt;# Tier 1 Nginx -&amp;gt; Tier 2 fileGateway (8100/8101/8102) -&amp;gt; Tier 3 fileGateway ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access examples (via Static File Gateway):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8100/play.html       # Access HLS player page via gateway
http://127.0.0.1:8100/hls/live/stream/index.m3u8  # Access HLS stream via gateway
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Medium/High Concurrency: Deploy FLV Live Gateway Cluster
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;A single FLV gateway process on Linux stably supports nearly 20,000 concurrent viewers.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Tier 1 Gateway: Pull from origin&lt;/span&gt;
php flvGateway.php 8080 http://ORIGIN_IP:8501

&lt;span class="c"&gt;# Horizontal Scaling: Deploy multiple instances at the same tier&lt;/span&gt;
php flvGateway.php 8081 http://ORIGIN_IP:8501
php flvGateway.php 8082 http://ORIGIN_IP:8501

&lt;span class="c"&gt;# Vertical Scaling: Multi-tier cascade&lt;/span&gt;
php flvGateway.php 8080 http://ORIGIN_IP:8501      &lt;span class="c"&gt;# Tier 1&lt;/span&gt;
php flvGateway.php 8081 http://127.0.0.1:8080       &lt;span class="c"&gt;# Tier 2 (pulls from Tier 1)&lt;/span&gt;
php flvGateway.php 8082 http://127.0.0.1:8081       &lt;span class="c"&gt;# Tier 3 (pulls from Tier 2)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7. Stop Service
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;OS&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl + C&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux/macOS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;kill -9 PID&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🔧 Port Configuration (Modify in &lt;code&gt;server.php&lt;/code&gt;)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1935&lt;/td&gt;
&lt;td&gt;RTMP&lt;/td&gt;
&lt;td&gt;RTMP publishing and playback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8501&lt;/td&gt;
&lt;td&gt;HTTP/WebSocket&lt;/td&gt;
&lt;td&gt;HTTP-FLV publishing/playback / WS-FLV live streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;Static file service + Web player pages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🚀 FLV Streaming Gateway (High-Concurrency Live Distribution)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gateway Introduction
&lt;/h3&gt;

&lt;p&gt;A lightweight stream distribution component supporting unlimited cascade deployment. Pulls HTTP-FLV from upstream origin/gateway, caches stream headers and GOP keyframes for instant startup on new connections, and replicates stream data to downstream clients or sub-gateways. &lt;strong&gt;Designed for medium to high-concurrency live scenarios&lt;/strong&gt;, supports both horizontal and vertical scaling.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gateway Core Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📡 Multi-stream concurrent relay in a single instance, handling different channel distributions simultaneously&lt;/li&gt;
&lt;li&gt;🔄 Unlimited cascade, Tier 1 → Tier 2 → Tier 3 chained expansion&lt;/li&gt;
&lt;li&gt;⚡ GOP pre-caching, no keyframe wait for new connections, instant playback&lt;/li&gt;
&lt;li&gt;🔁 Automatic reconnection on upstream stream loss, transparent to end users&lt;/li&gt;
&lt;li&gt;📊 Built-in runtime statistics, outputs viewer count and traffic every 10 seconds&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Horizontal Scaling&lt;/strong&gt;: Add gateway processes/instances at the same tier, linearly increasing concurrency&lt;/li&gt;
&lt;li&gt;🚀 &lt;strong&gt;Vertical Scaling&lt;/strong&gt;: Multi-tier cascade, distributing single-point pressure&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Adaptive I/O&lt;/strong&gt;: Linux auto-enables epoll, single process 20,000+ concurrent; Windows falls back to select for compatibility&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  FLV Gateway Startup Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 【Horizontal Scaling】Single tier, multiple instances&lt;/span&gt;
php flvGateway.php 8080 http://ORIGIN_IP:8501
php flvGateway.php 8081 http://ORIGIN_IP:8501
php flvGateway.php 8082 http://ORIGIN_IP:8501

&lt;span class="c"&gt;# 【Vertical Scaling】Multi-tier cascade&lt;/span&gt;
php flvGateway.php 8080 http://ORIGIN_IP:8501      &lt;span class="c"&gt;# Tier 1&lt;/span&gt;
php flvGateway.php 8081 http://127.0.0.1:8080       &lt;span class="c"&gt;# Tier 2&lt;/span&gt;
php flvGateway.php 8082 http://127.0.0.1:8081       &lt;span class="c"&gt;# Tier 3&lt;/span&gt;

&lt;span class="c"&gt;# 【Combined Scaling】Multi-tier + multi-instance per tier&lt;/span&gt;
&lt;span class="c"&gt;# Tier 1 Gateway Cluster&lt;/span&gt;
php flvGateway.php 8080 http://ORIGIN_IP:8501
php flvGateway.php 8081 http://ORIGIN_IP:8501
&lt;span class="c"&gt;# Tier 2 Gateway Cluster (pulls from Tier 1)&lt;/span&gt;
php flvGateway.php 8180 http://127.0.0.1:8080
php flvGateway.php 8181 http://127.0.0.1:8081
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Gateway Playback URL Format
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://GATEWAY_IP:PORT/{app}/{channel}.flv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Tier 1 Gateway
http://127.0.0.1:8080/live/stream.flv
# Tier 2 Gateway
http://127.0.0.1:8081/live/stream.flv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Debug Logging
&lt;/h3&gt;

&lt;p&gt;Add &lt;code&gt;$gateway-&amp;gt;debug = true;&lt;/code&gt; in the gateway startup script to enable full detailed runtime logs.&lt;/p&gt;

&lt;h2&gt;
  
  
  📁 Static File Gateway &lt;code&gt;fileGateway.php&lt;/code&gt; (High-Concurrency VOD Resource Hosting)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Gateway Introduction
&lt;/h3&gt;

&lt;p&gt;A lightweight HTTP static file server for unified hosting of all static resources. &lt;strong&gt;This is the recommended playback method for file-based protocols such as HLS, fMP4, and MP4&lt;/strong&gt;. Supports horizontal and vertical scaling to handle large-scale VOD concurrency.&lt;/p&gt;

&lt;h3&gt;
  
  
  Core Capabilities
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;📁 Unified hosting for all static resources (recorded files + playback pages)&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Horizontal Scaling&lt;/strong&gt;: Multi-instance deployment with load-balanced traffic distribution&lt;/li&gt;
&lt;li&gt;🔗 &lt;strong&gt;Vertical Scaling&lt;/strong&gt;: Multi-tier cascade (e.g., Nginx + fileGateway + backend storage)&lt;/li&gt;
&lt;li&gt;📊 Built-in access logs for statistical analysis&lt;/li&gt;
&lt;li&gt;🚀 Pure PHP implementation, lightweight with no dependencies&lt;/li&gt;
&lt;li&gt;🧠 &lt;strong&gt;Adaptive I/O&lt;/strong&gt;: Linux epoll, single process 20,000+ concurrent; Windows select compatible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;💡 Best Practice&lt;/strong&gt;: Point HLS/fMP4/MP4 playback paths to this gateway cluster, letting the origin server focus solely on writing files — achieving read-write separation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Startup Commands (Multi-process/Multi-instance Distribution)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Basic startup (host current directory, port 8100)&lt;/span&gt;
php fileGateway.php 0.0.0.0 8100

&lt;span class="c"&gt;# 【Horizontal Scaling】Multi-instance deployment&lt;/span&gt;
php fileGateway.php 0.0.0.0 8100
php fileGateway.php 0.0.0.0 8101
php fileGateway.php 0.0.0.0 8102

&lt;span class="c"&gt;# Linux/macOS background multi-instance&lt;/span&gt;
php fileGateway.php 0.0.0.0 8100 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
php fileGateway.php 0.0.0.0 8101 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
php fileGateway.php 0.0.0.0 8102 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Nginx Reverse Proxy Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;filegateway_cluster&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;# Horizontal Scaling: multiple fileGateway instances&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8101&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;127.0.0.1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8102&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;media.example.com&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="p"&gt;~&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s"&gt;.(m3u8|ts|mp4|m4s|flv|html|css|js)&lt;/span&gt;$ &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://filegateway_cluster&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Access URL Format
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://GATEWAY_IP:PORT/{relative_file_path}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Web player pages (accessed via static gateway)
http://127.0.0.1:8100/index.html      # FLV live page
http://127.0.0.1:8100/play.html       # HLS live page
http://127.0.0.1:8100/mp4.html        # MP4 VOD page
http://127.0.0.1:8100/video.html      # FLV VOD page
http://127.0.0.1:8100/play_merge.html # fMP4 segment VOD page

# Recorded resource access
http://127.0.0.1:8100/hls/live/stream/index.m3u8
http://127.0.0.1:8100/mp4/live/stream/output_merge/init.mp4
http://127.0.0.1:8100/mp4/live/stream/output_merge/stream_full.mp4
http://127.0.0.1:8100/flv/live/stream/20240101_120000.flv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📡 Publishing Guide
&lt;/h2&gt;

&lt;p&gt;The project supports both &lt;strong&gt;RTMP&lt;/strong&gt; and &lt;strong&gt;HTTP-FLV&lt;/strong&gt; mainstream publishing protocols, compatible with OBS, FFmpeg, and various streaming tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. RTMP Publishing
&lt;/h3&gt;

&lt;h4&gt;
  
  
  URL Format
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rtmp://127.0.0.1:1935/{app}/{channel}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app&lt;/code&gt;: e.g., &lt;code&gt;live&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;channel&lt;/code&gt;: e.g., &lt;code&gt;stream&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Only alphanumeric characters supported&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Publishing Examples
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;OBS Studio&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download and install &lt;a href="https://obsproject.com/" rel="noopener noreferrer"&gt;OBS Studio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Settings → Stream → Server: &lt;code&gt;rtmp://127.0.0.1:1935/live&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stream Key: &lt;code&gt;stream&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Start Streaming&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;FFmpeg Loop Publishing&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-re&lt;/span&gt; &lt;span class="nt"&gt;-stream_loop&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"video.mp4"&lt;/span&gt; &lt;span class="nt"&gt;-vcodec&lt;/span&gt; h264 &lt;span class="nt"&gt;-acodec&lt;/span&gt; aac &lt;span class="nt"&gt;-f&lt;/span&gt; flv rtmp://127.0.0.1:1935/live/stream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. HTTP-FLV Publishing
&lt;/h3&gt;

&lt;h4&gt;
  
  
  URL Format
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://127.0.0.1:8501/{app}/{channel}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app&lt;/code&gt; and &lt;code&gt;channel&lt;/code&gt; follow the same rules as RTMP, alphanumeric only&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Publishing Examples (FFmpeg)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Local FLV file publishing&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-re&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; test.flv &lt;span class="nt"&gt;-c&lt;/span&gt;:v libx264 &lt;span class="nt"&gt;-c&lt;/span&gt;:a aac &lt;span class="nt"&gt;-f&lt;/span&gt; flv http://127.0.0.1:8501/live/stream

&lt;span class="c"&gt;# Local MP4 file loop publishing&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-re&lt;/span&gt; &lt;span class="nt"&gt;-stream_loop&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; video.mp4 &lt;span class="nt"&gt;-c&lt;/span&gt;:v libx264 &lt;span class="nt"&gt;-c&lt;/span&gt;:a aac &lt;span class="nt"&gt;-f&lt;/span&gt; flv http://127.0.0.1:8501/live/stream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use the built-in client pusher provided by this project (FLV/MP4 static files only):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php pusher.php test.flv http://127.0.0.1:8501/live/stream 1.0 &lt;span class="nt"&gt;--no-reconnect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php pusher.php test.mp4 http://127.0.0.1:8501/live/stream 1.0 &lt;span class="nt"&gt;--no-reconnect&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📺 Playback URL Summary &amp;amp; Tools
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Live Streaming URLs
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Distribution Recommendation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RTMP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rtmp://127.0.0.1:1935/live/stream&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Native RTMP players, ffplay supported&lt;/td&gt;
&lt;td&gt;Direct from origin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP-FLV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:8501/live/stream.flv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Low-latency browser playback, ffplay&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Distribute via FLV Gateway Cluster&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket-FLV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ws://127.0.0.1:8501/live/stream.flv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;WebSocket streaming playback&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Distribute via FLV Gateway Cluster&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HLS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/hls/live/stream/index.m3u8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Preferred for Android/iOS mobile&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Must distribute via fileGateway&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  VOD Playback URLs (After Recording Completes)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;File Type&lt;/th&gt;
&lt;th&gt;Access URL (must go through fileGateway)&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Merged MP4 VOD&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/mp4/live/stream/output_merge/stream_full.mp4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merged fMP4 Segment VOD (MSE)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/mp4/live/stream/output_merge/init.mp4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Separate Audio/Video fMP4 VOD&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/mp4/live/stream/output_separate/audio_init.mp4&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raw FLV VOD&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/flv/live/stream/20240101_120000.flv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;For high-concurrency scenarios&lt;/strong&gt;: You must use the Static File Gateway Cluster (e.g., &lt;code&gt;127.0.0.1:8100/8101/8102&lt;/code&gt;), distributing traffic via load balancing to achieve static resource read-write separation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Web Player Pages
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Page Purpose&lt;/th&gt;
&lt;th&gt;Access URL (recommended via fileGateway)&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FLV Live Playback&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/index.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP-FLV low-latency live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HLS Live Playback&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/play.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HLS mobile-compatible live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merged MP4 VOD&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/mp4.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Complete MP4 file VOD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Raw FLV VOD&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/video.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FLV native file VOD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;fMP4 Segment VOD&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://{fileGateway_IP}:8100/play_merge.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Supports both merged and separate segment playback&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Command-Line Playback Tools (ffplay)
&lt;/h3&gt;

&lt;p&gt;The project is fully compatible with &lt;strong&gt;ffplay&lt;/strong&gt; player, can directly pull various stream URLs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Play RTMP stream&lt;/span&gt;
ffplay rtmp://127.0.0.1:1935/live/stream

&lt;span class="c"&gt;# Play origin HTTP-FLV stream&lt;/span&gt;
ffplay http://127.0.0.1:8501/live/stream.flv

&lt;span class="c"&gt;# Play FLV gateway relayed stream&lt;/span&gt;
ffplay http://127.0.0.1:8080/live/stream.flv

&lt;span class="c"&gt;# Play HLS stream&lt;/span&gt;
ffplay http://127.0.0.1:8100/hls/live/stream/index.m3u8

&lt;span class="c"&gt;# Play VOD FLV/MP4 files&lt;/span&gt;
ffplay http://127.0.0.1:8100/flv/live/stream/20240101_120000.flv
ffplay http://127.0.0.1:8100/mp4/live/stream/output_merge/stream_full.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  💾 Live Recording Details
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Recording Mechanism (Three Independent Parallel Tasks)
&lt;/h3&gt;

&lt;p&gt;When publishing begins, the origin server simultaneously starts three &lt;strong&gt;independent parallel&lt;/strong&gt; recording tasks with zero blocking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    ┌─────────────────────────────────────────────────┐
                    │        RTMP / HTTP-FLV Dual-Protocol Ingest     │
                    └─────────────────────┬───────────────────────────┘
                                          │
                    ┌─────────────────────┼───────────────────────────┐
                    │                     │                           │
                    ▼                     ▼                           ▼
            ┌───────────────┐     ┌───────────────┐           ┌───────────────┐
            │ FLV Recording │     │ fMP4 Segments │           │ HLS Segments  │
            │  (real-time)  │     │  (real-time)  │           │  (real-time)  │
            └───────┬───────┘     └───────┬───────┘           └───────┬───────┘
                    │                     │                           │
                    ▼                     ▼                           ▼
            ┌───────────────┐     ┌───────────────┐           ┌───────────────┐
            │ Complete FLV  │     │ fMP4 Segments │           │ TS Segments   │
            │ (stream ends) │     │  (during live)│           │ + m3u8 index  │
            └───────────────┘     └───────┬───────┘           └───────────────┘
                                          │
                                          │ Auto-merge after stream ends
                                          ▼
                                    ┌───────────────┐
                                    │ Complete MP4  │
                                    │ (VOD playback)│
                                    └───────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Task Independence
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Recording Task&lt;/th&gt;
&lt;th&gt;Real-time&lt;/th&gt;
&lt;th&gt;Output&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Toggle&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FLV Record&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Complete FLV file&lt;/td&gt;
&lt;td&gt;Raw format backup, VLC/ffplay&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLV_TO_RECORD&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;fMP4 Segs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;fMP4 segments → merged MP4&lt;/td&gt;
&lt;td&gt;Browser MSE playback, VOD&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLV_TO_MP4&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;HLS Segs&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;TS segments + m3u8&lt;/td&gt;
&lt;td&gt;Mobile compatibility, HLS live&lt;/td&gt;
&lt;td&gt;&lt;code&gt;FLV_TO_HLS&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  📁 Project Directory Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rtmp_server/
├── flv/                              # FLV raw recording files (FLV_TO_RECORD)
├── mp4/                              # MP4/fMP4 transcoded output (FLV_TO_MP4)
├── hls/                              # HLS TS segments + m3u8 index (FLV_TO_HLS)
├── MediaServer/                      # RTMP core protocol, publish/play session logic
├── Root/                             # Low-level async I/O, Socket event-driven (includes epoll adaptive)
├── SabreAMF/                         # AMF0/AMF3 codec
├── server.php                        # Origin server entry point
├── fileGateway.php                   # Static file gateway (epoll supported, 20k+ concurrent)
├── flvGateway.php                    # FLV live gateway (epoll supported, 20k+ concurrent)
├── pusher.php                        # FLV Static File Push Client
├── *.html                            # Web player pages
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📈 Concurrency Performance Benchmarks
&lt;/h2&gt;

&lt;p&gt;All tests below were conducted in the &lt;strong&gt;same Docker container environment with &lt;code&gt;ulimit -n 65535&lt;/code&gt;&lt;/strong&gt;, using the same stress test script with 20,000 concurrent clients, each pulling streams for 5 seconds.&lt;/p&gt;

&lt;h3&gt;
  
  
  Origin Server (RTMP Origin)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Current container pids.max: unknown
Starting batch: 1000 clients (total 20 batches)
All clients started, waiting for completion...

===== Results =====
Success: 17,330
Failed: 2,670
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  FLV Live Gateway
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Current container pids.max: unknown
Starting batch: 1000 clients (total 20 batches)
All clients started, waiting for completion...

===== Results =====
Success: 19,923
Failed: 77
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Static File Gateway
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Concurrency: 20,000
Duration per client: 5s
Batch size: 1000

===== Results =====
Success: 20,000
Failed: 0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Notes&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The origin server handles RTMP/HTTP-FLV dual-protocol publishing, multi-protocol repackaging, and other business logic, yet a single process still stably achieves &lt;strong&gt;17,330&lt;/strong&gt; successful connections. Minor failures are due to instantaneous port collisions during testing.&lt;/li&gt;
&lt;li&gt;FLV Gateway, focused purely on stream relay, achieves a &lt;strong&gt;99.6% success rate&lt;/strong&gt; (19,923/20,000), approaching the single-machine TCP port pool limit.&lt;/li&gt;
&lt;li&gt;Static File Gateway is extremely lightweight, achieving &lt;strong&gt;20,000 concurrent connections with zero failures&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;All components adapt to the operating system: &lt;strong&gt;epoll is automatically enabled on Linux, breaking through the traditional select 1024 limit&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. How can a single process support 20,000+ concurrent connections?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Linux&lt;/strong&gt;: When the server detects the &lt;code&gt;event&lt;/code&gt; extension is installed, it &lt;strong&gt;automatically enables the epoll event-driven model&lt;/strong&gt;, no longer constrained by the traditional &lt;code&gt;select&lt;/code&gt; 1024 file descriptor limit. A single process easily handles 20,000+ connections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt;: Since the &lt;code&gt;event&lt;/code&gt; extension is unavailable, it automatically falls back to &lt;code&gt;select&lt;/code&gt; model, with limited connections per process (~256). Deploying multiple instances is recommended.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Performance Test&lt;/strong&gt;: In a Docker container (ulimit -n 65535), the Static File Gateway achieved &lt;strong&gt;20,000 concurrent with zero failures&lt;/strong&gt;, FLV Gateway achieved 99.6% success rate.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. How can gateways support even higher concurrency?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scaling Method&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Single Process High Performance&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Linux epoll mode, single process handles 20k+&lt;/td&gt;
&lt;td&gt;One fileGateway process handles 20,000 static requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Horizontal Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multiple instances at the same tier, load balanced&lt;/td&gt;
&lt;td&gt;3 fileGateway instances → 60,000+ concurrent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vertical Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-tier cascade&lt;/td&gt;
&lt;td&gt;Tier 1 → Tier 2 → Tier 3...&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Combined Scaling&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Horizontal + Vertical combined&lt;/td&gt;
&lt;td&gt;3 instances per tier × 3 tiers = theoretically 180,000+ concurrent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3. When do I need to deploy gateways?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concurrency Scenario&lt;/th&gt;
&lt;th&gt;Deployment Plan&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Low&lt;/strong&gt; (&amp;lt; 500)&lt;/td&gt;
&lt;td&gt;Origin server only, built-in HTTP service directly exposed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Medium&lt;/strong&gt; (500 – 5,000)&lt;/td&gt;
&lt;td&gt;Origin + single-tier gateway (1-2 instances)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;High&lt;/strong&gt; (&amp;gt; 5,000)&lt;/td&gt;
&lt;td&gt;Origin + multi-tier gateway cluster (each tier horizontally scalable)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  4. What's the difference between FLV Gateway and Static File Gateway?
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gateway Type&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Resource Types Handled&lt;/th&gt;
&lt;th&gt;Scaling Method&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;FLV Live Gateway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Live stream distribution&lt;/td&gt;
&lt;td&gt;HTTP-FLV real-time streams&lt;/td&gt;
&lt;td&gt;Horizontal + Vertical, cascade supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Static File Gateway&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Static resource hosting&lt;/td&gt;
&lt;td&gt;HLS/fMP4/MP4/FLV static files + Web pages&lt;/td&gt;
&lt;td&gt;Horizontal + Vertical, can integrate with Nginx&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  5. How to verify gateway concurrency capacity?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Use built-in stress test script (20,000 concurrent)&lt;/span&gt;
sh play.sh

&lt;span class="c"&gt;# Or use ab (Apache Bench) to test Static File Gateway&lt;/span&gt;
ab &lt;span class="nt"&gt;-n&lt;/span&gt; 10000 &lt;span class="nt"&gt;-c&lt;/span&gt; 500 http://127.0.0.1:8100/index.html

&lt;span class="c"&gt;# Use wrk to test FLV Gateway&lt;/span&gt;
wrk &lt;span class="nt"&gt;-t4&lt;/span&gt; &lt;span class="nt"&gt;-c1000&lt;/span&gt; &lt;span class="nt"&gt;-d30s&lt;/span&gt; http://127.0.0.1:8080/live/stream.flv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Toolkit
&lt;/h2&gt;

&lt;p&gt;The protocol conversion functionality of this project has been extracted into a standalone toolkit &lt;code&gt;xiaosongshu/flv2mp4&lt;/code&gt;, available at &lt;code&gt;https://github.com/2723659854/flv2mp4&lt;/code&gt;. It supports FLV, MP4, HLS transcoding, FLV and File gateways, as well as an FLV static file push client.&lt;/p&gt;

&lt;h2&gt;
  
  
  📄 License
&lt;/h2&gt;

&lt;p&gt;This project is limited to learning and technical research use. Commercial deployment risks are borne by the user.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Disclaimer
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Some open-source code originates from the open-source community. If copyright is involved, please contact the author for removal.&lt;/li&gt;
&lt;li&gt;This project is fully open-source and free, intended only for technical exchange.&lt;/li&gt;
&lt;li&gt;The author assumes no joint liability for any legal consequences arising from commercial or illegal use by users.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  📧 Contact
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;📬 Email: &lt;a href="mailto:2723659854@qq.com"&gt;2723659854@qq.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;🐙 GitHub: &lt;a href="https://github.com/2723659854" rel="noopener noreferrer"&gt;2723659854&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>architecture</category>
      <category>networking</category>
      <category>php</category>
      <category>showdev</category>
    </item>
    <item>
      <title>A lightweight RTMP live streaming server built with pure PHP</title>
      <dc:creator>2723659854</dc:creator>
      <pubDate>Mon, 01 Jun 2026 02:02:37 +0000</pubDate>
      <link>https://dev.to/2723659854/a-lightweight-rtmp-live-streaming-server-built-with-pure-php-2gh4</link>
      <guid>https://dev.to/2723659854/a-lightweight-rtmp-live-streaming-server-built-with-pure-php-2gh4</guid>
      <description>&lt;h2&gt;
  
  
  RTMP Server
&lt;/h2&gt;

&lt;p&gt;A lightweight RTMP live streaming server built with pure PHP. No Nginx or other streaming software required.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🎥 &lt;strong&gt;RTMP Push/Pull&lt;/strong&gt; - Standard RTMP protocol support&lt;/li&gt;
&lt;li&gt;📡 &lt;strong&gt;HTTP-FLV / WebSocket-FLV&lt;/strong&gt; - Low-latency playback in browsers&lt;/li&gt;
&lt;li&gt;🧩 &lt;strong&gt;HLS Output&lt;/strong&gt; - Automatic M3U8 + TS segment generation, mobile-friendly&lt;/li&gt;
&lt;li&gt;💾 &lt;strong&gt;Auto Recording&lt;/strong&gt; - Automatic recording during streaming, saves as both MP4 and FLV files&lt;/li&gt;
&lt;li&gt;🖥️ &lt;strong&gt;Built-in Players&lt;/strong&gt; - Multiple web playback pages, ready to use out of the box&lt;/li&gt;
&lt;li&gt;🐳 &lt;strong&gt;Docker Support&lt;/strong&gt; - One-click development environment, no manual extension configuration&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Pure PHP Implementation&lt;/strong&gt; - No need for Nginx, SRS, or other streaming servers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📋 Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PHP &amp;gt;= 8.1 (CLI mode)&lt;/li&gt;
&lt;li&gt;PHP extensions enabled:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;sockets&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pcntl&lt;/code&gt; (optional for Linux/macOS)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Quick Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project xiaosongshu/rtmp_server
&lt;span class="nb"&gt;cd &lt;/span&gt;rtmp_server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Start Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php server.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stop Server
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Windows&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Ctrl + C&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux / macOS&lt;/td&gt;
&lt;td&gt;`ps aux \&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  🔧 Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Port Configuration
&lt;/h3&gt;

&lt;p&gt;Default ports (modifiable in {% raw %}&lt;code&gt;server.php&lt;/code&gt;):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1935&lt;/td&gt;
&lt;td&gt;RTMP&lt;/td&gt;
&lt;td&gt;Push/Pull streaming&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8501&lt;/td&gt;
&lt;td&gt;HTTP/WebSocket&lt;/td&gt;
&lt;td&gt;FLV playback (live)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;HTTP&lt;/td&gt;
&lt;td&gt;HLS playback + Web pages + static file replay&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  📡 Pushing Streams
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Push URL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rtmp://127.0.0.1:1935/{app}/{channel}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;{app}&lt;/code&gt;: Application name, e.g., &lt;code&gt;live&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{channel}&lt;/code&gt;: Channel name, e.g., &lt;code&gt;stream&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Only English letters and numbers are supported&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Streaming Tools
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Using OBS Studio
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Download &lt;a href="https://obsproject.com/" rel="noopener noreferrer"&gt;OBS Studio&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Settings → Stream → Custom RTMP Server&lt;/li&gt;
&lt;li&gt;Server URL: &lt;code&gt;rtmp://127.0.0.1:1935/live&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Stream Key: &lt;code&gt;stream&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Start streaming&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Using FFmpeg
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-re&lt;/span&gt; &lt;span class="nt"&gt;-stream_loop&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"video.mp4"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-vcodec&lt;/span&gt; h264 &lt;span class="nt"&gt;-acodec&lt;/span&gt; aac &lt;span class="nt"&gt;-f&lt;/span&gt; flv &lt;span class="se"&gt;\&lt;/span&gt;
  rtmp://127.0.0.1:1935/live/stream
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Parameter Description:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-re&lt;/code&gt;: Read input at native frame rate&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-stream_loop -1&lt;/code&gt;: Loop infinitely&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-i&lt;/code&gt;: Input video file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-vcodec h264&lt;/code&gt;: H.264 video codec&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-acodec aac&lt;/code&gt;: AAC audio codec&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-f flv&lt;/code&gt;: FLV container format&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📺 Pulling &amp;amp; Playback Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Live Stream URLs (Real-time Playback)
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RTMP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rtmp://127.0.0.1:1935/live/stream&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Native RTMP protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP-FLV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:8501/live/stream.flv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Low-latency browser playback&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket-FLV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ws://127.0.0.1:8501/live/stream.flv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;WebSocket protocol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HLS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:80/hls/live/stream/index.m3u8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Recommended for mobile&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Built-in Web Player Pages
&lt;/h3&gt;

&lt;p&gt;After starting the server, open the following URLs in your browser (replace with your actual stream path):&lt;/p&gt;

&lt;h4&gt;
  
  
  🔴 Live Streaming Test Pages
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Page&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;FLV Live Player&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:80/index.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTTP-FLV live stream with autoplay (first click required)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HLS Live Player&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:80/play.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HLS live stream, compatible with mobile browsers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The default stream URL is &lt;code&gt;rtmp://127.0.0.1:1935/live/stream&lt;/code&gt;, which corresponds to stream name &lt;code&gt;live/stream&lt;/code&gt; in the page. Modify the stream address in the page if using a different channel name.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  🔵 Static File Playback Pages
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Page&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;MP4 Playback&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:80/mp4.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Play recorded MP4 files (auto-generated during streaming)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;FLV Playback&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:80/video.html&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Play recorded FLV files (auto-generated during streaming)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Recorded files are saved in &lt;code&gt;./mp4/&lt;/code&gt; and &lt;code&gt;./flv/&lt;/code&gt; directories. Modify the video path in the page to play specific files.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  💾 Auto Recording
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Streaming starts&lt;/strong&gt; → Recording begins automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaming ends&lt;/strong&gt; → Saves as both MP4 and FLV files&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MP4 file location&lt;/strong&gt;: &lt;code&gt;./mp4/{app}/{channel}/{channel}_full.mp4&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FLV file location&lt;/strong&gt;: &lt;code&gt;./flv/{app}/{channel}/{random_id}.flv&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Notes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Recorded MP4 files use standard fMP4 format, supporting drag-to-seek playback&lt;/li&gt;
&lt;li&gt;✅ Recorded FLV files use standard FLV format, playable with VLC and other players&lt;/li&gt;
&lt;li&gt;⚠️ Streaming with the same path will &lt;strong&gt;overwrite&lt;/strong&gt; previous recording files&lt;/li&gt;
&lt;li&gt;⚠️ The server does not automatically delete recording files; clean up as needed&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  FLV to MP4 Conversion (Manual)
&lt;/h3&gt;

&lt;p&gt;To manually convert a recorded FLV file to MP4 format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;require_once&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/vendor/autoload.php'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nb"&gt;ini_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'memory_limit'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'512M'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Path to the FLV file to convert&lt;/span&gt;
&lt;span class="nv"&gt;$file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"/test.flv"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Output directory for the converted MP4&lt;/span&gt;
&lt;span class="nv"&gt;$outputDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s2"&gt;"/output"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;\Xiaosongshu\Flv2mp4\Client&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$outputDir&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Conversion successful: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$res&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\Exception&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Conversion failed: "&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: The server automatically converts live streams to MP4 during streaming, so manual conversion is usually unnecessary.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📁 Directory Structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rtmp_server/
├── mp4/               # MP4 recording files
│   └── {app}/{name}/  # Organized by app/channel name
├── flv/               # FLV recording files
│   └── {app}/{name}/  # Organized by app/channel name
├── hls/               # HLS segment files
│   └── {app}/{name}/  # M3U8 + TS segments
├── MediaServer/       # Core server code
├── ../                # Other core service code
├── server.php         # Server entry point
├── index.html         # FLV live player page
├── play.html          # HLS live player page
├── mp4.html           # MP4 playback page
├── video.html         # FLV playback page
└── README.md          # Project documentation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ❓ FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Missing Extensions Error on Startup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: PHP CLI mode and FPM mode may have different extension configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;php -m&lt;/code&gt; to check installed extensions&lt;/li&gt;
&lt;li&gt;Install missing extensions (e.g., &lt;code&gt;sockets&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Using Docker environment avoids this issue&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Port Already in Use
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check port usage: &lt;code&gt;netstat -ano | findstr &amp;lt;port&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Modify port settings in &lt;code&gt;server.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Update port settings in player pages accordingly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Player Page Cannot Connect
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ensure the server is running and the port is not blocked by firewall&lt;/li&gt;
&lt;li&gt;Verify the playback URL in the page matches the actual stream path&lt;/li&gt;
&lt;li&gt;If using a different port, update the port number in the page&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Recording File Overwrite
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Streaming with the same path overwrites previous recording files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use different channel names when streaming&lt;/li&gt;
&lt;li&gt;Or implement custom cleanup and backup logic for recording files&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📄 License
&lt;/h2&gt;

&lt;p&gt;This project is for learning and communication purposes only. Commercial use is not permitted.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚠️ Disclaimer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Some project code originates from the internet; please contact us if there are copyright issues&lt;/li&gt;
&lt;li&gt;This project is fully open source and intended for technical exchange&lt;/li&gt;
&lt;li&gt;Users bear their own legal risks when using this project&lt;/li&gt;
&lt;li&gt;The author is not responsible for any losses incurred from using this project&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📧 Contact
&lt;/h2&gt;

&lt;p&gt;For questions or suggestions, please contact via email:&lt;/p&gt;

&lt;p&gt;📧 &lt;a href="mailto:2723659854@qq.com"&gt;2723659854@qq.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>networking</category>
      <category>php</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Pure PHP hand-built RTMP live streaming server</title>
      <dc:creator>2723659854</dc:creator>
      <pubDate>Tue, 26 May 2026 13:34:13 +0000</pubDate>
      <link>https://dev.to/2723659854/pure-php-hand-built-rtmp-live-streaming-server-1l0e</link>
      <guid>https://dev.to/2723659854/pure-php-hand-built-rtmp-live-streaming-server-1l0e</guid>
      <description>&lt;h1&gt;
  
  
  rtmp_server
&lt;/h1&gt;

&lt;p&gt;A pure PHP-based RTMP live streaming server. Supports RTMP push and pull streaming, FLV streaming (HTTP/WS), HLS streaming, and includes a simple web-based player.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;🎥 RTMP push &amp;amp; pull streaming&lt;/li&gt;
&lt;li&gt;📡 HTTP-FLV and WebSocket-FLV pull streaming&lt;/li&gt;
&lt;li&gt;🧩 HLS output (M3U8 + TS segments)&lt;/li&gt;
&lt;li&gt;🖥️ Built-in simple web player (FLV / HLS)&lt;/li&gt;
&lt;li&gt;🐳 Docker development environment (includes FFmpeg and PHP extensions)&lt;/li&gt;
&lt;li&gt;⚡ Pure PHP implementation – no Nginx or other streaming server required&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;PHP &amp;gt;= 8.1 (CLI mode)&lt;/li&gt;
&lt;li&gt;PHP extensions: &lt;code&gt;sockets&lt;/code&gt; and others (see error messages if missing)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer create-project xiaosongshu/rtmp_server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configuration &amp;amp; Startup
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Option 1: Using phpstudy (recommended for beginners)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Download and install &lt;a href="https://m.xp.cn/" rel="noopener noreferrer"&gt;phpstudy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Switch PHP version to &lt;strong&gt;8.1&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Install required extensions via phpstudy's package manager (follow any error prompts)&lt;/li&gt;
&lt;li&gt;Navigate to the project root and start the server&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Option 2: Using Docker (recommended – includes all dependencies)
&lt;/h4&gt;

&lt;p&gt;Run the following command in the project root:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Docker environment includes PHP 8.1, all required extensions, and FFmpeg (for pushing streams, packet inspection, or transcoding).&lt;/p&gt;

&lt;h3&gt;
  
  
  Start the Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php server.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stop the Server
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows&lt;/strong&gt;: &lt;code&gt;Ctrl + C&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux / macOS&lt;/strong&gt;: &lt;code&gt;kill -9 &amp;lt;PID&amp;gt;&lt;/code&gt; (find PID with &lt;code&gt;ps aux | grep server.php&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Port Configuration
&lt;/h2&gt;

&lt;p&gt;Default ports (can be modified in the entry file):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1935&lt;/td&gt;
&lt;td&gt;RTMP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8501&lt;/td&gt;
&lt;td&gt;FLV (HTTP &amp;amp; WebSocket)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;Web (HLS + static pages)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Push Streaming
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Push Stream URL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rtmp://127.0.0.1:1935/a/b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;a&lt;/code&gt; = application name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;b&lt;/code&gt; = stream key / channel name
(customizable; only letters and numbers allowed)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Push Streaming Tools
&lt;/h3&gt;

&lt;h4&gt;
  
  
  OBS Studio
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Download: &lt;a href="https://obsproject.com/" rel="noopener noreferrer"&gt;obsproject.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tutorial: &lt;a href="https://www.tencentcloud.com/zh/document/product/267/31569" rel="noopener noreferrer"&gt;OBS streaming to custom RTMP server&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  FFmpeg
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-re&lt;/span&gt; &lt;span class="nt"&gt;-stream_loop&lt;/span&gt; 1 &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"movie.mp4"&lt;/span&gt; &lt;span class="nt"&gt;-vcodec&lt;/span&gt; h264 &lt;span class="nt"&gt;-acodec&lt;/span&gt; aac &lt;span class="nt"&gt;-f&lt;/span&gt; flv rtmp://127.0.0.1/a/b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Parameter explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-re&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Read input at native frame rate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-stream_loop 1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Loop the input file once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-i "movie.mp4"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Input video file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-vcodec h264&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;H.264 video encoding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-acodec aac&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AAC audio encoding&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-f flv&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;FLV output format (required for RTMP)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Pull Streaming
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Available Pull URLs
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;URL&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;RTMP&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rtmp://127.0.0.1/a/b&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTTP-FLV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:8501/a/b.flv&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WebSocket-FLV&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ws://127.0.0.1:8501/a/b.flv&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HLS (M3U8)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http://127.0.0.1:80/hls/a/b/index.m3u8&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Players
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.videolan.org/" rel="noopener noreferrer"&gt;VLC media player&lt;/a&gt; – Open Network Stream&lt;/li&gt;
&lt;li&gt;Built-in web player:

&lt;ul&gt;
&lt;li&gt;FLV test page: &lt;a href="http://127.0.0.1:80/index.html" rel="noopener noreferrer"&gt;http://127.0.0.1:80/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;HLS test page: &lt;a href="http://127.0.0.1:80/play.html" rel="noopener noreferrer"&gt;http://127.0.0.1:80/play.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Missing extensions at runtime&lt;/strong&gt;: This project runs in PHP CLI mode, which differs from traditional FPM mode. Install the required extensions based on any error messages. If using Docker, all extensions are pre-installed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Port conflicts&lt;/strong&gt;: Check if ports 1935, 8501, or 80 are already in use. You can modify the port configuration in the entry file. If you change the ports, remember to update the built-in player pages accordingly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⚠️ Disclaimer
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Some code or materials in this project may originate from public sources. If there are any copyright concerns, please contact me for removal.&lt;/li&gt;
&lt;li&gt;This project is fully open source, intended for technical sharing and mutual progress. The author is not responsible for any legal or commercial disputes arising from individual usage.&lt;/li&gt;
&lt;li&gt;Users assume all risks associated with using this project, including but not limited to copyright and compliance issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For any questions or suggestions, feel free to reach out via email.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contact
&lt;/h2&gt;

&lt;p&gt;📧 Email: &lt;a href="mailto:2723659854@qq.com"&gt;2723659854@qq.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>backend</category>
      <category>networking</category>
      <category>php</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
