Lessons Learned from My First HTML5 Video implementation
I recently had the opportunity to implement an HTML5 video for a client. It was the first time I’d really worked with HTML5 video, and I ran into a few issues and quirks I thought I’d share for other developers who run into these issues.
1. HTML5 video with a fallback to Flash works really well. The opposite doesn’t work as well.
At first I started implementing my video in Flash with a fallback to HTML5 – not for any special reason, but only because a previous developer had implemented another of the client’s videos that way and I followed the pattern already set. I soon discovered that although this works fine for a video that just plays in a fairly static page, it wasn’t ideal for the kind of video I was implementing, which required some custom controls and interactions with other elements on the page. I first thought that the best way to handle this would be with a try / catch, but since my flash took a little bit of time to load, I would often get an exception when calling a flash function, even though the flash was ultimately playable. The real crux of the problem was that in an HTML5 to Flash fallback implementation, the flash code doesn’t even exist as far as the browser is concerned unless HTML5 is not supported – in which case the <video> tags don’t exist. The user can only ever interact with the HTML5 video or with the Flash – never with both. If you implement it the opposite way, BOTH Flash and HTML5 video exist on the page, potentially leading to a situation where the user is interacting with both videos. Once I found myself writing code to catch and prevent these weird interactions, I decided this was the wrong way to go. The HTML5 to Flash fallback is the way this code is meant to be implemented, and leads to the cleanest implementation.
2. Some events aren’t implemented the same way in all browsers
For my video I needed to add a listener that would hide an element when the video started playing, so I needed to listen for the play event. Easy, right? When you play an HTML5 video it fires a javascript event so all I needed to do was bind an event listener to .play(), and call the functions I needed to call when the event was fired. This worked exactly as I expected in Chrome, but I found that the implementation was different (and to my mind incorrect) in Firefox and Safari (I wasn’t testing IE at that point). In those browsers, if you let the video play all the way to the end and then hit play again, the play event wasn’t fired again. I tested this on the example video at http://www.w3.org/2010/05/video/mediaevents.html, which displays all the events that the video registers as they happen, so you can clearly see the new play events being registered in Chrome, but not in Safari or Firefox . If any one knows the reasoning behind this I’d love to know – to my thinking, if the user hits “play”, that action should call the play event, and I don’t see why subsequent plays should be any different?
Ultimately, I got around this problem by listening to the ‘timeupdate’ event. All the browsers I tested fired that one correctly and it was a good enough stand in for ‘play’ – if the time is updated, we can safely assume the video is playing. For my purposes, it didn’t matter that ‘timeupdate’ was fired much more often than play(), since I was just hiding an element on that event.
3. Autoplay doesn’t work on Mobile Safari
This isn’t a secret, Apple has done this by design – per their documentation they don’t allow videos to autoplay in Mobile Safari. I didn’t know about this limitation before working on this project, and others – including clients that request it – might not know either.
These are just a few of the quirks that I encountered when implementing an HTML5 video – I’d love to hear about other people’s experience with these or other issues in the comments!
1 Comment