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;
}
}
}
Related
I'm trying to receive a stream of a NetGroup (television) but it fails at some point. Here is the code (reduced to a testcase):
package lib
{
import flash.events.NetStatusEvent;
import flash.external.ExternalInterface;
import flash.media.SoundTransform;
import flash.media.Video;
import flash.net.GroupSpecifier;
import flash.net.NetConnection;
import flash.net.NetGroup;
import flash.net.NetStream;
import flash.net.NetStreamPlayOptions;
import mx.core.FlexGlobals;
public class player
{
private var connection:NetConnection;
private var group:NetGroup;
private var group_option:GroupSpecifier;
private var self:Object;
private var stream:NetStream;
private var stream_option:NetStreamPlayOptions;
private var video:Video;
private function _connect():void
{
self.connection = new NetConnection();
self.connection.addEventListener(NetStatusEvent.NET_STATUS, self._event_net_status);
self.connection.connect('rtmfp://p2p.peer-stream.com');
}
private function _event_net_status(event:NetStatusEvent):void
{
if(event.info.code === '')
return;
ExternalInterface.call('echo', 'status', event.info.code, false);
switch(event.info.code)
{
case 'NetConnection.Connect.Success':
self._p2p_start();
break;
case 'NetGroup.Connect.Success':
self._stream_init();
break;
case 'NetStream.Connect.Success':
self._stream_start();
break;
}
}
private function _p2p_start():void
{
self.group_option = new GroupSpecifier('G:0101010c0b0e70726f2073696562656e00');
self.group_option.ipMulticastMemberUpdatesEnabled = true;
self.group_option.multicastEnabled = true;
self.group_option.objectReplicationEnabled = true;
self.group_option.postingEnabled = true;
self.group_option.routingEnabled = true;
self.group_option.serverChannelEnabled = true;
self.group = new NetGroup(self.connection, self.group_option.groupspecWithAuthorizations());
self.group.addEventListener(NetStatusEvent.NET_STATUS, self._event_net_status);
}
private function _stream_init():void
{
self.stream = new NetStream(self.connection, self.group_option.groupspecWithAuthorizations());
self.stream.addEventListener(NetStatusEvent.NET_STATUS, self._event_net_status);
}
private function _stream_start():void
{
self.video.attachNetStream(self.stream);
self.stream.soundTransform = new SoundTransform();
self.stream_option = new NetStreamPlayOptions();
self.stream_option.streamName = 'G:0101010c0b0e70726f2073696562656e00';
self.stream.play2(self.stream_option);
}
public function player():void
{
super();
FlexGlobals.topLevelApplication.stage.quality = 'BEST';
self = this;
self.video = new Video(640, 480);
FlexGlobals.topLevelApplication.video_box.addChild(self.video);
self.video.smoothing = true;
self._connect();
}
}
}
The ExternalInterface call there shows me just the passed info in a textfield (I'm testing this in a browser). Here is the result of this output:
NetConnection.Connect.Success
NetGroup.Connect.Success
NetStream.Connect.Success
NetStream.Play.Reset
NetStream.Play.Start
But nothing happens on the player. Here are my thoughts:
I'm using the same string as GroupSpecifier and streamName but I'm assuming this is wrong. If so how can I get the stream name of the NetGroup?
I'm enabling everything from the GroupSpecifier as I don't know what are the minimum requirements to receive a stream and pass it then to another clients. Maybe enabling all makes some troubles here.
Maybe somebody can tell me how I can solve this problem to finally see a stream.
I was able to solve the problem: The streamName was indeed wrong and I could manually figure out the correct name. Also instead of using new GroupSpecifier() I must pass the known group-string directly to the NetGroup and NetStream object.
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);
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.
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));
}
}
}
}
I'm having an issue with flash, which I am not really familiar with. I'm basing this code off of what came with the wowza media server in the video chat example, but unlike that example flash is not prompting me for whether or not to allow the video camera.
Below is my actionscript:
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.media.Camera;
import flash.media.Microphone;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.system.Security;
import flash.system.SecurityPanel;
import flash.display.Sprite;
import flash.text.TextField;
import flash.events.StatusEvent;
public class QandA extends Sprite {
Security.LOCAL_TRUSTED;
private var nc:NetConnection = null;
private var camera:Camera;
private var microphone:Microphone;
private var nsPublish:NetStream = null;
private var nsPlay:NetStream = null;
private var videoCamera:Video;
public var prompt:TextField;
public function QandA():void {
stage.align = "TL";
stage.scaleMode = "noScale";
videoCamera = new Video(160,120);
addChild(videoCamera);
camera = Camera.getCamera();
microphone = Microphone.getMicrophone();
if (camera.muted) {
trace("Camera Muted");
Security.showSettings(SecurityPanel.CAMERA);
camera.addEventListener(StatusEvent.STATUS, statusHandler);
} else {
startCamera();
}
}
private function statusHandler(e:StatusEvent):void {
if (e.code == "Camera.Unmuted") {
trace("Camera Unmuted");
startCamera();
camera.removeEventListener(StatusEvent.STATUS, statusHandler);
} else {
trace("StatusEvent: " + e.code + " " + e.toString());
}
}
private function startCamera():void {
// here are all the quality and performance settings that we suggest
camera.setMode(160, 120, 12, false);
camera.setQuality(0, 75);
camera.setKeyFrameInterval(24);
microphone.rate = 11;
microphone.setSilenceLevel(0);
nc = new NetConnection();
nc.connect("rtmp://localhost/live/");
// get status information from the NetConnection object
nc.addEventListener(NetStatusEvent.NET_STATUS, ncOnStatus);
}
private function nsPublishOnStatus(infoObject:NetStatusEvent):void
{
trace("nsPublish: "+infoObject.info.code+" ("+infoObject.info.description+")");
}
private function ncOnStatus(infoObject:NetStatusEvent):void
{
trace("nc: "+infoObject.info.code+" ("+infoObject.info.description+")");
nsPublish = new NetStream(nc);
nsPublish.addEventListener(NetStatusEvent.NET_STATUS, nsPublishOnStatus);
nsPublish.bufferTime = 0;
nsPublish.publish("testing");
// attach the camera and microphone to the server
nsPublish.attachCamera(camera);
nsPublish.attachAudio(microphone);
}
}
I'm fairly confident it's something simple; as I've seen this code in/on countless sites when discussing how to publish to a live server.
Any help would be greatly appreciated, I've attempted using this code on a webserver to see if it was simply local security settings, but that was not the case.
Logs I receive when debugging the application in Flash CS5:
Attempting to launch and connect to Player using URL D:\development\qanda\qandaHost.swf
[SWF] D:\development\qanda\qandaHost.swf - 3583 bytes after decompression
Camera Muted
nc: NetConnection.Connect.Success (Connection succeeded.)
nsPublish: NetStream.Publish.Start (Publishing testing.)
Below is wrong:
Security.showSettings(SecurityPanel.**CAMERA**);
You should write:
Security.showSettings(SecurityPanel.**PRIVACY**);
I wasn't attaching the camera to the video, thus I couldn't see myself -- even though the video was in fact streaming.
private function startCamera():void {
trace("Attempting to start camera");
// here are all the quality and performance settings that we suggest
camera.setMode(160, 120, 12, false);
camera.setQuality(0, 75);
camera.setKeyFrameInterval(24);
videoCamera.attachCamera(camera);
microphone.rate = 11;
microphone.setSilenceLevel(0);
}