Khan / khan-mobile

You’re probably looking for www.github.com/khan/mobile
237 stars 34 forks source link

Use m3u8 on iPad #134

Open adamjernst opened 12 years ago

adamjernst commented 12 years ago

@jeresig We need to use the m3u8 format instead of mp4 on iPad. (We will still try to use offline_url first, of course.)

Even smarter behavior (though probably overkill) would be to try m3u8 first, then mp4 as a fallback.

Can you suggest the best way to do this on iPad only?

sophiebits commented 12 years ago

Will we ever be missing the m3u8?

adamjernst commented 12 years ago

It's theoretically possible—e.g. if something goes wrong with m3u8 transcoding but not mp4, but that's unlikely.

sophiebits commented 12 years ago

It appears that instead of setting the src attribute, you can just include multiple <source> elements in order of preference, like so:

<video controls autoplay>
  <source src="http://HttpLiveStream.m3u8">
  <source src="rtsp://LegacyStream.3gp">
  <source src="http://ProgressiveDownload.m4v">
</video>

(from http://developer.apple.com/library/safari/#documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video...)
Probably type="application/x-mpegURL" is appropriate to add for the m3u8, though none of Apple's examples show it.

Not sure if Android handles this properly, but if it does, this seems the simplest – no platform detection!

adamjernst commented 12 years ago

I forgot about that, and that would be an awesome solution!

... except, we set the src dynamically in Javascript for the video tag. I don't know if there is a way to do multiple source elements with that method.

We also have to reuse the existing video player; we can't create a new one all at once with the required source elements. This is for performance reasons (creating a new video player each time is very, very slow).

adamjernst commented 12 years ago

See in particular, this StackOverflow question about dynamically changing multiple source subelements. It looks like it should be possible if we call load after changing all the source subelements, but we'll need to test.

sophiebits commented 12 years ago

On iOS 5, this returns "probably":

var video = document.createElement("video");
var can = video.canPlayType('application/x-mpegURL; codecs="avc1.42E01E"');

(test: http://jsfiddle.net/gXcA8/)

Unfortunately, it returns "", indicating no support, in iOS 4(.3.2).

adamjernst commented 12 years ago

OK; where did you get that particular codec? Is there another type that does work on 4.3.2?

sophiebits commented 12 years ago

From the Modernizr.js source (supposedly it just means H.264). Unlike desktop Safari and iOS 5, it doesn't even return "maybe" for just canPlayType("application/x-mpegURL"), so I doubt there's a codec that it does like. iOS 4 does return maybe/probably for video/mp4.

sophiebits commented 12 years ago

Excellent, canPlayType('application/vnd.apple.mpegurl; codecs="avc1.42E01E"') works on 4 and 5.

sophiebits commented 12 years ago

FWIW, Android 2.2 canPlayType seems to return the empty string no matter what type I pass it. (I don't have Android 3 or 4 to test with.)

sophiebits commented 12 years ago

@benkomalo says that both application.vnd.apple.mpegurl and video/mp4 say "maybe" on a Xoom on 3.2 Honeycomb.

adamjernst commented 12 years ago

OK. Is there a MIME type for m3u8? Perhaps we can detect m3u8 compatibility on iOS 4/5 and it will return false on Android?

sophiebits commented 12 years ago

application.vnd.apple.mpegurl is supposedly the proper type for m3u8, so this doesn't look that promising.

adamjernst commented 12 years ago

Really? What is the MIME type for mp4 then?

Perhaps Honeycomb can play m3u8?

adamjernst commented 12 years ago

It appears that it may be supported in Android 3, although I'm not sure how that works with web browser embedding.