Overview
HLS (HTTP Live Streaming) is Apple’s adaptive bitrate streaming protocol that delivers video over HTTP. It’s widely supported across browsers, mobile devices, and smart TVs, making it the de facto standard for VOD and live streaming.
Key Benefits
Universal compatibility : Works on iOS, Android, browsers, smart TVs
Adaptive bitrate : Automatically adjusts quality based on bandwidth
HTTP-based : Uses standard web servers, CDN-friendly
Scalable : Easily distributed via CDNs
DRM support : FairPlay Streaming, AES encryption
Codec support : H.264, H.265/HEVC, AAC, AC3, MP3
Publishing for HLS
Ant Media Server automatically converts incoming streams to HLS. Publish using any supported protocol:
RTMP to HLS
WebRTC to HLS
SRT to HLS (Enterprise)
Direct HLS Creation
# Publish via RTMP
ffmpeg -re -i input.mp4 \
-c:v libx264 -preset veryfast -b:v 2500k \
-c:a aac -b:a 128k \
-f flv rtmp://your-server.com/WebRTCAppEE/stream123
# HLS automatically available at:
# https://your-server.com:5443/WebRTCAppEE/streams/stream123.m3u8
Playing HLS Streams
Browser Players
Native HLS (Safari)
HLS.js (All Browsers)
Video.js Player
React Player
<!-- Safari supports HLS natively -->
< video id = "video" controls autoplay >
< source src = "https://your-server.com:5443/WebRTCAppEE/streams/stream123.m3u8"
type = "application/x-mpegURL" >
</ video >
< script >
const video = document . getElementById ( 'video' );
video . addEventListener ( 'error' , ( e ) => {
console . error ( 'Video error:' , e );
});
</ script >
Mobile Players
iOS (AVPlayer)
Android (ExoPlayer)
Android (Kotlin)
import AVKit
import AVFoundation
class HLSPlayerViewController : UIViewController {
var player: AVPlayer ?
var playerViewController: AVPlayerViewController ?
override func viewDidLoad () {
super . viewDidLoad ()
let urlString = "https://your-server.com:5443/WebRTCAppEE/streams/stream123.m3u8"
guard let url = URL ( string : urlString) else { return }
player = AVPlayer ( url : url)
playerViewController = AVPlayerViewController ()
playerViewController ? . player = player
addChild (playerViewController ! )
view. addSubview (playerViewController ! . view )
playerViewController ! . view . frame = view. bounds
player ? . play ()
}
}
Desktop/CLI Players
# Basic playback
ffplay https://your-server.com:5443/WebRTCAppEE/streams/stream123.m3u8
# Low latency playback
ffplay -fflags nobuffer -flags low_delay \
https://your-server.com:5443/WebRTCAppEE/streams/stream123.m3u8
Configuration Options
Server-Side Configuration
Configure HLS settings in application.properties or via REST API:
# Enable HLS muxing
settings.hlsMuxingEnabled =true
# Segment duration (seconds)
settings.hlsTime =6
# Playlist size (number of segments)
settings.hlsListSize =10
# Playlist type: event, vod, or null (live)
settings.hlsPlayListType =
# HLS flags (comma-separated)
settings.hlsflags =delete_segments,omit_endlist
# Delete HLS files when stream ends
settings.deleteHLSFilesOnEnded =true
# Add date/time to HLS filename
settings.addDateTimeToHlsFileName =false
# HLS segment type: mpegts or fmp4
settings.hlsSegmentType =mpegts
# Segment filename format
settings.hlsSegmentFileSuffixFormat =%09d
# S3/Cloud storage
settings.uploadExtensionsToS3 =7
settings.s3StreamsFolderPath =streams
# HTTP endpoint for segments
settings.hlsHttpEndpoint =
# Encryption
settings.hlsEncryptionKeyInfoFile =
HLS Playlist Types
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:6
#EXT-X-MEDIA-SEQUENCE:12345
#EXTINF:6.000,
stream123_00012345.ts
#EXTINF:6.000,
stream123_00012346.ts
#EXTINF:6.000,
stream123_00012347.ts
Adaptive Bitrate Configuration
Enable ABR in application.properties:
# Enable adaptive streaming
settings.adaptiveResolutionsEnabled =true
# Encoder settings for different qualities
settings.encoderSettings =[
{ "height" :240, "videoBitrate" :500000, "audioBitrate" :64000},
{ "height" :360, "videoBitrate" :800000, "audioBitrate" :96000},
{ "height" :480, "videoBitrate" :1500000, "audioBitrate" :128000},
{ "height" :720, "videoBitrate" :2500000, "audioBitrate" :128000},
{ "height" :1080, "videoBitrate" :4500000, "audioBitrate" :192000}
]
Master playlist structure:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=564000,RESOLUTION=426x240
stream123_240p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=896000,RESOLUTION=640x360
stream123_360p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1628000,RESOLUTION=854x480
stream123_480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2628000,RESOLUTION=1280x720
stream123_720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=4692000,RESOLUTION=1920x1080
stream123_1080p.m3u8
Advanced Features
HLS Encryption (AES-128)
Source: HLSMuxer.java:144-169
Generate Encryption Key
Enable Encryption
Encrypted Playlist
# Generate random encryption key
openssl rand 16 > stream.key
# Generate initialization vector (IV)
openssl rand -hex 16
# Create key info file
cat > keyinfo.txt << EOF
https://your-server.com/keys/stream.key
stream.key
<IV_HEX_VALUE>
EOF
Low Latency HLS (LL-HLS)
LL-HLS support requires Enterprise Edition. It reduces latency to 2-3 seconds.
# Enable LL-HLS
settings.lLHLSEnabled =true
# Part duration (typically 0.5-1 second)
settings.hlsPartTargetDuration =0.5
# Enable LL-HLS via DASH muxer
settings.islLDashEnabled =true
settings.hlsEnabledViaDash =true
HLS with fMP4 Segments
Use fragmented MP4 instead of MPEG-TS:
settings.hlsSegmentType =fmp4
Benefits of fMP4:
Better HEVC/H.265 support
Improved seeking
Smaller file sizes
Better for VOD
Troubleshooting
Playback Issues
CORS Errors:
# Check CORS headers
curl -I https://your-server.com:5443/WebRTCAppEE/streams/stream123.m3u8
# Should include:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Add to nginx/web server config:
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' ;
add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' ;
404 Not Found:
# Check if stream exists
curl https://your-server.com:5443/WebRTCAppEE/rest/v2/broadcasts/stream123
# Verify HLS is enabled
curl https://your-server.com:5443/WebRTCAppEE/rest/v2/settings | grep hlsMuxingEnabled
# Check HLS files exist
ls -la /usr/local/antmedia/webapps/WebRTCAppEE/streams/
Segments Not Loading:
# Verify segment duration
ffprobe https://your-server.com:5443/WebRTCAppEE/streams/stream123.m3u8
# Check segment availability
curl -I https://your-server.com:5443/WebRTCAppEE/streams/stream123_000000000.ts
# Monitor segment generation
tail -f /usr/local/antmedia/log/antmedia-error.log | grep HLS
Reduce Latency:
# Shorter segment duration
settings.hlsTime =2
# Smaller playlist
settings.hlsListSize =3
# Immediate segment deletion
settings.hlsflags =delete_segments
Optimize for CDN:
# Longer segments for better caching
settings.hlsTime =10
# Larger playlist
settings.hlsListSize =20
# Upload to S3/CDN
settings.uploadExtensionsToS3 =7
Memory Usage:
# Delete old segments
settings.deleteHLSFilesOnEnded = true
settings.hlsflags =delete_segments
# Monitor disk usage
du -sh /usr/local/antmedia/webapps/WebRTCAppEE/streams/
Best Practices
Production Recommendations
Segment Duration : Use 6 seconds for standard HLS, 2-4 seconds for low latency
Playlist Size : Keep 3-5 segments for live, unlimited for VOD
Codec Settings : Use H.264 baseline/main profile for maximum compatibility
HTTPS : Always serve HLS over HTTPS in production
CDN : Use CDN for scalability (CloudFront, Cloudflare, Akamai)
Monitoring : Track segment generation and player errors
Recommended Settings by Use Case
Live Streaming
Low Latency Live
VOD
DVR/Time-Shift
settings.hlsTime =6
settings.hlsListSize =10
settings.hlsPlayListType =
settings.hlsflags =delete_segments
settings.deleteHLSFilesOnEnded =true
API Reference
For complete HLS implementation details: