jugg1es jugg1es - 6 months ago 18
iOS Question

MEDIA_ERR_DECODE on HTML5 video in iOS UIWebView after many plays

After playing around 20 short video clips (mp4's) in an HTML5 video control in a UIWebView in iOS, subsequent clips are failing with a

MEDIA_ERR_DECODE
. The thing is, is that I know the videos are fine, because they were previously played, sometimes even during the same session.

Furthermore, if you wait long enough to request a new video clip, it will usually start working again.

I also know it's not the server because I can do the exact same operation on chrome on my desktop computer and it always works.

Based on my troubleshooting, it seems like the bug is in iOS itself.


  1. Does anyone have any ideas for working around this?

  2. Is there any way to get more information about an media decode error like this in iOS? I tried using Safari's development tool to listen to the http requests but I can't let it record longer than a few seconds before it hits an out of memory error and kills the app.



UPDATE: It also works fine when run in the iOS simulator. It seems the problem only occurs on the iPad itself

Answer

After a discussion with Apple Support, the problem has been fixed. The problem has to do with the hardware H264 decoder. Basically, I was never removing the videos from the hardware decoder buffer by never releasing the video resources (which I thought javascript would do itself).

So I was setting the source like this:

$(vid).src = "some source file";
$(vid).play();
... some other stuff happens ...
$(vid).remove();

Doing it this way never removed the video from the decoder buffer, which meant that eventually it not be able to decode any more videos.

To fix this, this is how you must remove the video from the DOM:

$(vid).src = "some source file";
$(vid).play();
... some other stuff happens ...
$(vid).remove();
$(vid).src = "";
$(vid).load();

Now I realize that this doesn't make a ton of sense because after .remove() is called, I would have assumed that the control has been removed from the DOM and any garbage collection would do the rest automatically. However, it doesn't work like that. I hope this helps other people.