How to stop Camera capture in as3, flex? - actionscript-3

I'm starting work on flex using flashbuilder and I was testing cameras. Now I can get a camera to display but when I try using the stop button to stop the camera from capturing, ti doesn't work this is what I tried.
var video:Video;
public function startCamera(muteCam:Boolean=false):void{
video = new Video(); // this will work after the import is done
var camera:Camera=Camera.getCamera();
if(muteCam){
video.attachCamera(camera);
vidHolder.addChild(video);
}else{
video.attachCamera(null);
if(contains(video))
vidHolder.removeChild(video);
//camera=null;
}
}
These are my components
<s:Button x="116" y="28" label="Start" click="startCamera(true)"/>
<s:VideoDisplay id="vidHolder" x="31" y="87" width="200" height="300"
/>
<s:Button id="stop" x="208" y="28" label="Stop" click="startCamera(false)"/>

You are creating a new Video object every single time you call startCamera. So you are trying to remove a video which isn't actually on the stage.
Instead of:
video = new Video();
Use this:
if ( !video ) {
video = new Video();
}
That will only create the Video object if it has not already been created (!object evaluates the object to see if it is null or a boolean set to false. object == null would evaluate the same way in this case)

Related

Mission : Create a connection with a list of videos and a canvas make them plays 1 by 1, without stops, no click function, ended AddEventListener

