10

I am setting up an UIWebView to show the contents of a web camera through a URL that retrieves an MPJEG-stream.

I found out that if I wanted to switch to a different camera, it looked smoother if I did not reset the entire contents of the UIWebView, but instead set up a javascript function in the page I loaded into it, to replace the contents of the image, like this:

<img id='iImage' src='about:blank'>
<script type='text/javascript'>
function show(url)
{
    iImage.src = url;
}
</script>

If I did not do this, every time I switched to a new url, the UIWebView went white for a second or two until the new content was ready to be displayed, with the above code it just replaces the contents directly, no whiteout.

However, if I switch back and forth between two videostreams, at some point I get an error in the UIWebView, and by trial and error I've found out that this happens the 4th time I show the same videostream in the view. If I try to open up 4 videostreams in browser-tabs, the 4th get stuck in a loading cycle, until I close one of the previous three.

This leads me to believe that:

  1. The camera in question can only serve 3 streams at the same time
  2. Changing the src attribute on the <img...> tag does not close the previous stream

Can this be linked to keepalive? Could the webkit browser system keep the previous streams alive, even though I have stopped showing them in the <img...> tag?

Basically, to reproduce I can do this:

  1. Set up the above content in a UIWebView
  2. Call this 4 times: wv.EvaluateJavascript("show(url)")

On the 4th call, I get a blue question mark in the middle.

Can keep-alive be the culprit? And if so, can I control it?

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
  • Keep-alive is supposed to allow the browser to reuse a connection to get additional content. So you changing the URL (I assume to the same domain but different path), the previous connection should be reused. Your problem sounds like new sockets get opened for each image url. Could be due to WebKit bug with MJPEG. Try replacing the entire image HTML element and see if that helps. – Léo Natan May 12 '12 at 16:50
  • Yes, that works, but that is explicitly what I want to avoid doing. – Lasse V. Karlsen May 12 '12 at 17:26
  • Why is that? Changing the image element should not introduce the problem you had replacing all the content of web view. – Léo Natan May 12 '12 at 17:46
  • Ai, sorry, I misunderstood what you were saying, I'll try what you suggest. – Lasse V. Karlsen May 12 '12 at 18:58
  • No, that still blanks out the screen to white temporarily, so it has the same problem as just reloading the entire page. – Lasse V. Karlsen May 13 '12 at 09:58
  • From a cursory skim of the WebKit source code, it doesn't appear that a resource is forcibly stopped from loading if it is no longer needed after it starts loading. It appears that the browser optimistically hopes it finishes loading to be able to cache it. MJPEGs probably cause a problem with that idea. – Alex Taylor May 13 '12 at 13:58
  • That actually makes a lot of sense, that is, that that might be the cause of this, caching a never-ending stream doesn't sound like a lot of sense, but I bet that if there is a way for a stream like this to flag itself as "do not cache", these cheap cameras doesn't use it. – Lasse V. Karlsen May 13 '12 at 14:08
  • Why not just stream your camera captures in h264 streams? – Léo Natan May 13 '12 at 17:49
  • The camera in question does not support that. – Lasse V. Karlsen May 13 '12 at 17:53

1 Answers1

5

This is being caused by WebKit not stopping loading of an image resource even if the source is changed. This normally doesn't cause a problem for images but a never-ending streaming image will cause it to never let go until the page is reloaded.

There is a bug filed against Chromium that points at this issue. https://code.google.com/p/chromium/issues/detail?id=73395

From the comment thread, a workaround is to call window.stop() before changing the image. This is the same as clicking stop in the browser and causes all loading resources to abort. Hopefully, the fact that this isn't causing the page to reload will avoid your white flash.

I'd give the following a try:

<img id='iImage' src='about:blank'>
<script type='text/javascript'>
function show(url)
{
    window.stop();
    iImage.src = url;
}
</script>
Alex Taylor
  • 1,823
  • 1
  • 13
  • 26