views:

513

answers:

3

I want to build a component, where the user can play a video in a Flex Spark VideoDisplay. There will be a button and whenever the button is pressed, I want to save the current time of the VideoDisplay plus a screenshot. The screenshot needs to be someway saved, because I want to display all times and screenshots in a DataGrid (screenshots should appear when the user hovers a time in the DataGrid).

So, how can I take screenshots of the Spark VideoDisplay and save/display them?

+1  A: 

You can take snapshots a few ways, this way just uses the ImageSnapshot class, but you could do it by manually drawing the bitmap of the video display if you'd like. Here's a sample:

Renderer

<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer 
    xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    width="100" height="100" creationComplete="trace(data)">

    <mx:Image source="{this.data}" width="100%" height="100%"/>

</s:ItemRenderer>

Sample App

<?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">

    <fx:Script>
        <![CDATA[

            import mx.graphics.ImageSnapshot;

            public function takeSnapshot():void
            {
                var snapshot:BitmapData = ImageSnapshot.captureBitmapData(videoDisplay);
                var bitmap:Bitmap = new Bitmap(snapshot);
                list.dataProvider.addItem(bitmap);
            }
        ]]>
    </fx:Script>

    <s:layout>
        <s:VerticalLayout horizontalAlign="center"/>
    </s:layout>

    <s:VideoDisplay id="videoDisplay"
        source="video.mov"
        width="400" height="300"/>

    <s:Button id="button" click="takeSnapshot()"/>

    <s:List id="list" horizontalCenter="0" width="100%" itemRenderer="SnapshotRenderer">
        <s:dataProvider>
            <mx:ArrayList/>
        </s:dataProvider>
        <s:layout>
            <s:TileLayout/>
        </s:layout>
    </s:List>
</s:Application>

To accomplish exactly what you were describing (take snapshot and save snapshot), you could store those in an array in that takeSnapshot method, or you could loop through the list.dataProvider do get the bitmaps. Then you'd just need to pass them to a backend language (ruby, python, php...) to save.

Hope that helps, Lance

viatropos
Thanks! I don't actually want to save them. They should just be available to the user while he is playing the video.
Thomas
A: 

once you take the snapshot and get it in memory, how do you pass it to the server? i was thinking of saving to file and then uploading the file, but i can only find documentation on FileReference, which requires that you display a dialog. is there an alternate way to construct the request to the server with the image data?

jonas
A: 

use the JPEGEncoder in flex to vonvert it to bytearray, and then encode the byte array using the b64encoder as follow: ////// var jpg:JPEGEncoder = new JPEGEncoder(); var ba:ByteArray = jpg.encode(bitmapData);

var b64encoder:Base64Encoder = new Base64Encoder(); b64encoder.encodeBytes(ba); var b64String:String = b64encoder.flush(); /////

Now you can pass your b64String to your server via HTTP post method :)

Jeannius