Skip to main content

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:
# 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

<!-- 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

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 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

Performance Optimization

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

  1. Segment Duration: Use 6 seconds for standard HLS, 2-4 seconds for low latency
  2. Playlist Size: Keep 3-5 segments for live, unlimited for VOD
  3. Codec Settings: Use H.264 baseline/main profile for maximum compatibility
  4. HTTPS: Always serve HLS over HTTPS in production
  5. CDN: Use CDN for scalability (CloudFront, Cloudflare, Akamai)
  6. Monitoring: Track segment generation and player errors
settings.hlsTime=6
settings.hlsListSize=10
settings.hlsPlayListType=
settings.hlsflags=delete_segments
settings.deleteHLSFilesOnEnded=true

API Reference

For complete HLS implementation details:

Build docs developers (and LLMs) love