as3 Adobe Air access iPad device camera - actionscript-3

Is there a way you can use as3 to access iPad's camera?
I mean start the Camera within the app itself
have ability take a shoot and save the image to byteArray and applying the image to the background or doing some manipulation
I have done some research most of them just showing how to access the android devices.
Thanks for any suggestion or help.

Yes, you can absolutely do this. The beauty of Flash is that the code to do it is the same that you would use on Android or a PC.
Literally, you can do this to connect the camera to a Video object:
var camera:Camera = Camera.getCamera();
var video=new Video();
video.attachCamera(camera);
this.addChild(video); // 'this' would be a Sprite or UIComponent, etc...
There's a lot more to do if you want to do something useful, but it's fairly straight forward once you get started :)

bluebill1049, I'm not certain from the thread if you got what you were looking for, but I did see your request for the whole class. I found the same information (that Jason Sturges posted in his answer) in this post.
take photo using Adobe Builder (flex) for iOS
Unlike his reply here, his reply to that post had had a link to a great tutorial on building a mobile app and it was from that tutorial that this code was lifted/quoted. It requires an event class (event.CameraEvent - only a few lines) that's contained in that project/tutorial so it's important to be able to go back to the source, as it were. That source is located here:
http://devgirl.org/files/RIAUnleashed/
My thanks to Jason. Just so you don't have to dig, here's the event class that's missing from the quote:
package events
{
import flash.events.Event;
import flash.filesystem.File;
public class CameraEvent extends Event
{
public static const FILE_READY:String = "fileReady";
public var file:File;
public function CameraEvent(type:String, file:File=null, bubbles:Boolean = true, cancelable:Boolean = true)
{
super(type, bubbles, cancelable);
this.file = file;
}
}
}
Hope that helps!

Using the loader is not the only way to access the image bytes on iOS. It turns out the data is already in JPEG format to begin with, so encoding it again is not necessary.
Just do a mediaPromise.open() to get at the bytes and save them directly instead.

XpenseIt example code offers this camera implementation:
Class: CameraUtil:
package utils
{
import events.CameraEvent;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.MediaEvent;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.media.CameraRoll;
import flash.media.CameraUI;
import flash.media.MediaPromise;
import flash.media.MediaType;
import flash.utils.ByteArray;
import mx.events.DynamicEvent;
import mx.graphics.codec.JPEGEncoder;
[Event(name = "fileReady", type = "events.CameraEvent")]
public class CameraUtil extends EventDispatcher
{
protected var camera:CameraUI;
protected var loader:Loader;
public var file:File;
public function CameraUtil()
{
if (CameraUI.isSupported)
{
camera = new CameraUI();
camera.addEventListener(MediaEvent.COMPLETE, mediaEventComplete);
}
}
public function takePicture():void
{
if (camera)
camera.launch(MediaType.IMAGE);
}
protected function mediaEventComplete(event:MediaEvent):void
{
var mediaPromise:MediaPromise = event.data;
if (mediaPromise.file == null)
{
// For iOS we need to load with a Loader first
loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleted);
loader.loadFilePromise(mediaPromise);
return;
}
else
{
// Android we can just dispatch the event that it's complete
file = new File(mediaPromise.file.url);
dispatchEvent(new CameraEvent(CameraEvent.FILE_READY, file));
}
}
protected function loaderCompleted(event:Event):void
{
var loaderInfo:LoaderInfo = event.target as LoaderInfo;
if (CameraRoll.supportsAddBitmapData)
{
var bitmapData:BitmapData = new BitmapData(loaderInfo.width, loaderInfo.height);
bitmapData.draw(loaderInfo.loader);
file = File.applicationStorageDirectory.resolvePath("receipt" + new Date().time + ".jpg");
var stream:FileStream = new FileStream()
stream.open(file, FileMode.WRITE);
var j:JPEGEncoder = new JPEGEncoder();
var bytes:ByteArray = j.encode(bitmapData);
stream.writeBytes(bytes, 0, bytes.bytesAvailable);
stream.close();
trace(file.url);
dispatchEvent(new CameraEvent(CameraEvent.FILE_READY, file));
}
}
}
}

Related

Simple Camera in Actionscript/flex How to?

