How to get work calling methods of embedded Flash object placed inside Dart polymer element
-
21-12-2019 - |
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&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
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');