2011.03.29

HTML5 video issues on the iPad and how to solve them

I’ve been delaying this post since I wrote a rant about the iPad. The delay is mainly because I never found time to create sample files or record screencasts showing the bugs so I decided to publish it without any working examples since I don’t think I will have enough time or patience to isolate the problems and document it anytime soon, so you will have to believe that what I’m saying “is true” and that the bugs exist… Think of it as a reference in case you have any of those issues and not as a definitive way of making those things work, some bugs are only present on older versions of iOS and may not be easy to replicate. I’m sure I will leave a lot of important stuff behind but at least I’ll try to cover some bugs and how I solved them. I will try to be brief.

Bugs and Hacks

Preload video

The HTML5 video element have a preload attribute, which is used to specify if any data of the media element should be loaded before an user interaction[1], unfortunately Apple decided to not support this attribute on iOS to reduce bandwidth usage[2].

Here is an example of the code required to preload a video after user interaction on iOS 3.2+:

As you can see on the code comments it requires a series of hacks to make it work properly.

PS: On previous versions of iOS you could simulate a click event to trick the browser to start downloading the video but I don’t recommend using any technique that abuses flaws on the system, it can cause way more troubles than it solves, future updates on the OS may invalidate your whole application.

Loop video / Seek

The HTML5 video element have an attribute loop[3] which doesn’t work on iOS (as of iOS 4.2), the video element also expose the property currentTime[4] which is used to read the current playback position or to seek to a specific position. Setting currentTime to zero on “all” browsers makes the video start playing from the first frame, unfortunately doing that on iOS 3.2 breaks the currentTime property (value isn’t updated during playback) and also breaks the ended event dispatch. The way to fix it is to seek to 0.1 instead of 0. Here is an example of how to make an inline video loop (won’t work on fullscreen play).

Seeking to float point numbers with a single decimal digit in my case also solved some weird seeking behaviors on iOS 3.2. So instead of seeking to 12.3456 I started seeking to 12.3 - I haven’t done exhaustive tests on this but on my case it worked fine and I wasn’t able to replicate the bug anymore.

Hide QuickTime logo

The iPad displays the QuickTime logo sometimes while the video component is being instantiated, this can be very annoying and sometimes it can take a long time before it downloads the video metadata and/or poster image. My first attempt to solve this issue was to add an overlay on top of the video while it was loading and then fade it out after the video started to play or just set the video opacity to zero (since I wanted to fade the video after it finished loading), but unfortunately the QuickTime logo doesn’t respect the z-index or opacity of the video element, so it appears over any element. Another issue that I’ve found out is that setting display:none blocks the video download and that visibility:hidden also doesn’t solve the issue.

The solution is to set -webkit-transform:translateX(-2048px) on the video element (any value small/big enough to push the video outside the window area) than listen for any of the media data events (progress, loadedmetadata, load, canplaythrough, etc..)[5] and set translateX(0) after video.readyState gets bigger than 1, that way the QuickTime logo will be off the screen while video is getting ready to play. After that moment you can even fadeIn the video and or add overlays on top of it.

In some cases it was also breaking the z-index of the video and overlays, after applying the translate hack the z-index bugs disappeared.

Play button doesn’t show up on the placeholder

I’ve seen this happening many times with different videos but couldn’t find out what causes the bug, I just know that somehow using the browser history buttons (back/forward ) seems to increase the incidence of this bug. My solution so far is to not use the HTML5 video element to show the poster image, instead I just use a simple image link with a click handler that swaps the image with a video element, that way I can ensure the user will see the play icon and I can customize it. I’m not sure if this bug is still present on iOS 4.2-4.3 since I stopped using the plain HTML5 video tag when I noticed that this bug existed and that Android prior version 2.3 also had issues with the plain HTML5 video tag which required a JavaScript click handler to play the video[6].

