views:

3097

answers:

4

I'm using the VideoDisplay to play flv's, mov's, and mp4's and everything is working great. They are all being loaded via progressive download and are not being streamed. What I'd like to do is to grab a single specified frame (like whatever is being shown at the 10 second mark), convert it to a bitmap and use that bitmap as the preview image for the video. I'd like to do this at runtime so I don't have to create a preview image for every video that would be shown.

Any idea's on how to do this? I'd rather not fake it by playing it - seeking for that specific frame and then pausing it but I may have no other choice?

+1  A: 

I'm pretty sure this isn't possible. It may well be... but don't think so. I think the only way to load in video is to use the NetStream and NetConnection object, which as you know just kicks off the loading of the video.

If this is user generated video i think the best bet is to have some serever side script that generates the preview image. Have no idea how this is done but think this is how most clip sites work.

If all the videos are in your control it may be possible to write a script for one of the video editing programs to automate generating the image for a specific frame from a list of files. I think this is probably your best route as alternative that you could get up and running quickly.

Sorry for the vague answer... it may point you in the right direction if you need a quick solution.

James Hay
A: 

I agree with James, the only way to really do this would be to do it with a server side script and pull certain frames out of the video. Even if you could do this with flex, you really would not want to put the burden to do this (which would be processor intensive I would think) on the client machine. Not to mention it will be much more efficient to create the image before hand than to have flex determine the thumbnail to show every time it is loaded.

Ryan Guill
+2  A: 

Ryan and James are correct -- the right way's probably to extract frames at upload/transcode-time. But if that's not an option, you could opt for using some sort of a default/placeholder image of your own (something generic or somehow suitable for all videos whose thumbs haven't yet been captured), and just use VideoDisplay's DisplayObject-ness to grab and then upload a frame to your server, e.g.:

<mx:Script>
    <![CDATA[

        var captured:Boolean;

     private function creationCompleteHandler(event:Event):void
     {
      videoDisplay.source = "http://yourserver/yourvideo.flv";
     }

     private function videoDisplay_playheadUpdate(event:VideoEvent):void
     {
      if (!captured && videoDisplay.playheadTime >= 10)
       capture();
     }

     private function capture():void
     {
      var bmpData:BitmapData = new BitmapData(videoDisplay.width, videoDisplay.height);
      bmpData.draw(videoDisplay);

      captured = true;

      // Now just upload the byte array to your server for the next user
      var loader:URLLoader = new URLLoader();
      loader.dataFormat = URLLoaderDataFormat.BINARY;

      // ... etc.
     }

    ]]>
</mx:Script>

<mx:VideoDisplay id="videoDisplay" playheadUpdate="videoDisplay_playheadUpdate(event)" />

Again, it's perhaps not the most elegant solution, but it certainly works. This way, the first user sees the generic image, but every user thereafter gets the generated thumbnail. (Which, of course, you'll have uploaded and properly associated by then.) Make sense?

Christian Nunciato
I ended up doing something very similar to this (I probably should have stipulated that the app needs to be able to run offline so I don't have easy access to the server most of the time) but I ended up coding up a hack that involved loading the video and pausing it at the frame I needed. Thanks!
onekidney
Awesome, glad it helped.
Christian Nunciato
A: 

I am working on a robotics web cam recognition, using Flex, so that I have some web based control.

This might just work for me, I can capture the snapshot every second, load it into an image control, and do my analysis on it from the image control.

I tried the following:

var bmpData:BitmapData = new BitmapData(videoDisplay.width, videoDisplay.height);
bmpData.draw(videoDisplay);
imgsnapshot.source = bmpData;

This did not work, so maybe the displayobject interface will work better.

Any ideas?

Shaun