Adaptive Bitrate HLS Generation

MaxxSports has two variant streams for each camera, high and low resolution, generated by ffmpeg. Player can switch between the two resolutions based on bandwidth.

There are three playlists in this sample setup; master.m3u8 has two variant playlists:
var_0.m3u8: 426×240, with original resolution from input mp4 file
var_1.m3u8: 128×86, transcoded with parameter -s:v:1 128×86

Command used to generate the three playlists:
set FF=2018\bin\ffmpeg.exe
set MEDIA=Gym2017bshort.mp4    : to be replaced by rtsp://… for live camera feed.
%FF% -i %MEDIA% -s:v:1 128×86 -map 0:v -map 0:a -map 0:v -map 0:a -f hls -master_pl_name master.m3u8 -var_stream_map “v:0,a:0 v:1,a:1” var_%v.m3u8

Play URL: or or var_1.m3u8

This feature, var_stream_map, was added to ffmpeg in November 2017.
ffmpeg version is ffmpeg-20180925-a7429d8-win64-static 4.02, downloaded from


VLC Streaming

Sample commands of VLC as streaming server on windows 10. Client uses vlc.exe menu Media – Open Network Stream.
set VLC=D:\VLCPortable223\VLCPortable.exe
set MEDIA=Gym2017bshort.mp4
Server: %VLC% –intf dummy –sout=#std{access=http,mux=ts,dst=} %MEDIA%
Client: http://localhost:8080
rtp: over udp
Server: %VLC% -vvv %MEDIA% –sout “#transcode{vcodec=h264,vb=0,scale=0,acodec=mpga,ab=128,channels=2,samplerate=44100}:rtp{dst=,port=8080,mux=ts,ttl=10}”
Client: rtp://@:8080
Server: %VLC% -vvv %MEDIA% –sout “#transcode{vcodec=h264,vb=0,scale=0,acodec=mpga,ab=128,channels=2,samplerate=44100}:std{access=udp,mux=ts,dst=}”
Client: udp://@:8080
Server: %VLC% -vvv %MEDIA% –sout “#transcode{vcodec=h264,vb=0,scale=0,acodec=mpga,ab=128,channels=2,samplerate=44100}:rtp{sdp=rtsp://}”
Client: rtsp://
Server: %VLC% -vvv %MEDIA% –sout “#transcode{vcodec=h264,vb=0,scale=0,acodec=mpga,ab=128,channels=2,samplerate=44100}:rtp{dst=,port=8080,mux=ts,ttl=10}”
Client: rtp://
Remotely control server:
Start server: %VLC% –intf rc –rc-host –sout=#std{access=http,mux=ts,dst=}
Open command console: telnet localhost 12345
enter: add Gym2017bshort.mp4
Start client: http://localhost:8080
In telnet console, before reaching end of media, enter this command to seek media:
seek 1%


Assuming host A B both behind NAT on the internet.
STUN: Session Traversal Utilities for NAT
A B talk to STUN server to know each other’s external IP and port state for hole punching.
The goal is to let A B directly talk to each other on UCP and sometimes TCP, if NAT is not symmetric.
This public IP is also needed in RTSP SDP when RTP over UDP.
STUN server itself communicates over UDP by default.
TURN: Traversal Using Relays around NAT
A first asks TURN server a permission, and then A sends all data to TURN, which is relayed to B.
Used for some NAT TCP, when hole punching doesn’t work.
ICE: Interactive Connectivity Establishment
Just a combination of STUN and TURN, and automatically switches between the two.

Vue on sale

Sony PlayStation Vue’s Core Plan is on sale for just $40, regular $50
and they have beautiful office locally in SF.