Programmatically extracting a frame from a video in Flash - apache-flex

I need to write a small Flash app that will need to extract a video frame from a playing video. It will not need to be saved to the HDD of the user. I just need to get the image data and display it in the Flash movie. The frame to extract will be chosen by the user, which is why I'd like to do this purely on the client side (though I know I could do it from the server side).
I've tried searching for solutions but I'm not getting any useful results. Being a Flash newbie I haven't got any code yet seeing as I wouldn't know where to start.
So Flash gurus, is there a way to do this?

If you take a 'screen grab' of a DisplayObject in flash using BitmapData's draw() method.
If you have something for displaying flv somewhere a bit to the right, or down, try something like:
var cloneData:BitmapData = new BitmapData(video.width,video.height,false,0x000000);
cloneData.draw(video);
//test
addChild(new Bitmap(cloneData));
Goodluck!

After reading Georges answer, this is what I came up with as proof of concept. Posting here so it doesn't pollute original question.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="video.load()">
<mx:VideoDisplay id="video" x="0" y="0" source="/content/content.flv" />
<mx:Button x="10" y="10" label="Grab" click="grabClick()"/>
<mx:Button x="71" y="10" label="Play" click="video.play()"/>
<mx:Button x="130" y="10" label="Pause" click="video.pause()"/>
<mx:Script>
<![CDATA[
import mx.controls.*;
import flash.display.BitmapData;
private function grabClick():void {
var bitdata:BitmapData = new BitmapData(video.width, video.height, false, 0x0);
bitdata.draw(video);
var grabResult:Image = new Image();
grabResult.x = 0;
grabResult.y = video.height;
grabResult.source = new Bitmap(bitdata);
addChild(grabResult);
}
]]>
</mx:Script>
</mx:Application>

Related

Flex' VideoDisplay control does not open stream

I'm trying to make VideoDisplay playing media with FlashDevelop. Here's the source of my application:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.events.VideoEvent;
private function pause():void
{
if (moo_player.state == VideoEvent.PLAYING)
moo_player.pause(); else
if (moo_player.state == VideoEvent.PAUSED)
moo_player.play();
}
]]>
</mx:Script>
<mx:Panel>
<mx:VideoDisplay
source="bar.flv"
width="640"
height="480"
maintainAspectRatio="true"
id="moo_player"
autoPlay="true"
doubleClick="pause();"
doubleClickEnabled="true"
/>
</mx:Panel>
</mx:Application>
The problem is when i build application and run it (unfortunately, got no idea how to run it without KMPlayer or Mozilla - Flash Player is a plugin afaik) i got no video. The movie file is in the same directory as application's "Application.flv" one. But if i reload application (within player or browser) a few times, video starts.
So, here are my questions:
what's wrong with VideoDisplay
component and how to fix this
'non-playing'?
what's the better way
to execute application than running
it within movie player or browser?
P.S.: please, do not get mad of my knowledge lacks - i began to use Flex nearly 30 minutes ago.
You should be using Spark components, not MX components. Try this:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<s:VideoPlayer source="bar.flv" width="640" height="480" />
</s:Application>
There's some issues with video display internally in the component. One of the only flex components that's kind of poorly done in some ways. Please don't let it discourage you from exploring Flex.
Create a custom component that extends it, create a file named CustomVideoDisplay.as with this code:
package
{
import mx.controls.VideoDisplay;
public class CustomVideoDisplay extends VideoDisplay
{
[Bindable]
override public function get source():String
{
return super.source;
}
override public function set source(value:String):void
{
super.source = value;
play();
}
public function CustomVideoDisplay()
{
super();
}
}
}
Then add this into your root <application> tag :
xmlns:local="*"
And for your video component, refer to it as:
<local:CustomVideoDisplay
source="bar.flv"
width="640"
height="480"
maintainAspectRatio="true"
id="moo_player"
autoPlay="true"
doubleClick="pause();"
doubleClickEnabled="true"
/>
Let me know if this doesn't do the trick for you!
Well, i thought: my player will be ran at client-side of web project, and in FireFox that code runs successfully each of seven runs. I think this would be enough for testing and implementation.
Thanks everyone for the trouble-taking!

More than one titleWindow in a Flex Application

