Long time since last post... It's been nearly 2 months since I changed my internet provider at home... and have no connection yet :-(
I recently had to implement a cool feature for a project, consisting in a picture-taker using the webcam, for a user registration process. The feature has been added recently in Facebook, allowing users to upload pictures and videos directly to their friends' walls.
Displaying the webcam content in a Flash movie is quite easy:
// 1. Access the default camera
var cam:Camera = Camera.getCamera();
// 2. Create a video display object
var video:Video = new Video(550,400);
// 3. Attach the camera to the video display
video.attachCamera(cam);
// 4. Add the video display object to the stage
stage.addChild(video);
Then, through the BitmapData object, it's possible to take a snapshot at the desired moment drawing the data from the Video object into a ByteArray (and encoding this information using an encoder JPEG/PNG/...). This binary data can be sent to the server, with a URLRequest and there processed by whatever server side technology.
// 1. Create the request object
var req:URLRequest = new URLRequest(remoteURL);
// 2. Specify we're sending binary data
req.contentType = "application/octet-stream";
// 3. Send by POST (GET doesn't allow enough data)
req.method = URLRequestMethod.POST;
// 4. Put the image binary data in the request body
req.data = binaryArray;
It's quite easy to get this point. But there's a usability issue with all this stuff, which is that to access the webcam, Flash needs the user authorization, requested through a dialog. First thing that drove me crazy, because if the Flash movie doesn't have the minimum dimensions (215 x 138) to show this dialog, there's no advice, but the video won't be displayed. It's clearly explained in the ActionScript 3 language reference (link to API), it's true. My fault, my fault :-P
But then, a second usability problem. Camera.getCamera() retrieves the "default" camera in the computer. In my MacBook Pro, Flash detects 3 webcams (even I just have the built-in one), which are displayed as "FireWire Video","DV Video" and "USB Video Class Video".
The problem is that just from the "USB Video Class Video" I'm able to capture video images. So it's not just asking for permission to access the webcam to the user, but also requiring him/her to go to the camera tab in the Flash settings menu, to try between this unknown video devices to check which one works? But wait, Facebook is detecting my webcam automatically! Even if I choose one of the non valid... when I try again the "USB Video Class Video" it's being used. So it must be possible to select the correct one somehow. And then I came across this article (Sander Kruger's blog):
Here, the author explains a tricky way to detect the valid one. The basics:
- Camera.getCameras() returns an array of Camera objects with the system cameras (in my MacBook Pro [FireWire Video, DV Video. USB Video Class Video], so we can know how many are accessible.
- Camera.getCamera() will get the default one (could be any of the system ones, available or not), but there's a second method, Camera.getCamera(String), that retrieves one specifically, from the total we discovered using Camera.getCameras(). The String parameter, represents the index of every camera in the array Camera.getCameras(), [0 to N-1]. So in my case, we can get the USB Video Class Video Cam for example, doing Camera.getCamera("2").
- The Camera object will dispatch a StatusEvent notifying if the user has accepted or rejected the access to the webcam from the Flash built dialog.
- The Camera object will dispatch ActivityEvents when it detects movement in the scene, but only if the camera is attached to a Video object where to be displayed.
With all this ingredients then you can cook a camera detection process. Once the Camera says it's accessible from the user request dialog (StatusEvent), you can loop over each cam object from Camera.getCameras, adding an activity handler for the ActivityEvents it could dispatch, and attach the Camera to a Video object, that's not added to the Stage (always hidden then). Then starting a Timer, we can give the Camera some time to detect activity... if it was not the case and the countdown finishes, then we should remove the activity event, detach the camera from the video and move to try the next Camera from the Array. Keep looping this way until one of the Cameras gives some activity news... or all of them are checked and none response to activity.
Hope the experience is helpful to someone :-)
Wednesday, December 17, 2008
Subscribe to:
Post Comments (Atom)
3 comments:
Just one post. Funny who cares that it has been 2 months since you have been on here. You know a link of a real Flex site.
awesome, exactly what i was looking for.
Helpful to me, will use on www.SillyWebcam.com as I never thought of using two cameras at once for effects I make thanks!
Post a Comment