119 lines
3.5 KiB
ActionScript
119 lines
3.5 KiB
ActionScript
/**
|
|
* Simple Camera Capture application meant to be used where WebRTC is not supported
|
|
* (e.g. Safari, Internet Explorer, Opera). All orchestration is assumed to happen
|
|
* in JavaScript. The only function this application has is to capture a snapshot
|
|
* and allow a 640x480 PNG of that snapshot to be made available to the JS as a
|
|
* base64 encoded data URL.
|
|
*
|
|
* There are really only three methods:
|
|
* snap() freezes the video and returns a PNG file as a data URL string. You can
|
|
* assign this return value to an img's src attribute.
|
|
* reset() restarts the the video.
|
|
* imageDataUrl() returns the same thing as snap() --
|
|
*
|
|
* Note that this file is merely the source code for CameraCapture.swf; to make
|
|
* changes, you must edit this file, compile it to .swf, and check in the .swf
|
|
* file separately
|
|
*/
|
|
|
|
package
|
|
{
|
|
import flash.display.BitmapData;
|
|
import flash.display.PNGEncoderOptions;
|
|
import flash.display.Sprite;
|
|
import flash.events.Event;
|
|
import flash.external.ExternalInterface;
|
|
import flash.geom.Rectangle;
|
|
import flash.media.Camera;
|
|
import flash.media.Video;
|
|
import flash.utils.ByteArray;
|
|
|
|
import mx.utils.Base64Encoder;
|
|
|
|
[SWF(width="640", height="480")]
|
|
public class CameraCapture extends Sprite
|
|
{
|
|
// We pick these values because that's captured by the WebRTC spec
|
|
private const VIDEO_WIDTH:int = 640;
|
|
private const VIDEO_HEIGHT:int = 480;
|
|
|
|
private var camera:Camera;
|
|
private var video:Video;
|
|
private var b64EncodedImage:String = null;
|
|
|
|
public function CameraCapture()
|
|
{
|
|
addEventListener(Event.ADDED_TO_STAGE, init);
|
|
}
|
|
|
|
protected function init(e:Event):void {
|
|
camera = Camera.getCamera();
|
|
camera.setMode(VIDEO_WIDTH, VIDEO_HEIGHT, 30);
|
|
|
|
video = new Video(VIDEO_WIDTH, VIDEO_HEIGHT);
|
|
video.attachCamera(camera);
|
|
|
|
addChild(video);
|
|
|
|
ExternalInterface.addCallback("snap", snap);
|
|
ExternalInterface.addCallback("reset", reset);
|
|
ExternalInterface.addCallback("imageDataUrl", imageDataUrl);
|
|
ExternalInterface.addCallback("cameraAuthorized", cameraAuthorized);
|
|
ExternalInterface.addCallback("hasCamera", hasCamera);
|
|
|
|
// Notify the container that the SWF is ready to be called.
|
|
ExternalInterface.call("setSWFIsReady");
|
|
}
|
|
|
|
public function snap():String {
|
|
// If we already have a b64 encoded image, just return that. The user
|
|
// is calling snap() multiple times in a row without reset()
|
|
if (b64EncodedImage) {
|
|
return imageDataUrl();
|
|
}
|
|
|
|
var bitmapData:BitmapData = new BitmapData(video.width, video.height);
|
|
bitmapData.draw(video); // Draw a snapshot of the video onto our bitmapData
|
|
video.attachCamera(null); // Stop capturing video
|
|
|
|
// Convert to PNG
|
|
var pngBytes:ByteArray = new ByteArray();
|
|
bitmapData.encode(
|
|
new Rectangle(0, 0, video.width, video.height),
|
|
new PNGEncoderOptions(),
|
|
pngBytes
|
|
);
|
|
|
|
// Convert to Base64 encoding of PNG
|
|
var b64Encoder:Base64Encoder = new Base64Encoder();
|
|
b64Encoder.encodeBytes(pngBytes);
|
|
b64EncodedImage = b64Encoder.toString();
|
|
|
|
return imageDataUrl();
|
|
}
|
|
|
|
public function reset():String {
|
|
video.attachCamera(camera);
|
|
b64EncodedImage = null;
|
|
|
|
return imageDataUrl();
|
|
}
|
|
|
|
public function imageDataUrl():String {
|
|
if (b64EncodedImage) {
|
|
return "data:image/png;base64," + b64EncodedImage;
|
|
}
|
|
return "";
|
|
}
|
|
|
|
public function cameraAuthorized():Boolean {
|
|
return !(camera.muted);
|
|
}
|
|
|
|
public function hasCamera():Boolean {
|
|
return (Camera.names.length != 0);
|
|
}
|
|
}
|
|
}
|
|
|