EDIT 3: As of IOS 10, HLS will support fragmented mp4 files. The answer
now, is to create fragmented mp4 assets, with a DASH and HLS manifest. > Pretend flash, iOS9 and below and IE 10 and below don’t exist.
Everything below this line is out of date. Keeping it here for posterity.
EDIT 2: As people in the comments are pointing out, things change.
Almost all browsers will support AVC/AAC codecs.
iOS still requires HLS. But via adaptors like hls.js you can play
HLS in MSE. The new answer is HLS+hls.js if you need iOS. or just
Fragmented MP4 (i.e. DASH) if you don’t
There are many reasons why video and, specifically, live video is very difficult. (Please note that the original question specified that HTML5 video is a requirement, but the asker stated Flash is possible in the comments. So immediately, this question is misleading)
First I will restate: THERE IS NO OFFICIAL SUPPORT FOR LIVE STREAMING OVER HTML5. There are hacks, but your mileage may vary.
EDIT: since I wrote this answer Media Source Extensions have matured,
and are now very close to becoming a viable option. They are supported
on most major browsers. IOS continues to be a hold out.
Next, you need to understand that Video on demand (VOD) and live video are very different. Yes, they are both video, but the problems are different, hence the formats are different. For example, if the clock in your computer runs 1% faster than it should, you will not notice on a VOD. With live video, you will be trying to play video before it happens. If you want to join a a live video stream in progress, you need the data necessary to initialize the decoder, so it must be repeated in the stream, or sent out of band. With VOD, you can read the beginning of the file them seek to whatever point you wish.
Now let’s dig in a bit.
Platforms:
- iOS
- PC
- Mac
- Android
Codecs:
- vp8/9
- h.264
- thora (vp3)
Common Delivery methods for live video in browsers:
- DASH (HTTP)
- HLS (HTTP)
- flash (RTMP)
- flash (HDS)
Common Delivery methods for VOD in browsers:
- DASH (HTTP Streaming)
- HLS (HTTP Streaming)
- flash (RTMP)
- flash (HTTP Streaming)
- MP4 (HTTP pseudo streaming)
- I’m not going to talk about MKV and OOG because I do not know them very well.
html5 video tag:
- MP4
- webm
- ogg
Lets look at which browsers support what formats
Safari:
- HLS (iOS and mac only)
- h.264
- MP4
Firefox
- DASH (via MSE but no h.264)
- h.264 via Flash only!
- VP9
- MP4
- OGG
- Webm
IE
- Flash
- DASH (via MSE IE 11+ only)
- h.264
- MP4
Chrome
- Flash
- DASH (via MSE)
- h.264
- VP9
- MP4
- webm
- ogg
MP4 cannot be used for live video (NOTE: DASH is a superset of MP4, so don’t get confused with that). MP4 is broken into two pieces: moov and mdat. mdat contains the raw audio video data. But it is not indexed, so without the moov, it is useless. The moov contains an index of all data in the mdat. But due to its format, it can not be ‘flattened’ until the timestamps and size of EVERY frame is known. It may be possible to construct an moov that ‘fibs’ the frame sizes, but is is very wasteful bandwidth wise.
So if you want to deliver everywhere, we need to find the least common denominator. You will see there is no LCD here without resorting to flash
example:
- iOS only supports h.264 video. and it only supports HLS for live.
- Firefox does not support h.264 at all, unless you use flash
- Flash does not work in iOS
The closest thing to an LCD is using HLS to get your iOS users, and flash for everyone else.
My personal favorite is to encode HLS, then use flash to play HLS for everyone else. You can play HLS in flash via JW player 6, (or write your own HLS to FLV in AS3 like I did)
Soon, the most common way to do this will be HLS on iOS/Mac and DASH via MSE everywhere else (This is what Netflix will be doing soon). But we are still waiting for everyone to upgrade their browsers. You will also likely need a separate DASH/VP9 for Firefox (I know about open264; it sucks. It can’t do video in main or high profile. So it is currently useless).