I would like to make a video playlist, (Source video is copied in a canvas to block controls,
options like download video), i made 2 Drag and Drop lists and i would like to connect 1 drag n Drop list to the canvas (that is also the video player box) then play the videos 1 by 1,
witout stops, no click function, function AddEventListener ended in the canvas box.
I worth for 2 videos, here is some parts of the code :
<script type="text/javascript">
// listener function changes src
function myNewSrc() {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.src = "videos/80s_Mix_II-700.mp4";
myVideo.src = "videos/80s_Mix_II-700.webm";
myVideo.load();
myVideo.play();
}
// add a listener function to the ended event
function myAddListener() {
var myVideo = document.getElementsByTagName('video')[0];
myVideo.addEventListener('ended', myNewSrc, false);
}
</script>
<body onload="myAddListener()">
<div id="video_player_box">
<video id="video" autoplay autobuffer width="1" height="1" >
<source src="videos/milenio_6_minimix_700.mp4" type="video/mp4">
<source src="videos/milenio_6_minimix_700.webm" type="video/webm">
<source src="videos/milenio_6_minimix_700.ogg" type="video/ogg">
</video>
<div align="center">
<canvas id="myCanvas" width="1130" height="560">
Your browser does not support the HTML5 canvas tag.</canvas>
</div>
<script>
var v = document.getElementById("video");
var c = document.getElementById("myCanvas");
ctx = c.getContext('2d');
v.addEventListener('play', function() {
var i = window.setInterval(function()
{
ctx.drawImage(v, 5, 5, 1130, 560)
}, 20);
}, false);
v.addEventListener('pause', function() {
window.clearInterval(i);
}, false);
v.addEventListener('ended', function() {
clearInterval(i);
}, false);
</script>
</div>
<div id="cadre2" ondrop="drop(event)" ondragover="allowDrop(event)"> <p> Canal VIP </p>
<ol><li> <video src="videos/milenio_6_minimix_700.mp4" draggable="true"
ondragstart="drag(event)" id="drag1" width="288" height="188" alt="Video 1">
</video></li>
...
The idea is to say get the videos from #cadre2, play them, 1 by 1, in the canvas until the end and loop, make the same path.
I made my list Drag and drop to have the decision to modify online the video playlist, more flexible.
Hope to have some advises!! I'm not pro of Php and dynamic, i've started Javascript but
it takes time to be pro!
If you have some code, it will be really appreciated!! Thanks in advance!!!
In order to make a player that can play videos continously you need to implement some sort of double-buffering at load level (I'll demonstrate later).
But there are some issues in the code as it is -
myVideo.src = "videos/80s_Mix_II-700.mp4";
myVideo.src = "videos/80s_Mix_II-700.webm";
myVideo.load();
This will simply override the source property. And setting the source will automatically start loading the video.
The proper way to check for video support is using the method canPlayType like this:
/// which format can we play?
if (video.canPlayType("video/mp4").length > 0) {
video.src = urlToMP4;
} else if (video.canPlayType("video/webm").length > 0) {
video.src = urlToWEBM;
} else {
video.src = urlToOggOrSomeOtherSupportedFormat;
}
The problem though with canPlayType is that it returns maybe in Chrome and probably in Firefox. It returns an empty string if it cannot play the video type so we check if string contains anything to determine the possibility for this format to play.
You also need to implement an event listener for canplay which tells your app that the video was loaded and buffered successfully and can now be started using play (or starts if autoplay was set to true).
I would recommend a simple procedure like this:
Create an array of objects with the video URLs you want to play for the various formats
When first video is loaded (canplay) start loading the next video in the list when start playing the first
I would also recommend a re-factoring of the code to handle loading and playing.
For example, if we initialize an array to hold our custom video objects:
var list = [];
we can now add URLs like this:
function addVideo(urlMP4, url) {
list.push({
urlMP4: urlMP4,
url: url,
isReady: false
})
}
Then this function will let us add a MP4 and a link for WEBM or OGG:
addVideo('http://video1.mp4', 'http://video1.webm');
addVideo('http://video2.mp4', 'http://video2.webm');
addVideo('http://video3.mp4', 'http://video3.ogg');
...
Then we need to start a "chain-reaction" so to speak by using a double-buffered loading mechanism. The first time we need to trigger it manually:
getVideo(list[0], play);
function getVideo(vid, callback) {
/// which video is playing? (see demo for details)
var video = (isVideo1 === false ? video1 : video2),
me = this;
/// we need to know when video is ready
video.addEventListener('canplay', canPlay, false);;
/// call this when ready
function canPlay(e) {
/// remove event listener (in case setting new src does not trigger)
video.removeEventListener('canplay', canPlay, false);
/// update our object with useful data, for example:
vid.isReady = true;
/// if we provided a callback then call that with custom video object
if (typeof callback === 'function')
callback(vid);
}
/// check video format support (see demo for details)
if (video.canPlayType("video/mp4").length > 0) {
video.src = vid.urlMP4;
} else {
video.src = vid.url;
}
}
Our play function will manage which video is playing and what to play next:
function play(){
/// what video is currently not playing?
var video = (isVideo1 === false ? video1 : video2),
next = current; /// current is index for list, starts at 0
/// switch
isVideo1 = !isVideo1;
/// increment for next video to platy and start over if list ended
next++;
if (next > list.length - 1) next = 0;
/// only attempt next if there are more videos than 1 in list
if (list.length > 0) getVideo(list[next]);
/// start already loaded video (getVideo)
video.play();
isPlaying = true;
/// set current to next in list
current = next;
}
Here is an online demo
I made this demo just to demonstrate the double-buffered loading. Feel free to incorporate in your own project with pause, stop etc.
There is room to move things around in the code I provided here but it's as said just example of the principle. You also need to consider a scenario where next video takes longer to load then what current video playing takes to play (ie. current video ends before next has finished loading). This is not checked in this code.
In order to properly synchronize video frames with canvas you need to use requestAnimationFrame or you will get freezes from time to time.
In the demo the loop runs all the time. You can consider to implement a conditional to stop the loop. I just implemented a conditional for drawing when video list has started playing (rAF does not use much resources in it self and you may get problems synchronizing stop and start when you switch videos so I would personally leave it running as-is for this type of scenarios (continuous video play) and only stop it if there is an error occurring).

Print selected multiple item from tilelist in flex3

i'm working on flex 3 project. in which i have one tileList in which there are muliple images, every images put in different canvas in tileList. i will give allowmultipleSelection to true. now i need to print all that Images on print button click, which user select from TileList.
please give me proper suggestion, how i will DO.
Thanks,
I got my answer Here, I take Tile instead of TileList and i push all Selected Image into one Array. And in printer.printPage I will Pass that Array and It will work now.
/* MyCustomItemBox */
<mx:HBox id="hb" autoLayout="false">
<mx:Image id="img" source="{imageURL}"/>
</mx:HBox>
/* Print Script */
// Custom Component which will be added in to Tile.
var myCustomBox= new MyCustomItemBox();
thumbView.addChild(myCustomBox);
// On Print Button Click
protected function onPrintPages(event:MouseEvent):void
{
var printer:Printer = new Printer();
var arr:Array = new Array();
for(var i:int = 0;i<10;i++)
{
var bdi:MyCustomItemBox = thumbView.getChildAt(i) as MyCustomItemBox;
var hb:HBox = bdi.getChildByName("hb") as HBox;
arr.push( hb.getChildByName( 'img' ) as UIComponent );
}
if(arr.length > 0)
printer.printPage(arr,null, "showAll");
}
<mx:Tile id="thumbView" autoLayout="false" width="90%" height="90%" />

Actionscript - Event That Notifies When Image Source Has Changed AND is Done Loading

I am looking for an event that fires after an image's source property has been changed, and the image display object has loaded the new data. I thought the 'complete' event was the way to go, but it seems to fires as soon as the source has changed, BUT before the image is done loading. In the snippet below, I am trying to get the imgMap_completeHandler to fire once imgMap has been updated with the bytes from doExport().
public function doExport(bytes:ByteArray):void
{
FlexGlobals.topLevelApplication.addElement(this);
imgMap.source = bytes;
}
protected function imgMap_completeHandler(event:Event):void
{
var pngEncoder:PNGEncoder = new PNGEncoder();
var snapShot:ImageSnapshot = ImageSnapshot.captureImage(this,0,pngEncoder);
export = snapShot.data;
dispatchEvent(new Event("exportComplete"));
}
<s:Image id="imgMap" complete="imgMap_completeHandler(event)" width="100%" height="100%"/>
Have you tried to extend Image class and source method to do that?
You may only have to create a standard event just after the
public function source(....)
{
[super source...]
dispatchEvent(new Event('Loaded'));
}
Hope it helps!

How do I attach camera to Spark.components.VideoDisplay

I'm using Flash Builder and created a spark-application Flex project that will stream video from the local camera. If I use mx.controls.VideoDisplay; there is no problem since it has attachCamera(camera) method. But Spark's VideoDisplay component does not have that method. I know I can use mx controls inside a Spark app but I want to know:
What is the real difference between spark.components.VideoDisplay and mx.controls.VideoDisplay?
How do I attach camera to spark.components.VideoDisplay?
Is there any advantages if I go with spark (since it's newer to mx library)?
thanks.
EDIT: In the documentation this is mentioned: "Starting with Flex 4.0, Adobe recommends that you use the spark.components.VideoPlayer class as an alternative to this class. (mx.controls.VideoDisplay)"
Here are the specifics to get this working:
import mx.events.FlexEvent;
import org.osmf.net.StreamType;
import spark.components.mediaClasses.DynamicStreamingVideoItem;
import spark.components.mediaClasses.DynamicStreamingVideoSource;
private var _cam:DynamicStreamingVideoSource = new DynamicStreamingVideoSource();
private var _dynVideoSource:DynamicStreamingVideoSource;
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
_dynVideoSource=new DynamicStreamingVideoSource();
var videoItems:Vector.<DynamicStreamingVideoItem>;
videoItems=new Vector.<DynamicStreamingVideoItem>();
videoItems[0]=new DynamicStreamingVideoItem();
_dynVideoSource.host= "";
_dynVideoSource.streamType=StreamType.LIVE;
_dynVideoSource.streamItems=videoItems;
mycam.source=_dynVideoSource;
var cam:Camera = Camera.getCamera(); //Camera.names[0]);
cam.setMode(640, 480, 15);
cam.setQuality(0, 80);
mycam.videoObject.attachCamera(cam);
}
Straight up, the answer is that you can't attach a camera to the Spark VideoDisplay. Sorry. I was trying to make this happen too, but I had to default to the mx VideoDisplay and there's nothing wrong with using it :)
Spark is newer and I prefer to use it whenever possible too, but in this case, you just need to use the MX control. It happens.
I tried to attach the camera to videoDisplay.videoObject - but the videoObject was always null, which throws an error.
To resolve that I created a dummy DynamicStreamingVideoObject and passed it as the source
_cam = new DynamicStreamingVideoSource();
<s:VideoDisplay id="mycam" source="_cam" />
then, in the creationComplete handler of the application i did this
var cam:Camera = Camera.getCamera();
mycam.videoObject.attachCamera(cam);
this resolved the issue.
Been looking for a solution to this and found the below
var cam:Camera = Camera.getCamera();
cam.setMode(320, 240, 15);
cam.setQuality(0, 0);
var myCam:Video = new Video(320,240);
myCam.attachCamera(cam);
myVideo.addChild(myCam);
thanks
Shorter workaround:
<s:VideoDisplay id="camVideoDisplay"
source="dummy"
autoPlay="false"
autoDisplayFirstFrame="false"/>
In this case, the Video object can be then referenced as camVideoDisplay.videoObject, e.g.:
camVideoDisplay.videoObject.attachCamera( .. );

