Question

I'm implementing an application with ability to take a photo using webcam. As a fallback for IE I use flash object which handle webcam interaction. Everything works fine until I use this flash object inside Dart polymer element. Seems like something go wrong after code translated from Dart to Javascript.

Here's the working example using plain html & js http://flash-camera-test.herokuapp.com/
As you can see, you are able to capture webcam stream and take a photo.

Here's not working example of dart application using the same code for handling webcam http://flash-invoke-test.herokuapp.com/
It allows you dynamically insert polymer element with Flash object inside. But when you click 'Capture' it throws

Object doesn't support this property or method 'CallFunction'

function __flash__addCallback(instance, name) {
  instance[name] = function () { 
    return eval(instance.CallFunction("<invoke name=\""+name+"\" returntype=\"javascript\">" + __flash__argumentsToXML(arguments,0) + "</invoke>"));
  }
}

Where the instance parameter is my <object> with Flash inside, and the name parameter equals "capture"

Flash object source code https://github.com/addyosmani/getUserMedia.js/blob/master/dist/fallback/src/jscam.as

Html

<object id="XwebcamXobjectX" name="XwebcamXobjectX" type="application/x-shockwave-flash" data="assets/fallback/jscam_canvas_only.swf" width="352px" height="264px">
  <param name="movie" value="assets/fallback/jscam_canvas_only.swf" />
  <param name="FlashVars" value="mode=callback&amp;quality=100" />
  <param name="allowScriptAccess" value="always" />
</object>

<canvas id="canvas" width="320" height="240"></canvas>
<a onclick="window.webcam.capture()">Capture</a>

Javascript

<script>
  window.webcam = {
    width: 320, 
    height: 240, 
    mode: "callback",
    capture: function (x) {
      var cam = document.getElementById('XwebcamXobjectX');
      cam.capture(x);
    },
    save: function (x) {
      var cam = document.getElementById('XwebcamXobjectX');
      cam.save(x);
    },
    onImageSaved: function (img) {},
    debug: function () {},
    onCapture: function () {
      var canvas = document.getElementById('canvas');
      this.image = canvas.getContext("2d").getImageData(0, 0, this.width, this.height);
      this.pos = 0;
      this.save();
    },
    onTick: function () {},
    onSave: function (data) {
      var col = data.split(";"),
      img = this.image,
      tmp = null,
      w = this.width,
      h = this.height;

      for (var i = 0; i < w; i++) { 
        tmp = parseInt(col[i], 10);
        img.data[this.pos + 0] = (tmp >> 16) & 0xff;
        img.data[this.pos + 1] = (tmp >> 8) & 0xff;
        img.data[this.pos + 2] = tmp & 0xff;
        img.data[this.pos + 3] = 0xff;
        this.pos += 4;
      }

      if (this.pos >= 4 * w * h) { 
        this.onImageSaved(img);
      }

    },
    onLoad: function () {}
  };

  window.webcam.onImageSaved = function (img) {
    var canvas = document.getElementById("canvas");
    ctx = canvas.getContext("2d");
    ctx.putImageData(img, 0, 0);
  };
</script>

Code of Dart application here https://github.com/petalvlad/dart-flash-invoke-test

Was it helpful?

Solution 2

I've solved my problem using SWFObject library. Also it requires to call desired method on impl property:

var cam = document.getElementById('XwebcamXobjectX');
cam.impl.capture();

OTHER TIPS

This line is not working

var cam = document.getElementById('XwebcamXobjectX');

This doesn't find an element inside of the shadowDOM (inside a Polymer element).

I'm not a JS developer but something like this might work

var cam = document.querySelector('container-polymer').shadowRoot.querySelector('#canvas');
var cam = document.querySelector('container-polymer').webkitShadowRoot.querySelector('#canvas');
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top