diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..f095af8 --- /dev/null +++ b/README.en.md @@ -0,0 +1,150 @@ +# rtp2httpd - IPTV Streaming Relay Server + +Language: [中文](README.md) | [English](README.en.md) + +rtp2httpd is a multimedia stream relay server. This project is a complete rewrite of [oskar456/rtp2httpd](https://github.com/oskar456/rtp2httpd), adding many new features and tailored for Mainland China IPTV environments. + +rtp2httpd converts multicast RTP/UDP and RTSP streams to HTTP unicast, and implements carrier-grade FCC ([Fast Channel Change](https://blog.csdn.net/yangzex/article/details/131328837)) for near-instant channel switching. It can act as a seamless replacement for `udpxy` and `msd_lite`, delivering an experience close to native set-top boxes. + +## ✨ Core Features + +### 📡 Multi-Protocol Support + +- **RTP->HTTP**: Convert multicast RTP/UDP streams to standard HTTP streams +- **RTSP->HTTP**: Convert RTSP to HTTP video streams with a full RTSP/RTP stack and UDP NAT traversal (STUN) + - Enables catchup playback for IPTV RTSP time-shift sources +- **HTTP->HTTP**: Full reverse proxy to relay IPTV intranet HLS sources to LAN/WAN +- **UDPxy Compatibility**: Fully compatible with UDPxy URL formats +- **M3U Playlist Integration**: Supports M3U/M3U8 with automatic URL detection and conversion + - Supports external M3U URLs + - Smart detection for RTP/RTSP URLs and conversion to HTTP proxy format + - Automatic handling of catchup-source time-shift URLs + - Access the converted playlist via `http:///playlist.m3u` +- **Loss/Jitter Resilience**: Out-of-order recovery and FEC forward error correction + - Reorders out-of-order RTP packets to reduce artifacts caused by jitter + - Reed-Solomon FEC redundancy for mild packet loss (requires upstream multicast FEC) +- **Channel Snapshots**: Fetch channel snapshots via HTTP to reduce decoder load on clients + +### ⚡ FCC Fast Channel Change + +- **Carrier FCC Protocol Support**: Works with carrier FCC servers for millisecond-level channel switching +- **Fast Decode**: FCC ensures IDR frames are delivered quickly for instant playback + +### 📊 Real-Time Status Monitoring + +- **Web Status Page**: Visit `http:///status` for live server stats +- **Client Connection Stats**: IP, state, bandwidth usage, and transfer volumes per connection +- **Live Logs**: Real-time log view with dynamic log level control +- **Remote Management**: Force disconnect clients from the web UI + +### 🎬 Built-in Player + +- **Browser Playback**: Modern embedded web player with responsive desktop/mobile UI +- **Fast Startup**: Works with FCC for fast start and fast channel switching +- **Time-Shift & Catchup**: Supports EPG and catchup playback (requires RTSP catchup source) +- **Zero Overhead**: Pure web frontend, no decoding/transcoding load on rtp2httpd + +### 🚀 Performance Optimizations + +- **Non-blocking IO**: epoll-based event model for high concurrency +- **Multi-core Scaling**: Multiple worker processes to utilize multi-core CPUs +- **Buffer Pooling**: Pre-allocated pools, dynamic sharing across clients to avoid slow-client stalls +- **Zero-copy**: Supports Linux MSG_ZEROCOPY to avoid user/kernel copies +- **Lightweight**: Pure C with minimal dependencies, runs well on embedded devices + - Binary size is about 340KB (x86_64) with all web assets embedded +- See the **[Performance Benchmark](docs/en/benchmark.md)** (vs msd_lite, udpxy, tvgate) + +## 📹 Demos + +### Fast Channel Change + Catchup + +https://github.com/user-attachments/assets/a8c9c60f-ebc3-49a8-b374-f579f8e34d92 + +> **Tip**: Fast channel change works best with IPTV-optimized players such as [mytv-android](https://github.com/mytv-android/mytv-android) / [TiviMate](https://tivimate.com) / [Cloud Stream](https://apps.apple.com/us/app/cloud-stream-iptv-player/id1138002135). The demo uses TiviMate. +> General players like PotPlayer / IINA are not optimized for fast start, so FCC benefits are limited. + +### Built-in Player + +https://github.com/user-attachments/assets/d676b8c1-7017-48a1-814c-caab0054b361 + +> Configure an M3U playlist and open `http:///player` in a browser. +> Browser decoding limits apply (Chrome cannot play AC3 audio for Beijing TV 4K, iOS cannot play MP2 audio for HD/SD channels). + +### Real-Time Status Monitoring + +Image + +### 25 x 1080p Multicast Streams Playing Simultaneously + +https://github.com/user-attachments/assets/fedc0c28-f9ac-4675-9b19-a8efdd062506 + +> Single stream bitrate: 8 Mbps. Total CPU usage is 25% of a single core (i3-N305) with 4MB memory usage. + +## 🚀 Quick Start + +### One-Command OpenWrt Install/Update + +```bash +uclient-fetch -q -O - https://raw.githubusercontent.com/stackia/rtp2httpd/main/scripts/install-openwrt.sh | sh +``` + +After installation, find "rtp2httpd" under the "Services" menu in the LuCI admin UI to configure it. + +If LuCI behaves oddly after an update, **Ctrl+F5 refresh** or **clear browser cache** or **use incognito mode**. + +If the LuCI entry does not appear after install, your LuCI version may be too old to support JS-based LuCI apps. Consider updating your firmware. Alternatively, edit `/etc/config/rtp2httpd` manually (set `disabled` to 0) and restart via `/etc/init.d/rtp2httpd restart`. + +> Some community members have also developed a Lua version of luci-app-rtp2httpd +> +> - +> - + +### Other Platforms + +rtp2httpd supports multiple deployment options: + +- **Static binary**: Runs on any Linux system +- **Docker container**: Containerized deployment +- **Build from source**: Compile from source, or include as an OpenWrt feed + +See the [Installation Guide](docs/en/installation.md). + +## 📖 Documentation + +- **[Quick Start](docs/en/quick-start.md)**: OpenWrt quick configuration +- **[Installation](docs/en/installation.md)**: Installation options +- **[URL Formats](docs/en/url-formats.md)**: Supported URL formats and protocols +- **[M3U Integration](docs/en/m3u-integration.md)**: M3U configuration and usage +- **[Configuration Reference](docs/en/configuration.md)**: Full configuration options +- **[FCC Setup](docs/en/fcc-setup.md)**: Enable millisecond-level fast channel change +- **[Video Snapshots](docs/en/video-snapshot.md)**: Channel preview configuration + +If you are new to IPTV multicast relay services and related network topics (DHCP auth, routing, multicast, firewalls), these guides are also helpful: + +- [Zhejiang Hangzhou Telecom IPTV Intranet Integration Guide](https://baiyun.me/zhejiang-hangzhou-telecom-iptv) +- [Auto-fetch IPTV unicast addresses for time-shift playback](https://www.bandwh.com/net/2571.html) +- [K2P OpenWrt IPTV full guide with rtp2httpd](https://www.right.com.cn/forum/thread-8457970-1-1.html) +- [Chongqing Telecom IPTV rtp2httpd capture guide](https://www.right.com.cn/forum/thread-8457356-1-1.html) +- [Zhejiang Telecom IPTV multicast to unicast, rtp2httpd](https://www.right.com.cn/forum/thread-8452510-1-1.html) +- [Rtp2httpd on Cool 9 Zhejiang Telecom IPTV](https://www.right.com.cn/forum/thread-8453715-1-1.html) +- [Hunan Telecom OpenWrt IPTV end-to-end guide](https://mp.weixin.qq.com/s/_hEVbrgHll_qIePXGtATTw) +- [📺 Bypass Router IPTV Plugin Guide](https://www.bilibili.com/video/BV1ioiKBNE8t/) +- [📺 Multicast to unicast series part 2](https://www.bilibili.com/video/BV1Zhr4B3ELy/) + +## 📄 License + +This project is released under the GNU General Public License v2.0. This means: + +- ✅ You can deploy in commercial environments (e.g., internal enterprise use) +- ✅ You can offer paid IPTV relay services based on it +- ✅ You can use it in paid IPTV consulting services +- ✅ You can sell hardware devices that include this software +- ⚠️ If you modify the code, you must publish the modified source code +- ⚠️ If you distribute binaries, you must also provide the source code +- ⚠️ You cannot close-source it and sell it + +## 🙏 Acknowledgements + +- The developers of the original project [oskar456/rtp2httpd](https://github.com/oskar456/rtp2httpd) +- Professionals who shared FCC protocol details publicly +- All users who tested and provided feedback diff --git a/README.md b/README.md index a285d90..4aba290 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # rtp2httpd - IPTV 流媒体转发服务器 +Language: [中文](README.md) | [English](README.en.md) + rtp2httpd 是一个多媒体流转发服务器。本项目基于 [oskar456/rtp2httpd](https://github.com/oskar456/rtp2httpd) 做了完全重写,在原项目基础上加入了许多新功能,专为中国大陆 IPTV 环境设计。 rtp2httpd 支持将组播 RTP/UDP 流、RTSP 流转换为 HTTP 单播流,并实现了运营商级的 FCC([Fast Channel Change](https://blog.csdn.net/yangzex/article/details/131328837))快速换台协议,可以作为 `udpxy` 和 `msd_lite` 的无缝替代,为 IPTV 用户提供接近原生机顶盒的观看体验。 diff --git a/docs/benchmark.md b/docs/benchmark.md index ed79a64..dcb23c8 100644 --- a/docs/benchmark.md +++ b/docs/benchmark.md @@ -1,5 +1,7 @@ # 性能测试报告 +Language: [中文](benchmark.md) | [English](en/benchmark.md) + **rtp2httpd**、**[msd_lite](https://github.com/rozhuk-im/msd_lite)**、**[udpxy](https://github.com/pcherenkov/udpxy)** 和 **[tvgate](https://github.com/qist/tvgate)** 四款组播转单播程序性能对比。 ## 测试环境 diff --git a/docs/cn-fcc-collection.md b/docs/cn-fcc-collection.md index 5ab4284..fc3f79c 100644 --- a/docs/cn-fcc-collection.md +++ b/docs/cn-fcc-collection.md @@ -1,5 +1,7 @@ # 各地区 FCC 服务器收集 +Language: [中文](cn-fcc-collection.md) | [English](en/cn-fcc-collection.md) + 以下是从互联网收集的各地区 FCC 服务器,不保证可用,如有不可用请到 讨论反馈。 1. 如果没有列出本城市 IP,可以尝试临近城市或省会的 IP。 diff --git a/docs/configuration.md b/docs/configuration.md index 5e5fd0c..cfb63c4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1,5 +1,7 @@ # 配置参数详解 +Language: [中文](configuration.md) | [English](en/configuration.md) + rtp2httpd 支持通过命令行参数和配置文件两种方式进行配置。 ## 命令行参数 diff --git a/docs/en/benchmark.md b/docs/en/benchmark.md new file mode 100644 index 0000000..3d5a570 --- /dev/null +++ b/docs/en/benchmark.md @@ -0,0 +1,103 @@ +# Performance Benchmark Report + +Language: [中文](../benchmark.md) | [English](benchmark.md) + +Performance comparison of four multicast-to-unicast programs: **rtp2httpd**, **[msd_lite](https://github.com/rozhuk-im/msd_lite)**, **[udpxy](https://github.com/pcherenkov/udpxy)**, and **[tvgate](https://github.com/qist/tvgate)**. + +## Test Environment + +- **Platform**: Ubuntu 24.04 on Apple M3 Max (Parallels Desktop VM) +- **Architecture**: aarch64 (all programs are native arm64 builds) +- **Kernel**: Linux 6.8.0-90-generic +- **Duration per test**: 10 seconds +- **Measurement method**: + - CPU: sampled with `top -b -n 2` + - Memory: USS (Unique Set Size) read from `/proc/[pid]/smaps_rollup` + - If a process forks, CPU and memory are summed across parent and children +- **Versions**: + - rtp2httpd: v3.8.3 + - msd_lite: commit 79a6c62 (2025-05-02) + - udpxy: commit 56fc563 (2026-01-26) + - tvgate: v2.1.8 + +## Test Scenarios + +| Test | Description | +| ---------------- | -------------------------------------------------------------------------- | +| **Multi-stream** | 8 clients, each requesting a different multicast address, ~40 Mbps per stream (4K IPTV bitrate) | +| **Single-stream**| 8 clients, all requesting the same multicast address, ~40 Mbps per stream | +| **High-bandwidth** | 1 client, ~400 Mbps per stream | + +## Summary Results + +### CPU Usage (%) + +| Scenario | rtp2httpd | msd_lite | udpxy | tvgate | +| --------------------- | ------------- | -------- | ------- | ------- | +| Multi-stream (8 unique addresses) | 🏆 **17.00%** | 25.80% | 106.00% | 331.00% | +| Single-stream (8 same address) | 🏆 **14.00%** | 14.20% | 85.00% | 51.45% | +| High-bandwidth (400 Mbps) | 🏆 **26.73%** | 39.50% | 30.85% | 89.53% | + +### Memory Usage (MB) + +| Scenario | rtp2httpd | msd_lite | udpxy | tvgate | +| --------------------- | ----------- | ----------- | ----- | ------ | +| Multi-stream (8 unique addresses) | 🏆 **4.50** | 10.25 | 12.53 | 182.00 | +| Single-stream (8 same address) | 4.88 | 🏆 **2.62** | 12.53 | 33.25 | +| High-bandwidth (400 Mbps) | 3.88 | 🏆 **2.62** | 3.21 | 47.38 | + +## Detailed Results + +### Test 1: Multi-stream (8 clients, different addresses, ~40 Mbps) + +Each client requests a different multicast address (239.81.0.1-8), testing the server's ability to handle multiple independent streams. + +| Metric | rtp2httpd | msd_lite | udpxy | tvgate | +| -------- | -------------- | -------- | -------- | --------- | +| CPU Avg | 🏆 **17.00%** | 25.80% | 106.00% | 331.00% | +| CPU Peak | 🏆 **18.00%** | 30.00% | 116.00% | 332.00% | +| Memory Avg | 🏆 **4.50 MB** | 10.25 MB | 12.53 MB | 182.00 MB | + +### Test 2: Single-stream (8 clients, same address, ~40 Mbps) + +All 8 clients request the same multicast address, testing multicast reuse efficiency. + +| Metric | rtp2httpd | msd_lite | udpxy | tvgate | +| -------- | ------------- | -------------- | -------- | -------- | +| CPU Avg | 🏆 **14.00%** | 14.20% | 85.00% | 51.45% | +| CPU Peak | 18.00% | 🏆 **15.00%** | 108.00% | 52.90% | +| Memory Avg | 4.88 MB | 🏆 **2.62 MB** | 12.53 MB | 33.25 MB | + +### Test 3: High-bandwidth (1 client, ~400 Mbps) + +Single client receives a high-bandwidth stream (50x playback ≈ 400 Mbps). + +| Metric | rtp2httpd | msd_lite | udpxy | tvgate | +| -------- | ------------- | -------------- | ------- | -------- | +| CPU Avg | 🏆 **26.73%** | 39.50% | 30.85% | 89.53% | +| CPU Peak | 🏆 **29.40%** | 40.00% | 46.00% | 96.00% | +| Memory Avg | 3.88 MB | 🏆 **2.62 MB** | 3.21 MB | 47.38 MB | + +## Conclusions + +**rtp2httpd** shows excellent overall performance: + +- **Best CPU efficiency**: Lowest CPU usage in all three scenarios. In multi-stream, only 66% of msd_lite, 16% of udpxy, and 5% of tvgate. +- **Strong multi-stream handling**: With 8 independent 4K multicast streams, both CPU and memory are the lowest, ideal for multi-channel IPTV gateways. +- **Stable at high bandwidth**: Only ~27% CPU at 400 Mbps, leaving ample headroom. +- **Reasonable memory usage**: ~4 MB with default settings, stable across scenarios and suitable for embedded devices. + +Compared to udpxy's fork-per-client model, rtp2httpd uses a more efficient event-driven architecture, offering clear advantages under high concurrency. Compared to msd_lite, rtp2httpd is more CPU-efficient, especially in multi-stream scenarios. + +## Running the Benchmark + +See [tools/README.md](../../tools/README.md) for tools and methodology. + +Quick run: + +```bash +cd tools +./benchmark.sh +``` + +Results are saved to `benchmark_results_YYYYMMDD_HHMMSS.txt`. diff --git a/docs/en/cn-fcc-collection.md b/docs/en/cn-fcc-collection.md new file mode 100644 index 0000000..199baef --- /dev/null +++ b/docs/en/cn-fcc-collection.md @@ -0,0 +1,41 @@ +# FCC Servers by Region (China) + +Language: [中文](../cn-fcc-collection.md) | [English](cn-fcc-collection.md) + +Below are FCC servers collected from the internet. Availability is not guaranteed. If a server is down, please discuss at . + +1. If your city is not listed, try a nearby city or the provincial capital. +2. In some regions, the FCC IP is the same as the RTSP unicast source IP but on a different port. If you can find a local RTSP unicast address, try port 8027 or 15970 as the FCC address. +3. You can judge whether FCC is working from the rtp2httpd logs. + - `FCC: Unicast stream started successfully` means the FCC address is valid and unicast streaming succeeded. + - `FCC: Server response timeout (80 ms), falling back to multicast` can mean: + 1. The FCC address is invalid. + 2. Your network is not configured correctly and cannot reach the FCC server. In general, you must obtain an IPTV intranet IP via DHCP/IPoE/PPPoE and enable `--upstream-interface-fcc` or `--upstream-interface` to bind the IPTV interface. Use ping/traceroute to verify. +4. In some regions, different multicast addresses require different FCC IPs, and some multicast channels may not enable FCC at all. +5. Some regions have multiple IPTV platforms (e.g., ZTE, Huawei, FiberHome) under the same carrier, so FCC addresses can differ. This may explain why one user in the same region can use an address and another cannot. + - Typically port 8027 is Huawei, and port 15970 is ZTE/FiberHome. + +| Province | Telecom | Unicom | Mobile | +| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | ----------------------------- | +| Hainan | 10.255.75.73:15970 | | | +| Jiangsu | 180.100.72.185:15970 | | | +| Zhejiang | 115.233.40.137:8027 (Hangzhou)
115.233.41.137:8027 (Hangzhou)
220.186.210.205:8027 (Wenzhou)
115.233.43.70:8027 (Jinhua)
220.191.136.24:8027 (Taizhou)
115.233.42.69:8027 (Shaoxing) | | | +| Shanghai | 124.75.26.151:15970
124.75.25.211:7777
124.75.25.214:7777
124.75.25.212:7777
124.75.25.215:7777
124.75.25.216:7777 | 10.223.3.189:8027 | | +| Tianjin | 10.255.4.140:8027 | | 10.206.255.108:8027 | +| Hunan | 10.255.168.4:15970
124.232.149.47:15970
61.150.161.42:8027
222.241.55.41:8027 (Changde) | | 100.127.255.233:15970 | +| Hubei | 121.60.255.120:15970 | | | +| Henan | | 10.254.199.130:8027 (Zhengzhou)
10.254.185.70:15970 | | +| Hebei | 192.168.30.150:8027 | 10.7.50.172:8027 (Tangshan)
10.7.35.172:8027 (Qinhuangdao) | | +| Shandong | | 124.132.240.66:15970
61.156.103.83:8027 (Qingdao)
119.184.120.108:8027 (Rizhao) | | +| Shanxi | 10.56.17.68:8027 | 10.112.7.159:8027 | | +| Shaanxi | 113.136.29.140:8027 (Xi'an)
113.136.242.134:8027 (Xi'an) | | | +| Guangdong| 183.59.156.166:8027 (Guangzhou)
183.59.160.61:8027 (Shenzhen)
183.59.168.166:8027 (Dongguan) | | | +| Guangxi | 180.141.207.228:8027
180.141.206.228:8027
113.15.79.82:8027
171.104.238.90:8027 (Liuzhou)
10.255.136.86:8027 (Liuzhou)
10.255.165.82:8027 (Fangchenggang) | | | +| Sichuan | 182.139.234.40:8027 (Chengdu)
182.139.229.78:8027 (Chengdu)
220.167.81.247:8027 (Chengdu)
118.123.55.74:8027 (Chengdu)
118.119.188.42:8027 (Emeishan)
118.119.178.42:8027 (Leshan)
182.128.24.170:8027 (Guangyuan) | | 183.223.164.65:8027 | +| Chongqing| 172.23.35.216:15970 (Yongchuan)
172.23.2.138:8027 (Dazu) | 123.147.117.148:15970 | 172.16.4.155:8027 | +| Guizhou | 10.255.133.132:15970
10.255.5.32:8027 | | 117.187.29.36:15970 (Qiannan) | +| Anhui | 117.71.18.200:15970 | | | +| Liaoning | 10.255.128.136:8027 (Shenyang)
10.255.132.132:15970 (Shenyang) | 218.24.21.133:15970 | | +| Jilin | | | 111.26.238.155:8027 | +| Gansu | 125.76.62.60:8027 | | | +| Qinghai | 125.72.115.252:158
125.72.108.212:15970 (Xining) | | | diff --git a/docs/en/configuration.md b/docs/en/configuration.md new file mode 100644 index 0000000..8eec9c2 --- /dev/null +++ b/docs/en/configuration.md @@ -0,0 +1,276 @@ +# Configuration Reference + +Language: [中文](../configuration.md) | [English](configuration.md) + +rtp2httpd can be configured via command-line options or a configuration file. + +## Command-Line Options + +```bash +rtp2httpd [options] +``` + +### Network + +- `-l, --listen [address:]port` - Bind listen address and port (default: *:5140) +- `-m, --maxclients ` - Maximum concurrent clients (default: 5) +- `-w, --workers ` - Worker process count (default: 1) + +#### Upstream Interface Settings + +- `-i, --upstream-interface ` - Default upstream interface (applies to all traffic types, lowest priority) +- `-f, --upstream-interface-fcc ` - FCC upstream interface (overrides `-i`) +- `-t, --upstream-interface-rtsp ` - RTSP upstream interface (overrides `-i`) +- `-r, --upstream-interface-multicast ` - Multicast upstream interface (overrides `-i`) +- `-y, --upstream-interface-http ` - HTTP proxy upstream interface (overrides `-i`) + +**Priority rules**: `upstream-interface-{fcc,rtsp,multicast,http}` > `upstream-interface` > system routing table + +### Performance + +- `-b, --buffer-pool-max-size ` - Max buffer pool size (default: 16384) + - Each buffer is 1536 bytes; 16384 buffers use about 24MB + - Increase for higher throughput with many clients +- `-B, --udp-rcvbuf-size ` - UDP socket receive buffer size (default: 524288 = 512KB) + - Applies to multicast, FCC, RTSP RTP/RTCP UDP sockets + - For a 30 Mbps 4K IPTV stream, 512KB provides ~140ms buffering + - Increase to reduce packet loss for high-bitrate streams + - Actual size may be limited by `net.core.rmem_max` +- `-Z, --zerocopy-on-send` - Enable zero-copy send for performance (default: off) + - Requires kernel support for MSG_ZEROCOPY (Linux 4.14+) + - Improves throughput and reduces CPU on supported systems + - Not recommended if rtp2httpd is behind a reverse proxy (nginx/caddy/lucky, etc.) + +### FCC Fast Channel Change + +- `-P, --fcc-listen-port-range ` - FCC UDP listen port range (default: random port) + +### Service Control + +- `-c, --config ` - Config file path (default `/etc/rtp2httpd.conf`) +- `-C, --noconfig` - Do not read the config file + +### Logging + +- `-v, --verbose` - Verbosity (0=FATAL, 1=ERROR, 2=WARN, 3=INFO, 4=DEBUG) +- `-q, --quiet` - Only show fatal errors + +### Security + +- `-H, --hostname ` - Validate HTTP Host header +- `-X, --xff` - Enable X-Forwarded-For parsing +- `-T, --r2h-token ` - HTTP auth token (all requests must include the r2h-token query parameter) +- `-s, --status-page-path ` - Status page and API base path (default: /status) +- `-p, --player-page-path ` - Built-in player page path (default: /player) + +### Compatibility + +- `-U, --noudpxy` - Disable UDPxy compatibility mode (only services defined in `[services]` or `external-m3u` can be used) + +### RTSP NAT Traversal + +- `-N, --rtsp-stun-server ` - STUN server address (default: disabled) + - If the RTSP server only supports UDP transport and the client is behind NAT, STUN may help (not guaranteed) + - Format: `host:port` or `host` (default port 3478) + - Examples: `stun.miwifi.com` or `stun.miwifi.com:3478` + +### Other + +- `-S, --video-snapshot` - Enable video snapshot feature (default: off) +- `-F, --ffmpeg-path ` - FFmpeg executable path (default: ffmpeg) +- `-A, --ffmpeg-args ` - Extra FFmpeg args (default: -hwaccel none) +- `-h, --help` - Show help + +## Configuration File Format + +Config file path: `/etc/rtp2httpd.conf`. Lines starting with `#` or `;` are comments. + +```ini +[global] +# Verbosity: 0=FATAL 1=ERROR 2=WARN 3=INFO 4=DEBUG +verbosity = 3 + +# Max concurrent clients +maxclients = 20 + +# UDPxy compatibility +udpxy = yes + +# Worker process count (default: 1) +workers = 1 + +# Validate HTTP Host header (default: none) +hostname = somehost.example.com + +# When enabled, use X-Forwarded-For as the client address for the status page (default: no) +# Also accept X-Forwarded-Host / X-Forwarded-Proto as the playlist.m3u prefix +# Recommended only when behind a reverse proxy +xff = no + +# HTTP auth token (optional, default: none) +# When set, all HTTP requests must include r2h-token query parameter matching this value +# Example: +# http://server:5140/rtp/239.253.64.120:5140?fcc=10.255.14.152:15970&r2h-token=your-secret-token +# http://server:5140/player?r2h-token=your-secret-token +r2h-token = your-secret-token-here + +# Status page path (default: /status) +status-page-path = /status + +# Player page path (default: /player) +player-page-path = /player + +# Upstream interface configuration (optional) +# +# Simple: configure one default interface for all traffic +upstream-interface = eth0 +# +# Advanced: dedicated interfaces for each traffic type +# Note: dedicated interfaces have higher priority than the default +# upstream-interface-multicast = eth0 # Multicast (RTP/UDP) +# upstream-interface-fcc = eth1 # FCC +# upstream-interface-rtsp = eth2 # RTSP +# upstream-interface-http = eth3 # HTTP proxy +# +# Mixed example: default eth0, FCC uses faster eth1 +# upstream-interface = eth0 +# upstream-interface-fcc = eth1 +# +# Priority: upstream-interface-{multicast,fcc,rtsp,http} > upstream-interface > system routing table + +# External M3U (supports file://, http://, https://) +# Note: HTTP/HTTPS requires curl +external-m3u = https://example.com/iptv.m3u +# Or a local file +external-m3u = file:///path/to/playlist.m3u + +# External M3U refresh interval (seconds) +# Default 7200 (2 hours), set to 0 to disable auto-update +external-m3u-update-interval = 7200 + +# Periodic multicast re-join interval (seconds, default: 0 disabled) +# Set a positive value (e.g., 60) to periodically re-join multicast groups +# Compatibility workaround for: +# - IGMP snooping switches timing out without router IGMP Query +# - Misconfigured devices dropping multicast membership +# Recommended: 30-120 seconds (less than typical 260-second switch timeout) +# Note: disabled by default (0), enable only if multicast streams are interrupted +mcast-rejoin-interval = 0 + +# FCC media listen port range (optional, format: start-end, default: random) +fcc-listen-port-range = 40000-40100 + +# Max buffer pool size (default: 16384) +# Each buffer is 1536 bytes; 16384 buffers use about 24MB +# Increase for higher throughput, e.g., 32768 or higher +buffer-pool-max-size = 16384 + +# UDP socket receive buffer size (default: 524288 = 512KB) +# Applies to multicast, FCC, RTSP RTP/RTCP UDP sockets +# For a 30 Mbps 4K IPTV stream, 512KB provides ~140ms buffering +# Increase to reduce packet loss on high-bitrate streams +# Actual size may be limited by net.core.rmem_max +udp-rcvbuf-size = 524288 + +# Enable zero-copy send (default: no) +# Set yes/true/on/1 to enable +# Requires MSG_ZEROCOPY (Linux 4.14+) +# Improves throughput and reduces CPU, especially under high concurrency +# Not recommended if rtp2httpd is behind a reverse proxy (nginx/caddy/lucky, etc.) +zerocopy-on-send = no + +# STUN server for RTSP NAT traversal (default: disabled) +# If the RTSP server only supports UDP and the client is behind NAT, STUN may help (not guaranteed) +# Format: host:port or host (default port 3478) +rtsp-stun-server = stun.miwifi.com + +# Enable video snapshots (default: no) +# When enabled, use the `snapshot=1` query parameter to fetch real-time snapshots +video-snapshot = no + +# FFmpeg executable path (default: ffmpeg, via system PATH) +# Set a full path if ffmpeg is not in PATH or you need a specific version +ffmpeg-path = /usr/bin/ffmpeg + +# Extra FFmpeg args (default: -hwaccel none) +# These args are passed to ffmpeg when generating snapshots +# Common: -hwaccel none, -hwaccel auto, -hwaccel vaapi, -hwaccel qsv +ffmpeg-args = -hwaccel none + +[bind] +# Listen on 5140 for all addresses +* 5140 + +# Listen on 8081 for a specific IP +192.168.1.1 8081 + +# Multiple listen addresses supported + +# [services] can embed an M3U playlist starting with #EXTM3U +# Similar to external-m3u, but M3U is in the config file +[services] +#EXTM3U x-tvg-url="https://example.com/epg.xml.gz" +#EXTINF:-1 tvg-id="CCTV1" tvg-name="CCTV1" tvg-logo="https://example.com/logo/CCTV1.png" group-title="CCTV" catchup="default" catchup-source="rtsp://10.0.0.50:554/catchup?playseek={utc:YmdHMS}-{utcend:YmdHMS}",CCTV-1 +rtp://239.253.64.120:5140 +#EXTINF:-1 tvg-id="CCTV2" tvg-name="CCTV2" group-title="CCTV",CCTV-2 +rtp://239.253.64.121:5140 +``` + +## Configuration Priority + +1. Command-line options (highest) +2. Config file +3. Built-in defaults (lowest) + +## Public Access Recommendations + +If you expose the service to the public internet, it is recommended to change `hostname` / `r2h-token` / `status-page-path` / `player-page-path` to improve security. + +```ini +[global] +hostname = iptv.example.com +r2h-token = my-secret-token-12345 +status-page-path = /my-status-page +player-page-path = /my-player +``` + +If possible, use a reverse proxy such as nginx / lucky / caddy and enable `xff`. + +```ini +[global] +xff = yes +``` + +Ensure the reverse proxy forwards `X-Forwarded-For` / `X-Forwarded-Host` / `X-Forwarded-Proto`. For lucky, enable the "Wan Shi Da Ji" option. For nginx, here is an example: + +```nginx +server { + listen 80; + server_name iptv.example.com; + + location / { + proxy_pass http://127.0.0.1:5140; + proxy_http_version 1.1; + + # Forward client IP and scheme headers + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Proto $scheme; + + # Streaming optimizations + proxy_buffering off; + } +} +``` + +## Performance Tuning + +Consider tuning kernel parameters. Enabling [BBR](https://blog.clash-plus.com/post/openwrt-bbr/) can improve stability and reduce startup latency on public networks. + +## Related Docs + +- [Quick Start](quick-start.md): Basic configuration guide +- [M3U Integration](m3u-integration.md): M3U configuration details +- [FCC Setup](fcc-setup.md): FCC-related configuration +- [Video Snapshots](video-snapshot.md): Video snapshot configuration diff --git a/docs/en/fcc-setup.md b/docs/en/fcc-setup.md new file mode 100644 index 0000000..018569a --- /dev/null +++ b/docs/en/fcc-setup.md @@ -0,0 +1,138 @@ +# FCC Fast Channel Change Setup + +Language: [中文](../fcc-setup.md) | [English](fcc-setup.md) + +FCC (Fast Channel Change) is a carrier-grade protocol that enables millisecond-level channel switching. Most IPTV set-top boxes in China rely on FCC for fast channel changes. + +## How FCC Works + +On channel switch, the client first requests an FCC server to get a unicast video stream. The FCC server immediately sends IDR frames and initial data for instant decode. Once the unicast stream synchronizes with the multicast stream, it switches over seamlessly to multicast. + +You must find the FCC server for the corresponding multicast source before using FCC. + +## How to Find FCC Servers + +### Method 1: Use a Known FCC List + +Check the [Mainland China FCC server list](./cn-fcc-collection.md) to see if there is a local address available. + +### Method 2: Capture from a Set-Top Box + +If your region is not listed, you can capture traffic from an IPTV set-top box. + +#### Capture with Wireshark + +1. **Install Wireshark** on your PC. + +2. **Connect the set-top box**: + + - Option 1: Use a network tap or mirrored port + - Option 2: Set your PC as the set-top box gateway (MITM capture) + + There are many network tutorials for these methods. + +3. **Find the channel list request and search for fields**: + + - Look for `ChannelFCCIP`: FCC server IP address + - Look for `ChannelFCCPort`: FCC server port + +4. **Or identify FCC protocol packets directly**: + + - Trigger FCC by switching channels and capture FCC packets directly + - Install the [Wireshark FCC protocol plugin](../../wireshark-support/README.md) + - Filter by `fcc`, then record the peer IP and port + +## Configure and Use FCC + +### Specify FCC Server in the URL + +```url +http://server:port/rtp/multicast:port?fcc=FCC-IP:port[&fcc-type=protocol] +``` + +**Examples**: + +```url +# Telecom FCC (auto-detect) +http://192.168.1.1:5140/rtp/239.253.64.120:5140?fcc=10.255.14.152:15970 + +# Huawei FCC (auto-detect) +http://192.168.1.1:5140/rtp/239.253.64.120:5140?fcc=10.255.14.152:8027 + +# Force Huawei FCC protocol +http://192.168.1.1:5140/rtp/239.253.64.120:5140?fcc=10.255.14.152:8027&fcc-type=huawei + +# Force Telecom FCC protocol +http://192.168.1.1:5140/rtp/239.253.64.120:5140?fcc=10.255.14.152:15970&fcc-type=telecom +``` + +#### fcc-type Parameter + +- **telecom** or omitted: Telecom/ZTE/FiberHome FCC protocol +- **huawei**: Huawei FCC protocol + +In most cases, `telecom` works. Some specific networks require `huawei`. + +### Configure FCC in M3U + +If you use an M3U playlist, add the FCC parameters to each channel URL: + +```m3u +#EXTM3U +#EXTINF:-1,CCTV-1 (Telecom FCC) +http://192.168.1.1:5140/rtp/239.253.64.120:5140?fcc=10.255.14.152:15970 +#EXTINF:-1,CCTV-2 (Huawei FCC) +http://192.168.1.1:5140/rtp/239.253.64.121:5140?fcc=10.255.14.152:8027 +``` + +## NAT Traversal + +### Huawei FCC Protocol + +The Huawei FCC protocol supports NAT traversal natively, so it works behind NAT without port forwarding. Huawei FCC only works on Huawei IPTV platforms. + +### Telecom FCC Protocol + +If you use the Telecom/ZTE/FiberHome FCC protocol and rtp2httpd runs behind a router (e.g., NAS, PC) while the upstream router connects to the IPTV network, port forwarding is required for FCC to work. + +Most IPTV platforms (including Huawei) also support the Telecom FCC protocol. + +You must also configure IGMP / multicast forwarding (`igmpproxy` / `omcproxy`) to receive multicast streams. + +#### Configuration Steps + +First, set `--fcc-listen-port-range` manually: + +```bash +# Command line +rtp2httpd --fcc-listen-port-range 40000-40100 + +# Config file +[global] +fcc-listen-port-range = 40000-40100 +``` + +Then configure port forwarding on the upstream router to forward this port range (e.g., `40000-40100`) to the device running rtp2httpd. + +> **Tip**: If your environment needs NAT traversal and the FCC server supports both protocols, prefer the Huawei FCC protocol (port 8027) to avoid port forwarding. + +## Test Whether FCC Works + +1. **Use a fast-start player**: The player must be fast enough to avoid becoming the bottleneck. + +2. **Observe channel switch speed**: + + - FCC enabled: switch delay < 1s + - FCC disabled: 2-5 seconds + +3. **Check logs**: + + - `FCC: Unicast stream started successfully` means the FCC address is valid and unicast streaming succeeded. + - `FCC: Server response timeout (80 ms), falling back to multicast` can mean: + 1. The FCC address is invalid. + 2. Your network is not configured correctly and cannot reach the FCC server. In general, you must obtain an IPTV intranet IP via DHCP/IPoE/PPPoE and enable `--upstream-interface-fcc` or `--upstream-interface` to bind the IPTV interface. Use ping/traceroute to verify. + +## Related Docs + +- [URL Formats](url-formats.md): FCC URL format +- [Configuration Reference](configuration.md): FCC-related options diff --git a/docs/en/installation.md b/docs/en/installation.md new file mode 100644 index 0000000..374481b --- /dev/null +++ b/docs/en/installation.md @@ -0,0 +1,204 @@ +# Installation + +Language: [中文](../installation.md) | [English](installation.md) + +rtp2httpd supports multiple installation methods for different environments. + +## OpenWrt Router Deployment + +OpenWrt is the best runtime environment for rtp2httpd. After IPTV network integration (search for "OpenWrt IPTV integration" guides), once you obtain an IPTV intranet IP via DHCP, you can access the entire IPTV network without NAT traversal. + +The minimum supported OpenWrt version is 21.02. On lower versions, the LuCI UI may not load. You can still edit `/etc/config/rtp2httpd` manually and restart via `/etc/init.d/rtp2httpd restart`. + +### One-Command Install Script + +Use the script to download and install the latest version. If rtp2httpd is already installed, rerun the script to upgrade. + +```bash +uclient-fetch -q -O - https://raw.githubusercontent.com/stackia/rtp2httpd/main/scripts/install-openwrt.sh | sh +``` + +The script will: + +- Detect CPU architecture +- Fetch the latest release from GitHub +- Download and install required packages (core + LuCI + language packs) + +
+Use prerelease builds (click to view) + +```bash +uclient-fetch -q -O - https://raw.githubusercontent.com/stackia/rtp2httpd/main/scripts/install-openwrt.sh | sh -s -- --prerelease +``` + +
+ +### Manual Install + +If you cannot use the script, download packages for your architecture from [Releases](https://github.com/stackia/rtp2httpd/releases): + +- `rtp2httpd_x.y.z-1_.ipk` - Core package +- `luci-app-rtp2httpd_x.y.z_all.ipk` - LuCI web UI +- `luci-i18n-rtp2httpd-en_x.y.z_all.ipk` - English language pack +- `luci-i18n-rtp2httpd-zh-cn_x.y.z_all.ipk` - Chinese language pack + +```bash +opkg install rtp2httpd_*.ipk luci-app-rtp2httpd_*.ipk luci-i18n-rtp2httpd-*.ipk +``` + +## Static Binary Deployment + +Download the static binary `rtp2httpd--` from [Releases](https://github.com/stackia/rtp2httpd/releases), upload it to your device, and `chmod +x`. + +By default, it reads `/etc/rtp2httpd.conf`. Override with `--config` or `--noconfig`. + +**Example**: + +```bash +# Download binary +wget https://github.com/stackia/rtp2httpd/releases/download/vX.Y.Z/rtp2httpd-X.Y.Z-x86_64 +chmod +x rtp2httpd-X.Y.Z-x86_64 + +# Run with config file +./rtp2httpd-X.Y.Z-x86_64 --config /path/to/rtp2httpd.conf + +# Run with CLI arguments only +./rtp2httpd-X.Y.Z-x86_64 --noconfig --verbose 2 --listen 5140 --maxclients 20 +``` + +Tip: Use the sample config [rtp2httpd.conf](../../rtp2httpd.conf) as a starting point. See [Configuration Reference](configuration.md). + +## Docker Deployment + +Use Docker on supported devices. **Host networking is required** to receive multicast. + +### Basic Run + +```bash +docker run --network=host --cap-add=NET_ADMIN --ulimit memlock=-1:-1 --rm \ + ghcr.io/stackia/rtp2httpd:latest \ + --noconfig --verbose 2 --listen 5140 --maxclients 20 +``` + +### docker-compose + +```yaml +services: + rtp2httpd: + image: ghcr.io/stackia/rtp2httpd:latest + network_mode: host + restart: unless-stopped + cap_add: + - NET_ADMIN + ulimits: + memlock: + soft: -1 + hard: -1 + command: --noconfig --verbose 2 --listen 5140 --maxclients 20 +``` + +> **Recommended flags**: +> +> - `cap_add: NET_ADMIN`: Allows `SO_RCVBUFFORCE` to bypass `net.core.rmem_max` for larger UDP receive buffers +> - `ulimits: memlock: -1`: Required for zero-copy (`--zerocopy-on-send`), MSG_ZEROCOPY needs locked pages + +### Mount a Config File + +If you want to use a config file (assume `/path/to/rtp2httpd.conf`): + +```bash +docker run --network=host --cap-add=NET_ADMIN --ulimit memlock=-1:-1 --rm \ + -v /path/to/rtp2httpd.conf:/usr/local/etc/rtp2httpd.conf:ro \ + ghcr.io/stackia/rtp2httpd:latest +``` + +Tip: Use the sample config [rtp2httpd.conf](../../rtp2httpd.conf) as a starting point. See [Configuration Reference](configuration.md). + +## OpenWrt Build From Source + +If you want to compile rtp2httpd into an OpenWrt firmware image, add this repo to `feeds.conf.default`: + +```text +# Use latest main branch +src-git rtp2httpd https://github.com/stackia/rtp2httpd.git +``` + +Or pin a version: + +```text +# Use v3.1.1 code +src-git rtp2httpd https://github.com/stackia/rtp2httpd.git;v3.1.1 +``` + +Run `./scripts/feeds update rtp2httpd` and `./scripts/feeds install rtp2httpd`. + +Run `make menuconfig`, go to `LuCI -> Applications -> luci-app-rtp2httpd`, and select `*` (built-in) or `M` (as package), then save. + +Run `make package/feeds/rtp2httpd/luci-app-rtp2httpd/compile -j1 V=sc` to compile `luci-app-rtp2httpd` and `rtp2httpd`. + +### Firmware Maintainer Integration Guide + +If you maintain third-party OpenWrt firmware and want to integrate rtp2httpd directly into your feeds (instead of `src-git`), use the provided `Makefile.versioned`: + +```bash +git clone https://github.com/stackia/rtp2httpd.git +cd rtp2httpd + +# Replace Makefiles with pre-generated versions (fixed version, download URL, PKG_HASH) +mv openwrt-support/rtp2httpd/Makefile.versioned openwrt-support/rtp2httpd/Makefile +mv openwrt-support/luci-app-rtp2httpd/Makefile.versioned openwrt-support/luci-app-rtp2httpd/Makefile + +# Copy openwrt-support into your feeds repo +cp -r openwrt-support/* /path/to/your/feeds/ +``` + +`Makefile.versioned` differs from the original `Makefile` by pinning the version and `PKG_HASH`, and downloading source from GitHub Releases instead of a local git repo. It is updated on main with each release. + +## Traditional Build and Install + +For custom builds or development. + +### Dependencies + +```bash +# Ubuntu/Debian +sudo apt-get install build-essential autoconf automake pkg-config curl + +# Install Node.js LTS (for Web UI build) +curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash - +sudo apt-get install -y nodejs +corepack enable +``` + +### Build Steps + +```bash +# Clone repo +git clone https://github.com/stackia/rtp2httpd.git +cd rtp2httpd + +# Build frontend and embed assets +pnpm --prefix web-ui install --frozen-lockfile +pnpm --prefix web-ui run build + +# Generate build scripts +autoreconf -fi + +# Configure and build +./configure --enable-optimization=-O3 +make + +# Install +sudo make install +``` + +### Optional Dependencies + +- **curl** or **uclient-fetch** or **wget**: For external M3U playlists (HTTP/HTTPS) +- **ffmpeg**: For video snapshots + +## Next Steps + +- [Quick Start](quick-start.md): OpenWrt quick configuration +- [Configuration Reference](configuration.md): All configuration options +- [URL Formats](url-formats.md): Supported URL formats diff --git a/docs/en/m3u-integration.md b/docs/en/m3u-integration.md new file mode 100644 index 0000000..ae65f0d --- /dev/null +++ b/docs/en/m3u-integration.md @@ -0,0 +1,349 @@ +# M3U Playlist Integration + +Language: [中文](../m3u-integration.md) | [English](m3u-integration.md) + +rtp2httpd fully supports M3U/M3U8 playlists. It detects channels and provides a converted playlist so you can import external M3U lists, automatically replace URLs, and use them directly in IPTV players. + +## Core Capabilities + +- **External M3U integration**: Load M3U from external URLs (`file://`, `http://`, `https://`) +- **Inline M3U config**: Write M3U content directly in the config file +- **Built-in web player**: Open `/player` in a browser +- **Smart URL conversion**: Automatically detect RTP/RTSP and convert to HTTP proxy URLs +- **Catchup support**: Full support for `catchup-source` with automatic catchup services +- **Auto-update**: External M3U can be refreshed on a schedule (default 24 hours) +- **URL preservation**: Unknown URLs (e.g., third-party HTTP streams) are kept as-is + +## Configuration + +### Method 1: External M3U + +Specify an external M3U URL in the config file: + +```ini +[global] +# External M3U (file://, http://, https://) +# Note: HTTP/HTTPS requires curl or uclient-fetch or wget +external-m3u = https://example.com/iptv.m3u +# Or a local file +external-m3u = file:///path/to/playlist.m3u + +# External M3U refresh interval (seconds) +# Default 7200 (2 hours), set to 0 to disable auto-update +external-m3u-update-interval = 7200 +``` + +### Method 2: Inline M3U in Config + +Write M3U content directly under `[services]`: + +```ini +[services] +# Inline M3U content, starting with #EXTM3U +#EXTM3U x-tvg-url="https://example.com/epg.xml.gz" + +# Basic channel config +#EXTINF:-1 tvg-id="CCTV1" tvg-name="CCTV1" tvg-logo="https://example.com/logo/CCTV1.png" group-title="央视",CCTV-1 +rtp://239.253.64.120:5140 + +# Channel with catchup +#EXTINF:-1 tvg-id="CCTV2" tvg-name="CCTV2" group-title="央视" catchup="default" catchup-source="rtsp://10.0.0.50:554/catchup?playseek={utc:YmdHMS}-{utcend:YmdHMS}",CCTV-2 +rtp://239.253.64.121:5140 + +# Simple config (channel name only) +#EXTINF:-1,广东卫视 +rtp://239.194.10.15:1234 +``` + +## Using the Playlist + +### Option 1: Built-in Player + +After configuring M3U, open the built-in player: + +``` +http://server:port/player +``` + +**Example**: + +``` +http://192.168.1.1:5140/player +``` + +Built-in player features: + +- Automatically loads the configured M3U channel list +- Supports live and catchup playback +- Supports FCC fast start +- Modern responsive UI for mobile and desktop +- Custom player path (via `player-page-path`, see [Configuration Reference](configuration.md)) + +**Note**: Playback depends on the browser's native decoding. Some codecs (e.g., MP2, E-AC3) may not play in certain browsers. Use recent Chrome, Edge, or Safari. + +### Option 2: Use Converted Playlist in Other Players + +The converted M3U playlist is available at: + +``` +http://server:port/playlist.m3u +``` + +**Example**: + +``` +http://192.168.1.1:5140/playlist.m3u +``` + +Add this URL to any M3U-capable IPTV player (e.g., APTV, TiviMate). + +## Conversion Example + +### Input M3U + +```m3u +#EXTM3U x-tvg-url="https://example.com/epg.xml.gz" + +#EXTINF:-1 tvg-id="CCTV1" tvg-name="CCTV1" tvg-logo="https://example.com/logo/CCTV1.png" group-title="央视" catchup="default" catchup-source="rtsp://10.0.0.50:554/catchup?auth=loremipsum&playseek={utc:YmdHMS}-{utcend:YmdHMS}",CCTV-1 +rtp://239.253.64.120:5140 + +#EXTINF:-1 tvg-id="CCTV2" tvg-name="CCTV2" group-title="央视",CCTV-2 +rtp://239.253.64.121:5140 + +#EXTINF:-1 tvg-id="Other" tvg-name="其他频道",第三方频道 +http://other-cdn.com/live/stream.m3u8 +``` + +### Output M3U (Converted) + +```m3u +#EXTM3U x-tvg-url="http://192.168.1.1:5140/epg.xml.gz" + +#EXTINF:-1 tvg-id="CCTV1" tvg-name="CCTV1" tvg-logo="https://example.com/logo/CCTV1.png" group-title="央视" catchup="default" catchup-source="http://192.168.1.1:5140/CCTV-1/catchup?playseek={utc:YmdHMS}-{utcend:YmdHMS}",CCTV-1 +http://192.168.1.1:5140/央视/CCTV-1 + +#EXTINF:-1 tvg-id="CCTV2" tvg-name="CCTV2" group-title="央视",CCTV-2 +http://192.168.1.1:5140/央视/CCTV-2 + +#EXTINF:-1 tvg-id="Other" tvg-name="其他频道",第三方频道 +http://other-cdn.com/live/stream.m3u8 +``` + +**Notes**: + +- The EPG URL is converted to the rtp2httpd proxy +- CCTV-1 and CCTV-2 URLs are converted to rtp2httpd proxies +- CCTV-1 catchup-source is converted and dynamic placeholders are preserved +- Third-party channel URLs are unchanged + +## Usage Tips + +1. **HTTP/HTTPS support** + - Requires `curl` or `uclient-fetch` or `wget` + - rtp2httpd auto-detects available tools + +2. **Update strategy** + - External M3U auto-update defaults to 24 hours + - Adjust `external-m3u-update-interval` based on source update frequency + - Set to 0 to disable auto-update (restart service to refresh) + +3. **Mixed usage** + - External and inline M3U can both be configured + - They are merged into a single converted playlist + +4. **Enable `xff` behind a reverse proxy** + - M3U conversion needs the full access URL. If you use a reverse proxy, enable `xff` and ensure `X-Forwarded-*` headers are passed through. See [Public Access Recommendations](configuration.md#public-access-recommendations). + +## URL Detection and Conversion Rules + +### Supported URL Formats + +rtp2httpd recognizes and converts these URL formats: + +1. **Direct protocol URLs**: + - `rtp://[source@]multicast_addr:port[?query]` + - `rtsp://server:port/path[?query]` + - `udp://multicast_addr:port[?query]` + +2. **UDPxy-style HTTP URLs**: + - `http://hostname:port/rtp/multicast_addr:port` + - `http://hostname:port/rtsp/server:port/path` + - `hostname:port` is replaced with the actual rtp2httpd address and port + +### Conversion Examples + +| Original URL | Converted URL | +| -------------------------------------------- | ----------------------------------------- | +| `rtp://239.253.64.120:5140` | `http://hostname:5140/CCTV-1` | +| `rtsp://10.0.0.50:554/live` | `http://hostname:5140/CCTV-2` | +| `http://router:5140/rtp/239.1.1.1:1234` | `http://hostname:5140/频道名` | +| `http://other-server/stream.m3u8` (3rd-party) | `http://other-server/stream.m3u8` (unchanged) | + +**Service name extraction**: Uses the text after the last comma in the `#EXTINF` line. + +``` +#EXTINF:-1 tvg-id="..." tvg-name="..." group-title="...",CCTV-1 + ^^^^^^ + Service name +``` + +## Catchup Support + +When `catchup-source` is present, rtp2httpd creates corresponding catchup services. + +### Example + +```m3u +#EXTINF:-1 tvg-id="CCTV1" catchup="default" catchup-source="rtsp://10.0.0.50:554/catchup?playseek={utc:YmdHMS}-{utcend:YmdHMS}",CCTV-1 +rtp://239.253.64.120:5140 +``` + +### Result + +- **Live service**: `http://hostname:5140/CCTV-1` +- **Catchup service**: `http://hostname:5140/CCTV-1/catchup?playseek={utc:YmdHMS}-{utcend:YmdHMS}` + +### Placeholder Handling + +- **Dynamic placeholders** (contain `{` or `}`) are preserved in converted URLs for the player to fill + - Example: `{utc:YmdHMS}`, `{utcend:YmdHMS}` +- **Static parameters**: Other query parameters are not preserved in the converted M3U, but are still used when fetching upstream content + +### Unrecognized URL Handling + +If `catchup-source` is a third-party HTTP URL (e.g., `http://other-cdn.com/catchup`), it is kept as-is and not converted. + +## Line Labels + +Append a `$label` suffix to a URL to display a source label (e.g., resolution). The `$label` must be at the very end of the URL. + +This is only effective in players that support labels and channel aggregation (such as the built-in web player). + +### Example Input + +```m3u +#EXTINF:-1 tvg-id="广东卫视" tvg-name="广东卫视" tvg-logo="https://example.com/logo/广东卫视.png" group-title="卫视",广东卫视 +rtp://239.253.64.96:5140/?fcc=10.255.75.73:15970$超高清 +#EXTINF:-1 tvg-id="广东卫视" tvg-name="广东卫视" tvg-logo="https://example.com/logo/广东卫视.png" group-title="卫视",广东卫视 +rtp://239.253.64.200:5140/?fcc=10.255.75.73:15970$高清 +#EXTINF:-1 tvg-id="广东卫视" tvg-name="广东卫视" tvg-logo="https://example.com/logo/广东卫视.png" group-title="卫视",广东卫视 +rtp://239.253.64.44:5140/?fcc=10.255.75.73:15970$标清 +``` + +### Example Output + +Each `$label` channel generates an independent service path. `$label` becomes a `/label` subpath, while `$label` remains at the end of the converted URL: + +```m3u +#EXTINF:-1 tvg-id="广东卫视" tvg-name="广东卫视" tvg-logo="https://example.com/logo/广东卫视.png" group-title="卫视",广东卫视 +http://192.168.1.1:5140/卫视/广东卫视/超高清$超高清 + +#EXTINF:-1 tvg-id="广东卫视" tvg-name="广东卫视" tvg-logo="https://example.com/logo/广东卫视.png" group-title="卫视",广东卫视 +http://192.168.1.1:5140/卫视/广东卫视/高清$高清 + +#EXTINF:-1 tvg-id="广东卫视" tvg-name="广东卫视" tvg-logo="https://example.com/logo/广东卫视.png" group-title="卫视",广东卫视 +http://192.168.1.1:5140/卫视/广东卫视/标清$标清 +``` + +### Built-in Player Channel Aggregation + +> **Note**: Channel aggregation is a **built-in web player** feature, not a server-side behavior of rtp2httpd. Whether third-party players (e.g., APTV, TiviMate) support similar aggregation depends on their own implementation. rtp2httpd only parses `$label`, generates separate service paths, and preserves `$label` in the converted M3U. + +When the M3U contains multiple channels with the same group and name, the built-in player aggregates them into a single channel with multiple sources, shown once in the list. Users can switch sources (e.g., resolutions) in the source selector: + +Channel Source Selector + +If the source URL has a `$label` suffix, the player displays it as a label (e.g., "超高清", "高清", "标清"). Sources without `$label` are displayed with numeric labels (e.g., "Line 1", "Line 2"). + +## Time Placeholders Supported by the Built-in Player + +The built-in web player supports the following time placeholder formats for `catchup-source` URLs: + +### `${}` Format (long format) + +| Placeholder | Description | Example output | +| -------------------------------- | ------------------------------------------- | ------------------------- | +| `${utc}` | Program start time (UTC, ISO8601) | 2025-01-15T10:30:45.000Z | +| `${utc:yyyyMMddHHmmss}` | Program start time (UTC, custom long format)| 20250115103045 | +| `${utcend}` | Program end time (UTC, ISO8601) | 2025-01-15T12:30:45.000Z | +| `${utcend:yyyyMMddHHmmss}` | Program end time (UTC, custom long format) | 20250115123045 | +| `${start}` | Same as `${utc}` | 2025-01-15T10:30:45.000Z | +| `${start:yyyyMMddHHmmss}` | Same as `${utc:yyyyMMddHHmmss}` | 20250115103045 | +| `${end}` | Same as `${utcend}` | 2025-01-15T12:30:45.000Z | +| `${end:yyyyMMddHHmmss}` | Same as `${utcend:yyyyMMddHHmmss}` | 20250115123045 | +| `${lutc}` | Current time (UTC, ISO8601) | 2025-01-15T14:00:00.000Z | +| `${lutc:yyyyMMddHHmmss}` | Current time (UTC, custom long format) | 20250115140000 | +| `${now}` | Same as `${lutc}` | 2025-01-15T14:00:00.000Z | +| `${now:yyyyMMddHHmmss}` | Same as `${lutc:yyyyMMddHHmmss}` | 20250115140000 | +| `${timestamp}` | Current Unix timestamp (seconds) | 1736949600 | +| `${timestamp:yyyyMMddHHmmss}` | Same as `${lutc:yyyyMMddHHmmss}` | 20250115140000 | +| `${(b)yyyyMMddHHmmss}` | Program start time (local, long format) | 20250115183045 | +| `${(e)yyyyMMddHHmmss}` | Program end time (local, long format) | 20250115203045 | +| `${(b)timestamp}` | Program start Unix timestamp (seconds) | 1736937045 | +| `${(e)timestamp}` | Program end Unix timestamp (seconds) | 1736944245 | +| `${yyyy}` | Program start year (local) | 2025 | +| `${MM}` | Program start month 01-12 (local) | 01 | +| `${dd}` | Program start day 01-31 (local) | 15 | +| `${HH}` | Program start hour 00-23 (local) | 18 | +| `${mm}` | Program start minute 00-59 (local) | 30 | +| `${ss}` | Program start second 00-59 (local) | 45 | +| `${duration}` | Program duration (seconds) | 7200 | + +### `{}` Format (short format) + +| Placeholder | Description | Example output | +| --------------------- | -------------------------------------------- | ------------------------- | +| `{utc}` | Program start time (UTC, ISO8601) | 2025-01-15T10:30:45.000Z | +| `{utc:YmdHMS}` | Program start time (UTC, custom short format)| 20250115103045 | +| `{utcend}` | Program end time (UTC, ISO8601) | 2025-01-15T12:30:45.000Z | +| `{utcend:YmdHMS}` | Program end time (UTC, custom short format) | 20250115123045 | +| `{start}` | Same as `{utc}` | 2025-01-15T10:30:45.000Z | +| `{start:YmdHMS}` | Same as `{utc:YmdHMS}` | 20250115103045 | +| `{end}` | Same as `{utcend}` | 2025-01-15T12:30:45.000Z | +| `{end:YmdHMS}` | Same as `{utcend:YmdHMS}` | 20250115123045 | +| `{lutc}` | Current time (UTC, ISO8601) | 2025-01-15T14:00:00.000Z | +| `{lutc:YmdHMS}` | Current time (UTC, custom short format) | 20250115140000 | +| `{now}` | Same as `{lutc}` | 2025-01-15T14:00:00.000Z | +| `{now:YmdHMS}` | Same as `{lutc:YmdHMS}` | 20250115140000 | +| `{timestamp}` | Current Unix timestamp (seconds) | 1736949600 | +| `{timestamp:YmdHMS}` | Same as `{lutc:YmdHMS}` | 20250115140000 | +| `{(b)YmdHMS}` | Program start time (local, short format) | 20250115183045 | +| `{(e)YmdHMS}` | Program end time (local, short format) | 20250115203045 | +| `{(b)timestamp}` | Program start Unix timestamp (seconds) | 1736937045 | +| `{(e)timestamp}` | Program end Unix timestamp (seconds) | 1736944245 | +| `{Y}` | Program start year (local) | 2025 | +| `{m}` | Program start month 01-12 (local) | 01 | +| `{d}` | Program start day 01-31 (local) | 15 | +| `{H}` | Program start hour 00-23 (local) | 18 | +| `{M}` | Program start minute 00-59 (local) | 30 | +| `{S}` | Program start second 00-59 (local) | 45 | +| `{duration}` | Program duration (seconds) | 7200 | + +### Format Reference + +**Long format**: used in `${}` placeholders + +- `yyyy` - 4-digit year +- `MM` - 2-digit month (01-12) +- `dd` - 2-digit day (01-31) +- `HH` - 2-digit hour (00-23) +- `mm` - 2-digit minute (00-59) +- `ss` - 2-digit second (00-59) + +Example: `${utc:yyyyMMddHHmmss}` → `20250115103045` + +**Short format**: used in `{}` placeholders + +- `Y` - 4-digit year +- `m` - 2-digit month (01-12) +- `d` - 2-digit day (01-31) +- `H` - 2-digit hour (00-23) +- `M` - 2-digit minute (00-59) +- `S` - 2-digit second (00-59) + +Example: `{utc:YmdHMS}` → `20250115103045` + +## Related Docs + +- [URL Formats](url-formats.md): Supported URL formats +- [Configuration Reference](configuration.md): Full configuration options diff --git a/docs/en/quick-start.md b/docs/en/quick-start.md new file mode 100644 index 0000000..5d35bd6 --- /dev/null +++ b/docs/en/quick-start.md @@ -0,0 +1,91 @@ +# Quick Start + +Language: [中文](../quick-start.md) | [English](quick-start.md) + +## One-Command OpenWrt Install (Recommended) + +Use the install script to download and install the latest version: + +```bash +uclient-fetch -q -O - https://raw.githubusercontent.com/stackia/rtp2httpd/main/scripts/install-openwrt.sh | sh +``` + +The script will: + +- Detect CPU architecture +- Fetch the latest release from GitHub +- Download and install required packages (core + LuCI + language packs) + +## Basic Configuration + +After install, open LuCI and find "rtp2httpd" under the "Services" menu: + +Image + +### Required Settings + +1. **Enable**: Check to enable rtp2httpd +2. **Port**: Default 5140, can be customized +3. **Upstream interface**: Set to the IPTV network interface + +### Optional Settings + +- **External M3U**: If you have an M3U playlist, set it to use the built-in web player ([details](m3u-integration.md)) +- **FCC server**: Configure FCC for fast channel change ([how to obtain](fcc-setup.md)) +- **Video snapshots**: Enable channel preview snapshots ([setup](video-snapshot.md)) + +## Test Access + +After configuration, test with these URLs: + +```bash +# Access an RTP multicast stream +http://router-ip:5140/rtp/239.253.64.120:5140 + +# Status page +http://router-ip:5140/status + +# M3U playlist (if configured) +http://router-ip:5140/playlist.m3u + +# Built-in player (requires M3U) +http://router-ip:5140/player +``` + +## Use the Built-in Player + +If M3U is configured, open the built-in player in a browser: + +```bash +http://router-ip:5140/player +``` + +The built-in player provides: + +- Auto-loaded channel list (from configured M3U) +- Live playback +- Catchup playback (if the channel supports it) +- FCC fast channel change +- Responsive UI for mobile devices + +**Note**: Playback depends on browser decoding. Some codecs may not play. Use modern Chrome/Edge/Safari. + +## Use in Other Players + +Add `http://router-ip:5140/playlist.m3u` to any IPTV player. + +## View Logs + +You can check logs in three ways: + +1. Visit `/status` and view logs at the bottom +2. OpenWrt LuCI: "Status" -> "System Log" +3. SSH into the router and run `logread -e rtp2httpd` + +## Next Steps + +- [Installation](installation.md): Docker, static binary, source builds +- [M3U Integration](m3u-integration.md): Playlist detection and conversion +- [URL Formats](url-formats.md): Supported URL formats +- [Configuration Reference](configuration.md): All config options +- [FCC Setup](fcc-setup.md): Enable millisecond-level channel switching diff --git a/docs/en/rtsp-time-processing.md b/docs/en/rtsp-time-processing.md new file mode 100644 index 0000000..b05035b --- /dev/null +++ b/docs/en/rtsp-time-processing.md @@ -0,0 +1,205 @@ +# RTSP Time Handling and Timezone Conversion + +Language: [中文](../rtsp-time-processing.md) | [English](rtsp-time-processing.md) + +This document explains how rtp2httpd handles time parameters and timezone conversion for RTSP catchup playback. + +## IPTV RTSP Catchup Basics + +IPTV RTSP servers usually support catchup playback, allowing users to watch earlier segments. This is done by adding time range parameters (e.g., `playseek`, `tvdr`) to the RTSP URL. + +**Basic flow**: + +1. **Client request**: The client requests a specific time range. + + ``` + rtsp://iptv.example.com:554/channel1?playseek=20240101120000-20240101130000 + ``` + +2. **Server response**: The RTSP server returns recorded content for that range. + +3. **Time format requirements**: Different operators expect different formats and timezones. Some require UTC, some GMT+8, some expect `20240101120000`, others expect `20240101120000GMT`. Player support varies. If the player format/timezone does not match the operator, catchup fails. + +## What rtp2httpd Does + +As a proxy, rtp2httpd can flexibly convert time formats and timezones to match what the operator expects. + +**Key features**: + +- Auto-detects multiple time formats (Unix timestamp, yyyyMMddHHmmss, ISO 8601, etc.) +- Parses client timezone from User-Agent +- Smart timezone conversion (only for formats that need it) +- Supports extra time offsets (clock drift compensation) +- Keeps output format consistent with input format + +## Seek Parameter Configuration + +### r2h-seek-name (optional) + +Specify the RTSP seek parameter name. If not set, rtp2httpd auto-detects common names. + +#### Auto-detected names (priority order) + +1. `playseek` - most common +2. `tvdr` - used by some IPTV systems + +#### Usage + +- **Standard names**: If the RTSP server uses `playseek` or `tvdr`, no need to set this +- **Custom names**: If the server uses another name (e.g., `seek`, `timeshift`), set `r2h-seek-name` + +#### Examples + +```url +# Auto-detect playseek +http://192.168.1.1:5140/rtsp/iptv.example.com:554/channel1?playseek=20240101120000-20240101130000 + +# Auto-detect tvdr +http://192.168.1.1:5140/rtsp/iptv.example.com:554/channel1?tvdr=20240101120000-20240101130000 + +# Custom param name +http://192.168.1.1:5140/rtsp/iptv.example.com:554/channel1?custom_seek=20240101120000&r2h-seek-name=custom_seek +``` + +### r2h-seek-offset (optional) + +Extra offset in seconds applied when a seek parameter is found. Can be positive or negative. + +#### Use cases + +- **Clock drift compensation**: RTSP server time is consistently off +- **Fine tuning**: Start a few seconds earlier or later +- **Testing and debugging**: Validate different time positions + +#### Examples + +```url +# Add 1 hour (3600 seconds) to the playseek range +http://192.168.1.1:5140/rtsp/iptv.example.com:554/channel1?playseek=20240101120000-20240101130000&r2h-seek-offset=3600 + +# Subtract 30 seconds from the playseek range +http://192.168.1.1:5140/rtsp/iptv.example.com:554/channel1?playseek=20240101120000-20240101130000&r2h-seek-offset=-30 +``` + +### r2h-start (optional) + +Start playback from a specific time point for resume playback. This value is sent as an NPT (Normal Play Time) in the RTSP PLAY request header `Range: npt=