How to Build an H5 Live Streaming System with HLS, RTMP, Nginx, and FFmpeg
This guide walks through the fundamentals of HLS and RTMP protocols, compares their trade‑offs, and provides step‑by‑step instructions for setting up an Nginx‑RTMP server, configuring HLS, recording with WebRTC, and playing live streams in HTML5 video tags.
Introduction
Live video streaming has become popular, and the two dominant streaming protocols on the web are HLS (HTTP Live Streaming) and RTMP (Real‑Time Messaging Protocol). HLS is widely supported on mobile browsers, while RTMP offers lower latency on desktop browsers.
1. HLS Overview
HLS, created by Apple, delivers video over HTTP by encoding video/audio into MPEG‑2 TS segments and generating an .m3u8 playlist that references those .ts files. The playlist is repeatedly refreshed, allowing continuous playback. A typical .m3u8 file looks like:
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=200000
gear1/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=311111
gear2/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=484444
gear3/prog_index.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=737777
gear4/prog_index.m3u8Because HLS relies on HTTP, it works well across firewalls but introduces latency (typically 10‑30 seconds) due to segment length. Reducing segment size lowers latency but increases request overhead.
Basic playback in a supporting browser can be done with:
<video src="http://example.com/stream.m3u8" height="300" width="400" preload="auto" autoplay="autoplay" loop="loop" webkit-playsinline="true"></video>On non‑Safari browsers, third‑party players such as video.js with the videojs-contrib-hls plugin are required.
2. RTMP Overview
RTMP, originally from Macromedia and now Adobe, streams video over a persistent TCP connection. It provides low latency (≈2 seconds) but requires a Flash‑based player on browsers, making it unsuitable for mobile web. Native iOS apps can decode RTMP streams directly.
RTMP can be played in HTML5 via video.js with the Flash fallback:
<link href="http://vjs.zencdn.net/5.8.8/video-js.css" rel="stylesheet">
<video id="example_video_1" class="video-js vjs-default-skin" controls preload="auto" width="640" height="264" loop="loop" webkit-playsinline>
<source src="rtmp://10.14.221.17:1935/rtmplive/home" type='rtmp/flv'>
</video>
<script src="http://vjs.zencdn.net/5.8.8/video.js"></script>
<script>
videojs.options.flash.swf = 'video.swf';
videojs('example_video_1').ready(function() { this.play(); });
</script>3. Protocol Comparison
HLS : HTTP‑based, 10‑30 s latency, cross‑platform, best for mobile browsers.
RTMP : TCP‑based, ~2 s latency, low‑delay, best for desktop browsers and high‑interaction live streams.
4. Typical Live‑Streaming Architecture
Capture side : Camera or microphone on PC or mobile device.
Streaming server : Nginx with the nginx‑rtmp‑module receives the source (H.264/AAC), repackages it to HLS or RTMP, and serves the segments.
Playback side : Native players (QuickTime, VLC), mobile native players, or HTML5 video tags for HLS/RTMP.
5. Recording Video in the Browser (WebRTC)
WebRTC enables real‑time media capture in browsers, but support is limited to Chrome on desktop; most mobile browsers lack full functionality. The basic flow is:
Call navigator.webkitGetUserMedia() to obtain the camera stream.
Wrap the stream in a RTCPeerConnection.
Send the stream to the server via WebSocket.
Because of limited mobile support, native apps are often used for reliable recording.
6. iOS Native Capture Workflow
Use AVCaptureSession and AVCaptureDevice to capture raw audio/video.
Encode video with H.264 and audio with AAC (using libraries such as x264, faac, or ffmpeg).
Package the encoded streams into FLV/TS containers.
Open an RTMP connection and push the stream to the server.
7. Setting Up Nginx with RTMP Module
Install the module via Homebrew:
brew tap homebrew/nginx
brew install nginx-full --with-rtmp-moduleEdit /usr/local/etc/nginx/nginx.conf to add RTMP and HLS sections:
rtmp {
server {
listen 1935;
application rtmplive {
live on;
max_connections 1024;
}
application hls {
live on;
hls on;
hls_path /usr/local/var/www/hls;
hls_fragment 1s;
}
}
}
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /usr/local/var/www;
expires -1;
}Reload Nginx:
nginx -s reload8. Stream Conversion and Publishing with FFmpeg
Install FFmpeg (Homebrew): brew install ffmpeg Push an MP4 file as RTMP:
ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -acodec aac -f flv rtmp://10.14.221.17:1935/rtmplive/homePush the same file as HLS (via RTMP endpoint that generates HLS fragments):
ffmpeg -re -i /Users/gao/Desktop/video/test.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -q 10 rtmp://10.14.221.17:1935/hls/testFor live capture from webcam, desktop, and microphone on macOS:
ffmpeg -f avfoundation -framerate 30 -i "1:0" \
-f avfoundation -framerate 30 -video_size 640x480 -i "0" \
-c:v libx264 -preset ultrafast -filter_complex 'overlay=main_w-overlay_w-10:main_h-overlay_h-10' \
-acodec libmp3lame -ar 44100 -ac 1 -f flv rtmp://192.168.1.101:1935/hls/test9. Playing the Live Stream in H5
Both iOS and Android browsers support HLS natively. Use a simple video element:
<video controls preload="auto" autoplay="autoplay" loop="loop" webkit-playsinline>
<source src="http://10.14.221.8/hls/test.m3u8" type="application/vnd.apple.mpegurl" />
<p>Your browser does not support HTML5 video.</p>
</video>For iOS inside WeChat, the webkit-playsinline attribute is required and the domain must be whitelisted.
10. Conclusion
The end‑to‑end workflow covers video capture, server‑side transcoding and packaging, and HTML5 playback. Key points:
HLS on H5 requires H.264 video and AAC audio.
Latency can be reduced by tuning segment length and using CDNs for .ts files.
When lower latency is needed, RTMP combined with video.js can be used on desktop browsers.
References include detailed tutorials on building a complete live‑streaming system, WebRTC canvas/video integration, and FFmpeg command collections.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Aotu Lab
Aotu Lab, founded in October 2015, is a front-end engineering team serving multi-platform products. The articles in this public account are intended to share and discuss technology, reflecting only the personal views of Aotu Lab members and not the official stance of JD.com Technology.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