I am having no luck with trying to create a simple camera in actionscript. I don't want any controls- just a stage asking for permissions, then a livevideo of me in a window. Nothing fancy
Here's what I have so far: (the latest failure...)
package {
import flash.display.Sprite;
import flash.media.*;
public class FlashCamera extends Sprite
{
var cam:FlashCamera = Camera.getCamera();
var vid:Video = new Video();
vid.attachCamera(cam);
addChild(vid);
}
}
It's throwing this error when I try to compile this:
call to a possibly undefined method getCamera through a reference with static type Class
I'm compiling with flex in the windows command line like this:
(path to SDK)/bin/mxmlc Camera.as
Mind you, I am new to actionscript/flash development.
Can someone please explain what I am doing wrong?
For one thing, you're using classes of the name Camera from two different namespaces without disambiguating between the two. You'll probably also have to import other packages to support API versions of Camera and Video though (flash.media.Camera and flash.media.Video), but I'm not completely convinced this won't be done implicitly, especially not knowing the environment you're using.
Another thing you have to watch out for though, as far as realtime errors go, is when it takes the browser a few seconds to actually get the camera - just keep trying to grab it for at least a few seconds until it returns something other than null.
Found somethng that actually works, and will be adapting it for my needs:
package
{
import flash.display.Sprite;
import flash.events.NetStatusEvent;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Camera;
import flash.media.Microphone;
import flash.media.Video;
public class FlashVideo extends Sprite
{
private var nc:NetConnection;
private var good:Boolean;
private var rtmpNow:String;
private var nsIn:NetStream;
private var nsOut:NetStream;
private var cam:Camera;
private var mic:Microphone;
private var vidLocal:Video;
private var vidStream:Video;
public function FlashVideo()
{
trace("Hello testing");
rtmpNow = "rtmp://localhost/LiveStreams";
nc=new NetConnection();
nc.connect(rtmpNow);
nc.addEventListener(NetStatusEvent.NET_STATUS,checkCon);
setCam();
setMic();
setVideo();
}
private function checkCon(e:NetStatusEvent):void
{
good = e.info.code == "NetConnection.Connect.Success";
if (good)
{
nsOut = new NetStream(nc);
nsOut.attachAudio(mic);
nsOut.attachCamera(cam);
nsOut.publish("left","live");
nsIn = new NetStream(nc);
nsIn.play("right");
vidStream.attachNetStream(nsIn);
}
}
private function setCam()
{
cam = Camera.getCamera();
cam.setKeyFrameInterval(9);
cam.setMode(640,400,30);
cam.setQuality(0,95);
}
private function setMic()
{
mic = Microphone.getMicrophone();
mic.gain = 85;
mic.rate = 11;
mic.setSilenceLevel(15,2000);
}
private function setVideo()
{
vidLocal = new Video(cam.width,cam.height);
addChild(vidLocal);
vidLocal.x = 15;
vidLocal.y = 30;
vidLocal.attachCamera(cam);
vidStream = new Video(cam.width,cam.height);
addChild(vidStream);
vidStream.x=(vidLocal.x+ cam.width +10);
vidStream.y = vidLocal.y;
}
}
}

play flv using netStream appendBytes

I know that there are many ways to play an FLV file but considering my project requirements, I need to play the flv using URLStream and NetStream
here's the complete sample code that I'm doing my tests on:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.NetStatusEvent;
import flash.events.ProgressEvent;
import flash.utils.ByteArray;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.NetStreamAppendBytesAction;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.media.Video;
import flash.net.URLStream;
/**
* ...
* #author Hadi Tavakoli
*/
public class Main extends Sprite
{
private var netConnection:NetConnection;
private var netStream:NetStream;
private var ul:URLStream;
private var video:Video;
private var bytes:ByteArray = new ByteArray();
private var _isSeek:Boolean = false;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
video = new Video();
addChild(video);
netConnection = new NetConnection();
netConnection.addEventListener(NetStatusEvent.NET_STATUS, netConnectionStatusHandler);
netConnection.connect(null);
}
private function netConnectionStatusHandler(ev:NetStatusEvent):void
{
switch(ev.info.code)
{
case 'NetConnection.Connect.Success':
ul = new URLStream();
ul.addEventListener(ProgressEvent.PROGRESS, onProgress);
ul.load(new URLRequest('01.flv'));
break;
}
}
private function onProgress(e:ProgressEvent):void
{
ul.readBytes(bytes, bytes.length);
if (!netStream)
{
netStream = new NetStream(netConnection);
netStream.client = { };
video.attachNetStream(netStream);
netStream.play(null);
trace("BEGIN")
netStream.appendBytesAction(NetStreamAppendBytesAction.RESET_BEGIN);
}
else
{
if (!_isSeek)
{
trace("SEEK")
netStream.appendBytesAction(NetStreamAppendBytesAction.RESET_SEEK);
_isSeek = true;
}
}
if (bytes.length == e.bytesTotal)
{
trace("END")
netStream.appendBytesAction(NetStreamAppendBytesAction.END_SEQUENCE);
}
netStream.appendBytes(bytes);
trace("-")
}
}
}
I'm not sure if I am using "appendBytes" method correctly? the video is shown but only a very few first frames will play and then the video stops!
in my eyes it seems all ok! do you have any advice on where my problem is?
I don't think you need the if (!_isSeek) block. It looks like you are pushing the bytes as you receive them in a sequential order and so there's never a seek. It looks like it will push the first set of bytes and then append a seek action and append the rest of the bytes. Try just removing that block and see if it works.
Otherwise I think it's ok.
in "ul.readBytes(bytes, bytes.length);" line, there is a bug i guess. It's never worked for me also. It always return full length (from 0 to the available bytes). So It have a huge memory leak. But if you are using flash player 11.4 or later, you can change it like this.
ul.position = bytes.length;
ul.readBytes(bytes);