In most cases I still find that having a simple link pointing to the video file is the simplest and most reliable solution for video playback on mobile devices, specially since some devices cannot play files while progressively-downloading it but can play the same video files if they are downloaded to the device (Blackberry and some Androids), iPhone and Android will still play the video fullscreen using the native media player as if it was an HTML5 video tag (if files are properly encoded and served with right mime-type).

Click and touch eventsAdded: 2011-06-01

Click and touch events doesn’t work properly on a video element, it seems that the video element doesn’t bubble the events. The way to “solve” it is to add an overlay on top of the video and attach the events on the overlay. (thanks Hugo for reminding me that this issue exists)

It’s important to notice that items over the video element will only trigger click/touch events if the video player isn’t using the native controls.

Conclusion

As a said before on another post, the closer to the edge you are the more problems you find and since HTML5 video and the iPad itself are fairly new technologies, they still need a long time to mature and become stable. This post doesn’t cover all the bugs I’ve found and all the tricks I came up but it covers some of the most recurrent ones. I focused on the iPad and HTML5 video since it was the major cause of headaches on one of my last projects but Google Chrome also have some strange rendering issues and other bugs as well… - Developing cutting-edge websites for the iPad is not as “magical” as Steve Jobs wants you to believe.

References

  1. http://www.w3.org/TR/html5/video.html#attr-media-preload
  2. User Control of Downloads Over Cellular Networks
  3. http://www.w3.org/TR/html5/video.html#attr-media-loop
  4. http://www.w3.org/TR/html5/video.html#dom-media-currenttime
  5. http://www.w3.org/TR/html5/video.html#mediaevents
  6. Making HTML5 Video work on Android phones

Related

PS: a lot of people commented on my other post that “all” iPad users update the OS constantly but on one of my latest projects 17% of the iPad users where still using iOS 3.2 (version that came with 1st gen iPads) and I don’t want 17% of the users (and specially the client) thinking that the website is broken while in fact the fault is of their broken OS…


Comments

Thanks for this. Happy contemplating the head-against-wall banging I'll now be able to sidestep.

I've recently started using html5 video on some of my sites and have run into an interesting problem. I am hoping that possibly you have run into this as well and may have a solution.

Basically all of my video's are over an hour long. I have found that if I embed a short 5 minute mp4 video it will indeed show the poster and the play button. Clicking play works.

However, when I load a larger video, encoded exactly the same as the shorter one's, the play button never shows up on the ipad.

Any chance you have seen this problem before?

[...] HTML5 video issues on the iPad and how to solve them, Unsolved HTML5 video issues on iOS (Miller H. Borges Medeiros) [...]

I think, Apple is trying to prevent demands that are to excessive for the iPad. Sadly they don’t say that the iPad isn’t a device that can handle as much as a desktop computer, but brings the "the whole web" into the users hands.

If you would just code how you mean it (not talking about some obvious bugs like disrespecting z-index) than the user would see a lot of quicktime placeholders and experience video playback delays. It would be okay for the user when he knows that this is simply the normal way to browse on a low power device - but as the user might believe all the exaggerating bullshit from Apple he will blame the website.

So I know everything is Apple’s fault, but I think it should be okay to have a lower quality experience as a user on a lower quality device. (Progressive enhancement and that stuff are meant for that.)

I'm trying to write some simple controls to restart a video. Whenever I use .currentTime=0.1 or .currentTime=0 I get the same Dom_err_exception 11 invalid state only on ipad and iPhones. Works fine on chrome, safari, ff... I can give you the devel link if you want to take a look. Email. Thanks.

@Aaron, try setting higher values, maybe the video doesn't have a keyframe close enough, also try a different file to see if the problem is really on the video encoding... also make sure you are getting a reference to the proper video element.

You can see a working example of a video replay on the SoBe Skinsuit microsite - click "restart" during the video - I'm just not sure how long it will be live..

PS: I used all the hacks described on this page to code the skinsuit site.

