how to Insert webcam stream in between two layers in actionscript? - actionscript-3

In my flash project I have 3 layers.
back layer contain Flvplayback video
middle layer contain webcam stream
front layer contain flvplayback video(with Transparent background).
webcam stream video is also transparent.
I add the stream from following code.
webCam=Camera.getCamera();
webCam.setMode(appWidth/scale,appHeight/scale,60);
video=new Video(appWidth/scale,appHeight/scale);
video.smoothing=true;
video.attachCamera(webCam);
bmpdata=new BitmapData(appWidth/scale,appHeight/scale);
bmpdata_bg=new BitmapData(appWidth/scale,appHeight/scale);
bmp=new Bitmap(bmpdata);
bmp.smoothing=true;
bmp.x = 256;
bmp.y = 374;
addChild(bmp);
and I update that webcam stream using following function
function onFrameEnter(evt:Event):void {
bmpdata.draw(video);
}
I want to know how to add this webcam stream to a middle layer and play it.
Is there any way to add this webcam stream to flvplayback in the middle layer?

As far as I know it's impossible to refer to Flash IDE layers from Actionscript. There are a couple of workarounds you can do, though.
One is to have an empty instance movieclip in the desired layer with an instance name mcStream. Then, you can use mcStream.addChild(bmp);.
Another way is to refer to the item you want it to be under (we'll call it mcOverlay) and add it at its index. addChildAt(bmp, getChildIndex(mcOverlay)) This will push add it where the overlay is and push the overlay on top of it.
I definitely recommend having a look at http://www.adobe.com/devnet/flash/quickstart/display_list_programming_as3.html

Related

Slow BitmapData.draw() with matrix from camera video

Im building an iOS AIR app using AS3/Flash builder.
The app grabs the camera stream into a video object and then draws that to a BitmapData. The camera stream is 1280x720px and the container is 2208x1242px (iPhone 7+) so I need to scale the footage. I also need to rotate it around the center point:
mat.identity();
mat.translate(-video.width/2,-video.height/2);
mat.rotate(Math.PI/2);
mat.translate(video.height/2,video.width/2);
mat.scale(deviceSize.height/cam.width,deviceSize.width/cam.height);
I have timed the drawing operation with matrix:
videoBitmapData.draw(video,mat); //9-11ms
And without matrix:
videoBitmapData.draw(video); //2-3ms
Clearly the transformation is slowing me down.
Is there a faster way to do this? Maybe drawing first, then applying the matrix somehow?
Pre-rotating something?
Leveraging native scaling/rotation?
Can I skip using the video object somehow? Accessing the camera data in a more raw form?
I see no difference using render mode GPU vs CPU.
Thanks!
Edit:
I managed to get down to about half by doing this:
1. Put the video object inside a Sprite
2. Transform the Sprite.
3. Draw the Sprite to the BitmapData.
(5-6ms)
Suprisingly, this was more consistent than this:
1. Put the video object inside a Sprite
2. Transform the video object inside the Sprite
3. Draw the sprite to the BitmapData
(5-12ms)
Bonus:
I only needed part of the pixels from the camera (full width x 100px of the height). When realizing I could use clipRect with the .draw command I managed to get down to 0-1ms.
Thanks to Organis

How do i create an animation in AS3?

I am making a game in AS3 for a school project (using the AIR api). I have about a year's worth of experience in AS3, so i would say i'm proficient but not an expert. Anyway, i have never attempted to do sprite animations in AS3 and i'm not quite sure how to approach it.
If i create a list of bitmaps and call addChild() and removeChild() to display each frame of the animation, it would affect the framerate as these functions are not very efficient (i have tried this before and it tanked my framerate if i had too many animations going at once). I have also tried creating a list of BitmapData objects, adding a bitmap to the display list, and then pointing it to a different BitmapData each frame, but this does not seem to work at all.
So what is the best way to do this? In XNA, for example, i would create a sprite class that draws to the screen using a sprite batch, then i would create a list of sprite objects and cycle through them to create the animation. Is there any way to achieve a similar result in actionscript?
First (simple) method: you can just use multi-frame MovieClip for animation. Put an image in each frame, put a MovieClip on the stage and that's all. You can control this animation using play(), stop(), gotoAndPlay(), gotoAndStop(). It will work without much problems for a generic platform game (I did that myself long ago).
Second (advanced) method: use bitmap blitting. For each animation, create a bitmap image that holds each frame of the animation. Use this image as a source for copying pixels into your current animated object. You just need to copy a particular rectangle area inside a source bitmap that corresponds to the current frame.
The actual blitting happens here
destinationBitmapData.copyPixels(sourceBitmapData, areaRectangle, destinationPoint);
Where destinationBitmapData is your "canvas" that you're blitting to; sourceBitmapData is the source image holding all animation frames; areaRectangle is the Rectangle inside the source image defining which area to copy; destinationPoint is left-top coordinate of the copy area in your canvas.
The destination canvas can be just one small object (like your game character that is moving around) or the entire game screen with all objects. I.e. instead of blitting and adding each object separately, you can just have one big canvas and blit any necessary parts directly to it.
That said, there is already a number of various ready-made engines that use blitting and even advanced techniques like 3D acceleration for 2D sprites.
One of them is Starling.

How call volume slider function in different keyFrames with different sound channels?

I have this code for my volume slider:
var stVolume:SoundTransform=new SoundTransform();
slider.addEventListener(SliderEvent.CHANGE,volslider);
function volslider(ev:SliderEvent):void
{
stVolume.volume=(ev.value/100);
sch1.soundTransform = stVolume;
}
I have many frames with different sound channels. How can I call this function with specific sound channels in each frame like shc2, sch3 and others instead use repeatedly all of function?
Is it possible send SoundChannel name whit eventListener for example:
slider.addEventListener(SliderEvent.CHANGE,volslider(/*something i don't know*/,sch10));
An AudioSource is attached to a GameObject for playing back sounds in a 3D environment. In order to play 3D sounds you also need to have a AudioListener. The audio listener is normally attached to the camera you want to use. Whether sounds are played in 3D or 2D is determined by AudioImporter settings.

Move SWF shape points with as3 code

I have SWF vector shape, how to get access to control points of this shape? I want to move some points of this shape with as3 code. SWF created with flash professional CS5, code in flash develop.
Other way to create some Sprites in CS5, and move them with as3, but how to tie them with shape control points?
Employ readGraphicsdata() to read the GraphicsPath of your shape, it contains commands and control/anchor points. You can then parse that vector to find out the point you want to alter, then you change it, then you feed the path back into your shape via graphics.clear(); graphics.drawPath(path);, or use drawGraphicsData() instead to draw the complete set of graphics shape.
The manual on readGraphicsData()
The manual on GraphicsPath class format

AS3 - looping through movieclips and rasterizing them to bitmapdatas - how to be sure frames are ready?

this is a newer version to a question i have asked before but have not received an answer to.
I am developing a mobile AIR app with many animations and tests have shown that using bitmaps and GPU rendering give the best performance across all mobile models. I receive normal vector animations from the app's artists, and have built a system which loops through these animations at runtime and draws the content into bitmapdatas.
my concern is looping through the movieclip's frames. If I have these lines of code:
for (var i:uint=1; i<mc.totalFrames+1; i++) {
mc.gotoAndStop(i);
bitmapData.draw(mc);
}
I can't be sure the frame got "constructed" before being drawn, and my tests with an Android tablet prove this right - sometimes frames aren't drawn.
This mc is off the display list obviously (we dont need to render to the screen). So is there a way to make sure the frame has been built before drawing it to a bitmapdata? (and waiting for FRAME_CONSTRUCTED, EXIT_FRAME, etc.. is obviously slow and unneeded)
any ideas?
thanx
Saar
more info to clarify:
this is a children's book. each page has animations in it. all these animations are vector animations in timelines in FLAs I receive from the devloping artists (not the users).
Every page has an FLA which i publish to a swf.
what i actually do is replace vector animations in loaded SWFs with bitmap version of them.
At app runtime, upon each new page, i load the swf, go though all the animations in it (looping through the content's children) and each movieclip i rasterize into array of bitmapdatas.
My custom "Bitmap Movieclip" places on the displaylist a replcaement bitmap for each movieclip, and on ENTER_FRAME i switch the bitmaps' bitmapdatas from the array.
this gives very hight performance
I'd suggest use a splash screen, and place your MC to be converted to the bitmap to the stage first, then draw to your bitmapData. Several issues had me force to put a DisplayObject being drawn to the stage before actual drawing once already, so this might be a quick fix for you too.
var splashBD:BitmapData=new BitmapData(stage.stageWidth,stage.stageHeight,false,0xffffff);
var splashBM:Bitmap=new Bitmap(splashBD); // draw a thing as needed here
addChild(splashBM);
addChildAt(MC_to_convert,getChildIndex(splashBM));
// then advance it by frames and draw.
sorry MY BAD
waiting for FRAME_CONSTRUCTED is the answer