gotoAndPlay in embedded movieclip

I am working on an Air 2.6 project with an embedded SWF.
I am using the following embed code:
[Embed(source = "../../assets/click_feedback.swf", symbol="sub_circle")]
[Bindable]
public static var click_feedback:Class;
And the following code to get an instance of the click_feedback class:
private var cfb:MovieClip = new Assets.click_feedback() as MovieClip
The problems are:
The asset sub_circle has a frame labeled 'respond'. However, it just plays non stop whether or not the label is called with gotoAndPlay.
And, at the end of the animation, there is an Event.COMPLETE called, which is not being picked-up by my code.
I have tested the sub_circle asset in CS5 where I built it, and, in that environment it does not animate until 'respond' is called, and the event it triggers can be heard by my script.
Is this the correct way to handle embedded assets from an SWF?
Embedding of separate symbols from swf in general isn't a good idea:
It slows the compilation of your project, because of compiler must transcode swf format.
Embedding delete ALL AS code from timeline (I didn't check, but may be it remove labels as well, and it can be the reason of your issue).
I recommend embed the hole swf file and loads its bytes in runtime, a little more code to handle the async loading, but much more freedom and flexibility in use:
you safe all as3 code
you can choose ApplicationDomain where to load classes
you can easily switching from Embedding to runtime swf loading by url at any time, if you want to separate the as code and art/sounds assets.
organize your assets to library with the AssetsManager (with api like load(ByteArray or URL), getSkin(name):DisplyObject)
Code example adapted for your assets:
package
{
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
[SWF(width="800", height="200", backgroundColor="0x8B8B8B")]
public class astest extends Sprite
{
[Embed(source="../../assets/click_feedback.swf", mimeType="application/octet-stream")]
private static const common_art:Class;
private var loader:Loader;
private var domain:ApplicationDomain = ApplicationDomain.currentDomain;
public function astest()
{
init();
}
public function init():void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var loaderContext:LoaderContext = new LoaderContext(false, domain);
loaderContext.allowCodeImport = true;
loader.loadBytes(new common_art() as ByteArray, loaderContext);
}
private function onLoaded(event:Event):void
{
var clip:MovieClip = getSkin("sub_circle") as MovieClip;
addChild(clip);
}
private function getSkin(name:String):DisplayObject
{
if(domain.hasDefinition(name))
{
var clazz:Class = domain.getDefinition(name) as Class;
return new clazz() as DisplayObject;
}
return null;
}
}
}

Flash Builder 4.6 Mobile Flex AS3: How to communicate with embedded SWF