Hi there—I did some more investigation on this issue. A related issue that you might want to note is that the seekable attribute (which states where you're allowed to seek inside the video) isn't set until quite late on iPad: not until the canplaythrough event in my tests. Thus you may be seeking (setting currentTime) too soon; wait until seekable contains a valid range.

See my blog post for more.

Can you elaborate on the "overlay" for touch events? I'm working with trying to get a custom scrubber / controls and I'm having issues still with the zindex. I'd love to know how you got past that hurdle.

Thanks for the article. Found a solve for that "Play button doesn’t show up on the placeholder" bug when perusing the source of videojs. They "force the source" with javascript, and sure enough iOS v3 iPads have a 'currentSrc' value but an empty 'src' value, so this worked for me: videoObj.src = videoObj.currentSrc;

[...] HTML5 video issues on the iPad and how to solve them [...]

Hi There,

About your "CLICK AND TOUCH EVENTS" comment. Can you point me to any example or something, it is not totally clear to my what you mean with an overlay.

Cheers

The "overlay" would be and empty div or a transparent image. Just so you can attach the click event handler to this element instead of the video element. Good luck.

I use this Function to get the end. This works great on the ipad and u can use the load and play. var _vid; //global variable for video _vid = $('video').get(0); $(_vid).bind('timeupdate', function(){
if (_vid.currentTime > _vid.duration - 0.1){ // do what ever u want here when the video is ended. } });

Hi, does anyone have an example of hiding the QT logo.

I've tried 'canplaythrough' but to move a hidden layer in, but I just moves the layer in to show the QT logo. I've also tried to wait til 'playing' what seems to work, but i'm unable to remove the bind afterwards.

[...] HTML5 video issues on the iPad and how to solve them [...]

[...] HTML5 video issues on the iPad and how to solve them [...]

So I'm testing out the overlay idea to catch the click/touch events, but they definitely are not being trapped by the overlays. I am able to put overlays on top of the video, but the event listeners I had setup don't work when the tag is added to the page. Any examples/thoughts on how to achieve this?

Example of working code for hiding the Quicktime logo?

I've tried this in jQuery Mobile with moderate success:

$("div[id*='first-page']").live('pagebeforeshow', function(event, ui) { setTimeout(function() { window.scrollTo(0, 1) }, 100); $("#first-video").addClass('hidequicktime'); $("#but1").click(function(){ $("#but1").fadeToggle(1500); }); $("#first-video").bind('progress', function(){ $("#first-video").removeClass('hidequicktime'); $("#first-video").addClass('showmovie').fadeIn(500); }); });

$("div[id*='first-page']").live('pageshow', function(event, ui) { setTimeout(function() { window.scrollTo(0, 1) }, 100); $("#first-video").bind('ended', function(){ $.mobile.changePage($("#next-page"), { transition: "false" } ); }); });

The 'hidequicktime' and 'showmovie' class is using your method. Here's the CSS:

/Hide Quicktime Logo/

            .hidequicktime {
            -webkit-transform:translateX(-2048px);
             }

/Show movie/

            .showquicktime {
            -webkit-transform:translateX(0px);
             }

The problem, I'm having is that it isn't consistent, when the same code is applied to videos pages that are called from the 'ended' event.

Any improvement to the script?

Randy Collier

Memory leak in loading a second video. I think I have a work around for this.

Using DOM, copy the video element in a var remove the video element and then past the video element back into place.

this.videoHack = $("#video_box").html(); $("#video_box").html(""); $("#video_box").html(this.videoHack);

Another example that helped but caused some issue (load()). From: stackoverflow

this.video.src = ''; this.video.load();

Hey Miller

Could you perhaps provide an example on how to trigger the overlays by adding event listeners for click and touch events?

Currently I'm having a banner overlay on a video, which is linking to a page where the products being advertised in the video can be bought. But on the iPad it's not really converting since the click is being ignored...

I have tried doing something like this using jQuery

$('#link-banner').bind('touchstart', function () { alert('test'); });

But the 'test' is never being alerted when I click the banner on my iPad. Am I getting it totally wrong?

ELMER IGNACIO

OK

Mobile Safari's limited HTML5 support is annoying, but the lack of accurate documentation is inexcusable.

I have a question. I made a m3u8 video file which is related with Apple's new streaming standard name HTTP Live Streaming. And I want to make a webpage that store currenttime value in localstorage and then if next time user visit site again, the site use stored currenttime value and play from the stored currenttime value. In my experiment, I success play from the some point of time In the site witch played video before by user's interaction such as click, but I fail in new loaded the site. Do you know how to set currenttime value in refreshed site(no user interaction occured) and play from the specific point of the time?

Just wanted to say thanks for this. Please make sure your site never goes down because this page is a very important piece of documentation. (Web archive and Google Cache don't seem to have you backed up!) :)

I found a way to make buttons and banners on the html5 video tag and links work properly, iPad included. The solution is to make your own controls for the video in javascript and desactivate the default controls. Then, the liks of the buttons over the video works fine ;)

Sergio Pérez is the King :)

[...] HTML5 video issues on the iPad and how to solve them | Blog | Miller Medeiros * @author Miller Medeiros * Released under WTFPL [...]

I'm having an issue with my wordpress navigation menu submenu drop downs over embedded video content on mobile browsers such as the iPhone & iPad. The video controls seem to take over any other touch commands and even though the video appears beneath the menu links; any menu links that appear over the video are not clickable. I looked at various work arounds for this but haven't found any that seem to solve the problem. The video ignores the z-index. I've seem various mention of hiding the video on drop down or disabling the video control attributes but haven't found any solid working code. Site is redirect for mobile users. http://www.chrisnorr.com/html Links work fine in any regular computer desktop or laptop computer just not on mobile devices. Can anyone help?

Thanks

Also, video elements don't behave well under zoom: see http://stackoverflow.com/questions/12503142/in-ios-safari-slow-rendering-issues-with-video-and-scale

[...] Links: blog.zencoder.com: how-to-encode-video-for-mobile-use camendesign.com : video_for_everybody w3schools.com: html_videos.asp www.808.dk: code-html-5-video stackoverflow.com: using-php-to-output-an-mp4-video for iPhone html5-video-issues-on-the-ipad-and-how-to-solve-them [...]

I do not know if it's just me or if perhaps everybody else encountering problems with your website. It looks like some of the written text within your content are running off the screen. Can someone else please comment and let me know if this is happening to them as well? This could be a issue with my browser because I've had this happen before. Thanks

Thank you for your post. I'm having a loto of problems with poster attribute because it is not displaying onto iPad iOS 6.1.3. Do you have any suggestions for me? Many thanks!

Please find hereuder the html code:

[...] http://blog.millermedeiros.com/h … -how-to-solve-them/ 回复hennyChen: @cloudhsu [...]

adam anderson

Hi

great post and thank you!!!!

can i contact you for some paid work, I have need of your skills?

How can I place an image ( different image each time) over the black screen with the quicktime logo on, when changing from one video to another?

( the black screen that appears when you select a video and wait for it to load ( i am using a ipad)

many thanks in advance

I am extremely impressed with your writing skills as well as with the layout on your blog. Is this a paid theme or did you customize it yourself?

Anyway keep up the nice quality writing, it is rare to see a nice blog like this one today.

Also visit my webpage :: emergency brentwood tn locksmith service ([Caryn](https://www.youtube.com/watch?v=OrGx1I1Iv68 "Caryn"))

Leave a Comment

Please post only comments that will add value to the content of this page. Please read the about page to understand the objective of this blog and the way I think about it. Thanks.

Comments are parsed as Markdown and you can use basic HTML tags (a, blockquote, cite, code, del, em, strong) but some code may be striped if not escaped (specially PHP and HTML tags that aren't on the list). Line and paragraph breaks automatic. Code blocks should be indented with 4 spaces.