I'm a GIS Analyst that was moved to an Analyst Programmer position. This has been a hard transition for me as I don't have much of a programming background, but I was thrown into it.
I'm working on a Flex app inside a jsp page. Essentially it is a grid 3x2 that has images and text. What I am trying to do is have more than one titleWindow reference in this page, so that when an image is clicked a titleWindow is opened. (If anyone has a better idea, especially if it has to do with a hover I am very open to that!) Currently I have it working for one image. However, when I try to add a second function it errors on me. "Error 1021: Duplicate function definition" Below is the entire code for the main page that calls up the titleWindow. The code below is what gives the Error 1021.
<?xml version="1.0" encoding="utf-8"?>
<![CDATA[
import flash.geom.Point;
import mx.containers.TitleWindow;
import mx.core.IFlexDisplayObject;
import mx.managers.PopUpManager;
import windows.SimplePopupWindow;
private var point1:Point = new Point();
private function showWindow():void {
var login:SimpleTitleWindowExample=SimpleTitleWindowExample(PopUpManager.createPopUp( this, SimpleTitleWindowExample , true));
point1.x=131;
point1.y=119;
point1=roadStatus.localToGlobal(point1);
}
private var point2:Point = new Point();
private function showWindow():void {
var login:SimpleTitleWindowExampleFlood=SimpleTitleWindowExampleFlood(PopUpManager.createPopUp( this, SimpleTitleWindowExampleFlood , true));
point2.x=289;
point2.y=119;
point2=floodplain.localToGlobal(point2);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:BorderContainer x="10" y="0" width="750" height="600" backgroundColor="#BBB082" backgroundAlpha="1.0" cornerRadius="20" borderColor="#E8DBA7">
<s:Panel x="10" y="10" width="728" height="578" cornerRadius="20" chromeColor="#983D3A" borderColor="#F1EFE7" backgroundColor="#BBB082">
<mx:Image x="131" y="119" width="150" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus2_small.jpg" id="roadStatus" click="showWindow();"/>
<mx:Image x="289" y="119" width="150" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus_small.jpg" id="floodplain" click="showWindow();"/>
<mx:Image x="447" y="119" width="150" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus2_small.jpg"/>
<s:Label x="131" y="242" text="SJC Road Status"/>
<s:Label x="289" y="242" text="SJC Floodplain"/>
<s:Label x="447" y="242" text="Assessor's Parcels"/>
<mx:Image x="131" y="262" width="150" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus_small.jpg"/>
<mx:Image x="289" y="262" width="149" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus2_small.jpg"/>
<mx:Image x="446" y="262" width="151" height="115" source="file://GIS Map Portal/images/Map Images/SJCRoadStatus_small.jpg"/>
<s:Label x="131" y="385" text="Label"/>
<s:Label x="289" y="385" text="Label"/>
<s:Label x="446" y="385" text="Label"/>
<s:Label x="229" y="24" text="San Juan County Web Maps" fontFamily="Calvin and Hobbes" fontSize="25"/>
</s:Panel>
</s:BorderContainer>
Below is the titleWindow code. This code works so far!
<?xml version="1.0" encoding="utf-8"?>
<mx:Script>
<![CDATA[
import mx.managers.PopUpManager;
import mx.controls.Text;
// A reference to the TextInput control in which to put the result.
public var loginName:Text;
// Event handler for the OK button.
private function returnName():void {
//loginName.text="Name entered: " + userName.text;
PopUpManager.removePopUp(this);
}
]]>
</mx:Script>
<mx:HBox width="323" height="147" borderColor="#E8DBA7" dropShadowVisible="true">
<mx:Text text="The San Juan County GIS Department maintains aninteractive web map dedicated for researching county roads, but also includes city limits, lakes and rivers, and other geographic data.
" width="319" height="76" textAlign="center" color="#FFFFFF"/>
</mx:HBox>
<mx:HBox>
<mx:Button label="Go" click="navigateToURL(new URLRequest(''), 'quote')"/>
<mx:Button label="Back" click="PopUpManager.removePopUp(this);"/>
</mx:HBox>
Question: What code do I need to change above to be able to add more than one titleWindow (up to 6), or what code can I use for a hover to open a "window" or tool tip?
If anyone has any ideas or can direct me at all that would be great. I appreciate it!
Sounds like you just got thrown in the deep end. Generally speaking theres no limitation on the number of title windows you can have open, the PopUpManager class handles any UIComponent you tell it to open as a pop up and one of the arguments for the .createPopUp or addPopUp static methods on the manager will take a modal parameter which specifies if the user interaction should be blocked (indicated by blurring the application) or if the window should just be shown. It seems rather this error is stemming from your extension of the TitleWindow (the SimpleTitleWindowExample) can you post that code. Also as starting points on the topic check out the following documentation:
General Flex:
http://www.adobe.com/devnet/flex/videotraining.html
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/index.html
^ notice the runtimes and products selection options at the top of the screen, select according to SDK you're building with (or select SDK based on features)
PopUpManager:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/PopUpManager.html#createPopUp()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/PopUpManager.html#addPopUp()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/PopUpManager.html#removePopUp()
Tooltips:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/ToolTipManager.html#createToolTip()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/managers/ToolTipManager.html#destroyToolTip()
If you're still having troubles definitely post the code for the custom TitleWindow, also what version of the SDK you're using so I can try to replicate.
EDIT:
Ah okay seeing the rest of your code clears it up... you can't have two functions that have the same exact name so in your code you have showWindow as a function that is declared two times (I'm not sure how this is getting past compilation, I would have imagined the compiler would be smart enough to see this error before run-time, but it is what it is). Change the other showWindow to be something like showOtherWindow or something along those lines. It also looks like you come from a procedural programming background (C or some other non-OOP language) Object Oriented programming takes a little while to get your head around but makes a whole lot more sense when it comes to solving real world problems once you understand it, basically you're setting up descriptions and sending messages between objects using method calls and when you define a class, via AS or MXML you're defining the methods (order of method/property definitions doesn't functionally matter, things are still procedural, like step by step within the methods but the order of method declaration or property declaration has no effect).
This may be helpful:
http://www.codeproject.com/KB/architecture/OOP_Concepts_and_manymore.aspx
I'm basically at the opposite end of the spectrum in terms of skills, I have a formal education from DePaul University in computer science but at my current position am doing a lot of google maps flash code so I'm finding myself more and more needing to understand Datums and other GIS specialty info (just thought it was sort of interesting to find someone at the same intersection but going the other way :).

Fxcomponent: Flex video player issue

I'm using the fxcomponent: Flv video player to play my flv/mob files.
You may get it from here.
Now, player works perfectly as shown in their site, but when I try to use the FXVideo control in popup window (popup manager help is here), the component gives mirror image!, strange, I didn't change any code in that.
So can any one help me out to fix this issue, as I'm novice to action script?
Image:
For quick set up, I'm putting my code here:
FXVideo_Example.mxml file (No change at all except variable)
[Bindable]
private var source:String = "http://localhost/greatcatches.flv";
]]>
</mx:Script>
<controls:FXVideo width="480" height="360" source="{source}" autoPlay="false" bufferTime="10" />
MainPage.mxml:
import mx.core.IFlexDisplayObject;
import mx.managers.PopUpManager;
private function showW():void {
// Create a non-modal TitleWindow container.
var helpWindow:IFlexDisplayObject =
PopUpManager.createPopUp(this, FXVideo_Example, false);
}
]]>
</mx:Script>
<mx:VBox width="480" height="360">
<mx:Button click="showW();" label="Show"/>
</mx:VBox>
Ended up by using spark component!
<s:VideoPlayer id="videoPlayer"
source="http://localhost/greatcatches.flv"
autoRewind="true"
muted="true"
horizontalCenter="0"
verticalCenter="0" />

