My nifty new Canon S90 shoots reasonable video, and it comes to mind that I’d like to video-blog from Google I/O next week. So I embarked on an HTML5 video adventure, and am here to tell the tale.
Sidebar: When I say “reasonable video”, I mean 640x480; which sounds small these days, but is more or less the resolution of an old 4×3-shaped TV show or movie on DVD. Plenty good enough for conference reportage; plus the S90’s about as small as one of those Flip cameras.
If this has worked, you should be able to summon up one minute of shamelessly self-indulgent home video. «The Duplo Auteur»
Past to the Future ·
Previous attempts to publish video in this space have been only moderately
successful; I fought a range of problems including excessive size, browser
incompatibility, and a horrid schmozzle of arcane fragile markup using
<embed>
and <object>
and so on.
But, everyone says, we’re entering the golden era of HTML5; emit a
<video>
element and it should all Just Work. Not just yet,
mind you, but we’re getting closer and closer. I read Mark Pilgrim’s
wonderful
Video on the Web and decided
I just had to do it.
Sidebar: When I say “do it”, I mean wrangle
<video>
into my own home-grown blogging thingie, an ungodly melange of Perl, JavaScript, Ruby, and Java that was never actually designed, but sort of just spread out from a small starting footprint, sort of like shower-stall mildew.I tell people I had to build my own blogging system so that I understood the issues, so I guess that must be why I’m doing this
<video>
stuff by hand. Anyhow, that’s my story and I’m sticking to it.
Diving In · I basically followed Mark’s instructions step-by-step and they all more or less Just Worked, modulo a few tweaks; for example, if you want a width other than the 320 that Mark used, the effects spill over into a few other command-line arguments.
Anyhow, as of now, I have a setup that seems to work OK on the platforms that matter.
Sidebar: When I say “platforms that matter”, I mean Firefox, Safari, and Chrome; the ones that make an effort to do
<video>
. Well, and Android plus the iPhone family. As for IE and (sob) Camino? Sorry guys, use a better browser.Yes, there are a couple of different ways to get Flash running, for platforms that don’t do
<video>
— if I had to choose one it’d probably be Video for Everybody, but my first attempt Didn’t Just Work and while I was trying to see why, I realized that I Just Didn’t Care.
Layout · One reason why Mark presents his video 320-wide, I suspect, is that that size fits into a typically-vertical blog layout. But my camera is natively 640 wide, and there’s lots of room on the screen, and even a modern phone has room for 640x480 video. So I didn’t want to squeeze it.
So on the browser, I do a little landscape-shape popup and embed the
movie there. On Android, support for <video>
is a little
shaky; I was researching that and realized that the phone has a built-in
full-screen video player; dispatching to that is probably the moral equivalent
of doing a popup on a computer screen.
So, in the blog entry I generate a dispatch like so:
<a onclick='return videoPopup("popup.html", 640, 480, "$mp4")' href='popup.html'>$title</a>
Which invokes this chunk of JavaScript:
function videoPopup(url, width, height, mp4) {
if (navigator.userAgent.indexOf('Android') >= 0 ||
navigator.userAgent.indexOf('iPhone') >= 0 ||
navigator.userAgent.indexOf('iPad') >= 0 ||
navigator.userAgent.indexOf('iPod') >= 0) ||
navigator.userAgent.indexOf('webOS') >= 0) {
// don't wrap it in HTML, just point it at the H.264 bits and get the full-screen
// video player.
window.location = mp4;
}
else {
// 640x480 should fit on most screens, but won't in my blog layout, so make a
// popup for the video
width += 20;
height += 20;
newwindow=window.open(url,'videopopup','height=' + height + ',width=' + width);
if (window.focus) {newwindow.focus()}
}
return false;
}
It works great, and I must say I got an unreasonable thrill the first time I tapped the link on my phone and hey-presto, there was my own video loading up.
Sidebar: When I say “works great”, I mean I tested it on two different Nexus Ones, appealed for help from Apple-owning friends, and was told that it worked on one iPod Touch and one iPad; subsequently I hear that it runs on a couple of Palm webOS devices too. What further testing could one possibly want?
Time and Space · Yeah, it’s a problem. This is one minute of 640x480 video. The H.264 version, encoded at quality level 0.5 (of 1.0), is 6.1M. The Ogg version, which I encoded at level 6 (of 10) because I was seeing some digital skank at level 5, is 16M. Ouch. We all must Suffer For Our Art, and so should the Internet.
What Can We Conclude? · Seems like at least some of the work going into HTML5 has been worth the effort. I continue to believe that implementors will ignore the elaborate Science-Experiment portion of the project, while continuing to crank up the multimedia support.
Sidebar: When I say “HTML5”, I mean effectively “Has
<video>
”. After all, the page you are now reading has a<!DOCTYPE>
declaration that claims it’s XHTML 1.1, but lacks the proper XHTML default-namespace declaration, and is served astext/html
. None of these seem to get in the way.
Comment feed for ongoing:
From: Steve (May 16 2010, at 23:48)
How about adding something to your code to test for the Palm Pre's browser? It ought to be able to handle the mp4 bits just as well as Android/iPhone/etc.
[link]
From: DeadParrot (May 17 2010, at 00:11)
The video html source is a little funky. Looking at the source in my browser (Safari/Mac), I see
<source src='Lego.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
According to the referenced video professor article it should look like this
<source src='Lego.mp4' type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
(actual double quote marks instead of the " html entity). Do to the funkiness of HTML, I'm not sure what difference it would make under what circumstances.
[link]
From: John M. (May 17 2010, at 01:37)
Sadly the link doesn't appear in Google Reader (on Safari/Mac).
[link]
From: Jim Harvie (May 17 2010, at 03:31)
How utterly disappointed I was to see the Duplo Tim Built and not the vastly superior your 3-1/2 year old built.
[link]
From: Robin (May 17 2010, at 04:40)
Was the version of libtheora you used for encoding >= 1.1? It was released in September of last year but may have taken a bit longer to get into the tools you use. There was a significant quality boost in version 1.1.
[link]
From: Paul Donovan (May 17 2010, at 05:13)
Your video works fine in the latest 'experimental' builds of Camino that use Gecko 1.9.2, available from this forum thread: http://forums.mozillazine.org/viewtopic.php?f=12&t=1754775
I've been using this build as a replacement for the latest stable Camino build and it's a great improvement.
[link]
From: Mark Groen (May 17 2010, at 06:10)
Nice, that camera has h.264 though so hope you have paid your licensing fees for anything that could be considered tied to a commercial enterprise.
[link]
From: kl (May 17 2010, at 06:38)
That user-agent detection is uuugly.
Soon we'll have lesser-known mobile browsers put "iPhone" in their UAs, just it happened with "Mozilla" and "MSIE" past decades.
Please, find some other solution!
[link]
From: J. King (May 17 2010, at 08:16)
For what it's worth, it works quite nicely in Opera, too. It's not fond of pop-ups, though. Ah, well.
[link]
From: Anthony Burns (May 17 2010, at 21:24)
Just wanted to let you know that your video works beautifully and flawlessly on my Droid. Cheers!
[link]
From: Stephen J Pollei (May 20 2010, at 11:47)
Yes browser sniffing is bad.
http://diveintohtml5.org/detect.html
has a few javascript snippets that might work better.
!!document.createElement('video').canPlayType;
var v = document.createElement("video");
v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
v.canPlayType('video/ogg; codecs="theora, vorbis"');
v.canPlayType('video/webm; codecs="vp8, vorbis"');
[link]
From: Rick Graham (May 26 2010, at 13:48)
Works perfectly on my nexus one.
But when I spoke the url in, I got www.tbray.org slash fondling slash win.
LOL! It's new. I guess I should talk to it more.
[link]