Arnav Kumar
Senior Software Engineer, BrowserStack
ABR Overview
Â
download segments of video at an appropriate bitrate, and feed them to a video element when it gets hungry — using existing HTTP infrastructure
./audio/
├── ./esperanto/
| ├── ./128kbps/
| | ├── segment0.mp4
| | ├── segment1.mp4
| | └── segment2.mp4
| └── ./320kbps/
| ├── segment0.mp4
| ├── segment1.mp4
| └── segment2.mp4
└── ./french/
├── ./128kbps/
| ├── segment0.mp4
| ├── segment1.mp4
| └── segment2.mp4
└── ./320kbps/
├── segment0.mp4
├── segment1.mp4
└── segment2.mp4
./video/
├── ./240p/
| ├── segment0.mp4
| ├── segment1.mp4
| └── segment2.mp4
└── ./720p/
├── segment0.mp4
├── segment1.mp4
└── segment2.mp4
Segment Hierarchy
Live MPD Example
Â
<video src='foo.webm'></video>
DRM Implementation - Widevine
ffmpeg \
-f v4l2 -input_format mjpeg -r 30 -s 1280x720 -i /dev/video0 \
-f alsa -ar 44100 -ac 2 -i hw:2 -map 0:0 -pix_fmt yuv420p \
-c:v libvpx-vp9 -s 1280x720 -keyint_min 60 -g 60 ${VP9_LIVE_PARAMS} -b:v 3000k \
-f webm_chunk -header "/var/www/webm_live/glass_360.hdr" -chunk_start_index 1 \
/var/www/webm_live/glass_360_%d.chk \
-map 1:0 \
-c:a libvorbis -b:a 128k -ar 44100 \
-f webm_chunk \
-audio_chunk_duration 2000 \
-header "/var/www/webm_live/glass_171.hdr" \
-chunk_start_index 1 \
/var/www/webm_live/glass_171_%d.chk
Sample ffmpeg - Header Generation
ffmpeg \
-f webm_dash_manifest -live 1 \
-i /var/www/webm_live/glass_360.hdr \
-f webm_dash_manifest -live 1 \
-i /var/www/webm_live/glass_171.hdr \
-c copy \
-map 0 -map 1 \
-f webm_dash_manifest -live 1 \
-adaptation_sets "id=0,streams=0 id=1,streams=1" \
-chunk_start_index 1 \
-chunk_duration_ms 2000 \
-time_shift_buffer_depth 7200 \
-minimum_update_period 7200 \
/var/www/webm_live/glass_live_manifest.mpd
Sample ffmpeg - Generate MPD
arnav@arnav.at