How to copy something as a pastable bitmap in flash?

How to copy something as a pastable bitmap in flash?
So I have simple mxml project - empty page with a panel on it.
I want to be able to select some region on my panel and copy it somehow as bitmap pastable to photoshop, word and other programms.
How to do such thing? (libs, articles etc)
Edit - It may be not possible in FP10 but in FP 10.1 you can have it=)
See BETA ActionScript 3.0 Reference for the Adobe Flash Platform 10.1
Not in the best way ever but any way what's so ever
first use ClipboardFormats -
HTML_FORMAT (which IS supported
by FP10)
Create some template HTML
Embed your BitmapData to it (Use Encoders)
Now you can paste it in to Word and some other programms
You can't do that with Flex/Flash, but you can take a snapshot and save that to the filesystem and import that image to photoshop etc. Here's an example:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.graphics.codec.PNGEncoder;
import flash.display.BitmapData;
protected function saveAsPNG(target:Sprite, path:String):void
{
var bitmapData:BitmapData = new BitmapData(target.width, target.height);
bitmapData.draw(target);
var image:PNGEncoder = new PNGEncoder();
var byteArray:ByteArray = image.encode(bitmapData);
var file:FileReference = new FileReference();
file.save(byteArray, path);
}
]]>
</mx:Script>
<mx:Panel width="100%" height="100%">
<mx:HBox width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
<mx:Panel width="50%" height="50%"/>
<mx:Panel width="50%" height="50%"/>
</mx:HBox>
</mx:Panel>
<mx:Button label="Save As.." click="saveAsPNG(this, 'MyImage.png')"/>
</mx:Application>
If you use AIR, you can save Bitmaps to the Clipboard. Check out this advanced AIR Clipboard Application.
You also might be able to do the following:
Take snapshot and convert to Base64 encoding
Pass Base64 encoded PNG to Javascript
Save to <img/> tag in HTML
Copy to clipboard
(not sure if that's possible)
It looks like you can't even copy images to the clipboard in javascript. If you're on a Mac, you can use this: Command+Ctrl+Shift+4.
Hope that helps,
Lance

Waiting for Flex Effects to Finish

I'm a Flex rookie tasked with enhancing an existing application. One of those enhancements is getting the field that currently shows the time to smoothly fade back and forth between showing the time and the date.
I know the proper way to do this is to embed the font file in the application so I can fade the label in and out directly. I'm trying to avoid that if I can, since I'd prefer to make my changes as unobtrusive as possible.
I came up with what I felt was a reasonable workaround: create a "privacy screen" that just so happens to be the exact size, shape, and color of the clock's background; initialize its alpha to 0; then when changing the time/date, fade-in the privacy screen, make the change, and fade the screen back out again.
The code looks something like this:
var targets:Array = new Array();
targets.push(this.privacyScreen);
this.effectFadeIn.play(targets);
this.mylabel.text = "I am a date and/or time";
this.effectFadeOut.play(targets);
... with the key components looking like this:
<mx:Label text="" id="mylabel" width="100%" height="100%" x="0" y="0" color="0xff0000"/>
<mx:Canvas id="privacyScreen" width="100%" height="100%" x="0" y="0" alpha="1" backgroundColor="{myConfiguration.backgroundColor}"/>
<mx:Fade id="effectFadeIn" alphaFrom="0.0" alphaTo="1.0" duration="250"/>
<mx:Fade id="effectFadeOut" alphaFrom="1.0" alphaTo="0.0" duration="250"/>
As I'm sure the experienced Flex designers already know, this code is made from delicious fresh-squeezed FAIL. The basic assumption that execution will wait for the fade-in effect to finish is wrong, and the fade-out effect is apparently ignored while the fade-in is still in progress.
So I guess I have two related questions:
Is it possible to get execution to pause while waiting for an effect to run to completion?
Is this approach even viable, or does it simply reek of Doing It Wrong from top to bottom?
My thanks in advance for any insight anyone can offer.
(And I admit in advance that the more I try to learn this by doing, the more I realize I need to avail myself of some of the online training resources out there.)
I just played a bit with your code, is this what you're looking for?
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="onComplete();">
<mx:Script>
<![CDATA[
private var targets:Array = new Array();
private function onComplete():void {
targets.push(canv);
effectFadeOut.play(targets);
}
private function onFadeInEnd():void {
effectFadeOut.play(targets);
}
private function onFadeOutEnd():void {
effectFadeIn.play(targets);
}
]]>
</mx:Script>
<mx:Label text="{(new Date()).toString()}" id="lbl" x="0" y="0" color="0xff0000"/>
<mx:Canvas id="canv" width="100%" height="{lbl.height+5}" x="0" y="0" backgroundColor="#000000"/>
<mx:Fade id="effectFadeIn" alphaFrom="0.0" alphaTo="1.0" duration="250"
effectEnd="onFadeInEnd();" />
<mx:Fade id="effectFadeOut" alphaFrom="1.0" alphaTo="0.0" duration="250"
effectEnd="onFadeOutEnd();" />
</mx:WindowedApplication>
Hope that helps :)
Your code is executed while the label fades. this.effectFadeIn.play () does not wait for it to finish. I would add a setTimeout call to the lines of code you need to call later, or better yet, put them in another function. Then, call the function again after a certain interval.
import flash.utils.*;
private function FadeIn () : void {
var targets:Array = new Array();
targets.push(this.privacyScreen);
this.effectFadeIn.play(targets);
this.mylabel.text = "I am a date and/or time";
setTimeout (function (): void {FadeOut (targets);}, effectFadeIn.duration); // Function and duration
}
private function FadeOut (targets : Array) : void {
this.effectFadeOut.play(targets);
setTimeout (FadeIn (), this.effectFadeOut.duration;
}
I'm pretty sure this should work...

Resources