I have a Flash Barcode scanner (camera) and want to use it in a mobile project to scan QR-Codes. It would be nice that it is possible to re-use this SWF and embedded it into a mobile Flex application. The SWF is made in Flash CS5.
So far, embedding (and add it to the stage and showing it) is successful but how do i communicate with the SWF? For example calling a function of it or by using events.
Here is a code snippet:
[Embed(source="../cam/cam.swf")]
private var cam:Class;
....
....
public const EVT_SNAPSHOT : String = "onSnapShot";
public var camera : Object;
public function onInit(e:Event) : void
{
this.camera = new cam();
this.camera.addEventListener(Event.ADDED_TO_STAGE, this.cameraInit );
this.stage.addChild( this.camera as DisplayObject );
}
private function cameraInit(e:Event):void
{
trace( 'Added to stage' );
this.stage.addEventListener( EVT_SNAPSHOT, this.cameraDoScan ); // does not bind?
trace( this.camera.hasOwnProperty('getAppInfo') ); // shows 'false'
}
private function cameraDoScan(e:MouseEvent):void
{
trace('MouseClick!');
}
Does anyone know to communicate with this 'thing'?
The most functional way to use external swf module is to load it into current ApplicationDomain, so you will have access to all classes contained in this loaded swf:
package
{
import flash.display.DisplayObject;
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.utils.ByteArray;
import flash.utils.getDefinitionByName;
public class astest extends Sprite
{
[Embed(source="/../assets/art.swf", mimeType="application/octet-stream")]
private static const art:Class;
public function astest()
{
var artBytes:ByteArray = new art() as ByteArray;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onArtLoaded);
loader.loadBytes(artBytes, new LoaderContext(false, ApplicationDomain.currentDomain));
}
protected function onArtLoaded(e:Event):void
{
var domain:ApplicationDomain = ApplicationDomain.currentDomain;
if(domain.hasDefinition("welcome_view"))
{
var moduleClass:Class = domain.getDefinition("welcome_view") as Class;
var module:Object = new moduleClass();
//module.moduleFunction();
addChild(module as DisplayObject);
}else
{
trace("loaded swf hasn't class 'welcome_view'");
}
}
}
}

Away3D fail to load AWD

I've follow the tutorial from this link:
http://www.adobe.com/devnet/flashplayer/articles/creating-games-away3d.html
But the code seem like got problems with it that I can't even load the 3D vase.
Here is the code:
package
{
import away3d.containers.View3D;
import away3d.events.LoaderEvent;
import away3d.loaders.Loader3D;
import away3d.loaders.parsers.Parsers;
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLRequest;
public class Main extends Sprite
{
private var _view:View3D;
private var _loader:Loader3D;
public function Main()
{
_view = new View3D();
_view.backgroundColor = 0x666666;
_view.antiAlias = 4;
this.addChild(_view);
this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
Parsers.enableAllBundled();
_loader = new Loader3D();
_loader.addEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
_loader.addEventListener(LoaderEvent.LOAD_ERROR, onLoadError);
_loader.load( new URLRequest('vase.awd') );
}
private function onResourceComplete(ev:LoaderEvent):void
{
_loader.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
_loader.removeEventListener(LoaderEvent.LOAD_ERROR, onLoadError);
_view.scene.addChild(_loader);
}
private function onLoadError(ev:LoaderEvent):void
{
trace('Could not find', ev.url);
_loader.removeEventListener(LoaderEvent.RESOURCE_COMPLETE, onResourceComplete);
_loader.removeEventListener(LoaderEvent.LOAD_ERROR, onLoadError);
_loader = null;
}
private function onEnterFrame(ev:Event):void
{
_loader.rotationY = stage.mouseX - stage.stageWidth / 2;
_view.camera.y = 3 * (stage.mouseY - stage.stageHeight/2);
_view.camera.lookAt(_loader.position);
_view.render();
}
}
}
Any idea where the error is? Or is it got any tutorial that teaching how to load AWD files into flash?
Thanks.
I would suggest you to use AssetLibrary to load your Model, its very simple and easy to handle all the things that models contains,
AssetLibrary.addEventListener( AssetEvent.ASSET_COMPLETE, onAssetComplete );
AssetLibrary.addEventListener( LoaderEvent.RESOURCE_COMPLETE, onResourceComplete );
AssetLibrary.addEventListener( LoaderEvent.LOAD_ERROR, onLoadError );
for detailed example check This
I hope it helps you
delete "Parsers.enableAllBundled();"
try this:
AssetLibrary.enableParser(AWD1Parser)
or
AssetLibrary.enableParser(AWD2Parser)
or
var aWD2Parser:AWD2Parser=new AWD2Parser();
_loader.load(new URLRequest('vase.awd'),null,"vase.awd",aWD2Parser);
The vase AWD file adobe has with their tutorial is no longer valid. The AWD spec changed and adobe never updated their tutorial. You will usually get an End Of File error if you try to load it.