if I load a flv with netStream, how can I call a function when the flv stops playing

I have a website in ActionScript 3 that has lots of FLV animations that happen when you press buttons. Right now this is how I have it set up.
in AS3,
im loading FLv's (which are animations I exported in FLV form from After Effects)
with net stream. I have a timer set up for the same amount of length of time that the animations (FLV's) play and when the timer stops it calls a function that closes the stream, opens a new one and plays another video. The only problem I noticed using timers is that if the connection is slow and (animation)stops for a second, the timer keeps going, and calls the next flv too early.
Does anyone know a way to load a flv, or swf for that matter, at the end of play of the flv? so that the next FLV will always play at the end of the run time of the previous FLV, rather than using timers?
im thinking onComplete but I don't know how to implement that!?
Sequential playing is pretty easy to achieve with the OSMF framework, you should check it out. Google "osmf tutorials" and you should find a few tutorials online.
The framework is fairly recent, but it looks like it may become the de facto solution for media delivery in Flash as it's not limited to video but also audio & images.
As a developer you won't have to bother with the NetStream & NetConnection classes. Developing video solutions , as well as audio & images solutions should be streamlined and easier to handle. Only limitation is that it requires Flash 10
Here's some code for checking when a FLV ends with NetStream. I just provide snippets as I assume you got the FLV up and running already.
//create a netstream and pass in your connection
var netStream:NetStream = new NetStream(conn);
//add callback function for PlayStatus -event
var client : Object = {};
client.onPlayStatus = onPlayStatus;
netStream.client = client;
//attach your NetStream to the connection as usual
//---
//function that gets called onPlayStatus
function onPlayStatus(info : Object) : void {
trace("onPlayStatus:" +info.code + " " + info.duration);
if (info.code == "NetStream.Play.Complete") {
//play the next FLV and so on
}
}
EDIT: With your example code it will look something like this.
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
var listener:Object = new Object();
listener.onMetaData = function(md:Object):void{};
listener.onPlayStatus = function(info : Object) : void {
trace("onPlayStatus:" +info.code + " " + info.duration);
if (info.code == "NetStream.Play.Complete") {
//play the next FLV and so on
}
};
ns.client = listener;
vid1.attachNetStream(ns);
const moviename1:String = "moviename2.flv";
const moviename1:String = "moviename3.flv";
var movietoplay:String = "moviename.flv";
ns.play(movietoplay);