IPhone / ios 8: buffer limit when capturing html5 media files?

I have a test page with the following line of HTML5 Media Capture code (and nothing but a form submit button):

<input type=file accept=image/* id=capture capture=camera>

      

On iPhone 4s with ios 8.1.2, the code only works sometimes. It successfully launches the Take Photo / Photo Library dialog, but does not reliably take a new photo image (from the phone camera) for upload. More often than not, Safari displays an error message "Something went wrong with this page and it was restarted." Typically, if I clear the cache, close Safari and restart, it works again, once or twice, and then fails. After it fails, it never seems to do well again without restarting.

It is not clear if the problem is with the buffer or even with the file size of the new photo, but assuming it works sometimes, it is not a bug in the code or an OS / browser incompatibility.

Anyone experiencing something similar? Any suggestions how to make this work?

thank

+3


source to share


2 answers


Problem:

I figured out why this is happening in Safari / iOS, as the main page seems to be "throttled" in some way, which means if the page is a bit CPU / GPU heavy and / or (?) Memory t20> not always true in most cases.

Decision:

My solution was to fit <input capture="camera" ...>

inside <iframe>

, which size is independent of the input. This works because each frame works in its own process, but at a lower priority than the main one, but enough not to be an issue here. It works 100% of the time for me now even on a fairly heavy UI using a lot of GPUs.

index.html

:



<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        #camera-button {
          display: inline-block;
          width: 100px;
          height: 100px;
          background: red;
          border: 5px solid #eee;
          padding: 10px;
          z-index: 2147483647;
        }

        #camera-frame {
          width: 100px;
          height: 100px;
          background-color: transparent;
          opacity: 0;
        }
    </style>
</head>
<body>
    <span id="camera">
      <iframe id="camera-frame" src="camera.html" scrolling="no" frameBorder="0" allowTransparency="true" seamless>
    </span>

    <script>
      (function() {
          window.onCameraChanged = function(event) {
              var files;

              console.log("[index.html]: snap!", arguments);

              if (event.target) {
                  files = event.target.files;

                  console.log("[index.html]: files", files);

                  alert("[index.html]:", files.length, "files from camera.");
              }
          };
      }).call(this);
    </script>
</body>
</html>

      

camera.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
        body,
        html {
          width: 100%;
          height: 100%;
          margin: 0;
          padding: 0;
        }

        #camera-input {
          display: block;
          width: 100%;
          height: 100%;
          position: absolute;
          outline: none;
          box-shadow: none;
          border: none;
        }
    </style>
</head>
<body>
    <input id="camera-input" type="file" capture="camera" accept="image/*" onchange="window.onCameraChanged">

    <script>
      (function() {
          var el;

          window.onCameraChanged = function(event) {
              var files;

              console.log("[camera.html]: snap!", arguments);

              if (event.target) {
                  files = event.target.files;

                  if (window.parent) {
                    if (typeof window.parent.onCameraChanged === 'function') {
                      window.parent.onCameraChanged(event);
                    }

                    return window.parent.cameraFiles = files;
                  }
              }


          if (el = document.querySelector('#camera')) {
            el.onchange = window.onCameraChanged; // chrome
          }

      }).call(this);
    </script>
</body>
</html>

      

Something like that.

+5


source


I'll offer this as a preliminary solution since it hasn't failed yet, but I'm not sure why this is required. When clicking the button to capture the image, the first thing I do now is the following:

$('#capture').val('');



This clears the form before adding a new image. I tried reset()

it but it didn't work. Therefore, there is a problem with changing the image in the form after it has been added - it must first be removed, not just overwritten.

+1


source







All Articles