tags:

views:

429

answers:

3

Updated:

Since my original request appears to be almost impossible, what's the next simplest solution? Invoke the swftools app? Make a JNI call to the ffmpeg lib?

Original:

This is related to "how to extract flash frames programmatically" but I am constrained to Java libraries only (and no JNI calls to C please). This also implies no calls to console apps like swftools. I'm looking for a pure Java (or at least JVM) solution.

+1  A: 

Note that playback in SWF is controlled by ActionScript and declarative transformations, so to view that "first frame" properly in all cases you'd need to emulate the whole player. I'd say -- call external tools. What's the problem with them anyway? Is it something religion-mandated?

Vladimir Dyuzhev
No, if that's the only way I can do it then fine. I was just hoping to avoid the added complexity of an external dependency, ie. something I can't package up in a WAR, or something that might get deleted by an overeager sys admin, or that makes it harder to move the app between Windows and Linux hosts. It just complicates things.
rcampbell
In fact, you can package swftools into WAR :) You just need to unpack it first. I did that for some OCR native tools -- make a random dir under /tmp or /home, unpack tgz there, unpack tgz itself (this way execution permissions are set by tar, Java has troubles doing that), run it!
Vladimir Dyuzhev
+2  A: 

It is possible... if you can accept the end result being one frame FLV file (and not a proper image, like PNG or JPEG.) What is a single frame video, really? It's an image! This may very well give you the functionality you are looking for although it might seem a bit strange.

What you need to do is parse the FLV file. It's actually a very simple format. First, read up on some basic video compression terms. Second, read up on the FLV File Format specification on Adobe's site.

Roughly, an example FLV file would look like this inside:

'FLV' header
Meta data 
Frame 0 - Audio
Frame 1 - Video I-Frame (all information to create a full image) 
Frame 2 - Video P-Frame (just differential from last frame)
Frame 3 - Video P-Frame (just differential from last frame)
Frame 1 - Video I-Frame (all information to create a full image) 
Frame 2 - Video P-Frame (just differential from last frame)
Frame 3 - Video P-Frame (just differential from last frame)
Frame 0 - Audio
Frame 5 
...
Frame n
EOF

So, you'll search for the video I-frame you want as a picture. That, along with a basic FLV file header, together is all you need. Our ouput (be it a socket or a file) will be just:

'FLV' header
Frame 0 - Video I-Frame (all information to create a full image)

This all can be done in Java without any special tools. I've done it myself. For real.

Note that this approach applies only to FLV files, and not F4V (or other MP4-based file formats.)

Stu Thompson
SWF has programmatic actions inside, triggered (for example) by the beginning of the frame. Many SWF files has initialization attached to the beginning of the first frame. Thus, simple parsing won't help. You may end up with the empty background image. One need an emulated playback.
Vladimir Dyuzhev
Or it may work perfectly, depending on his source files.
Stu Thompson
+2  A: 

Or if you want to do it directly from Java, you can use this code. It uses Xuggler, an open-source library for encoding and decoding video from java. Xuggler does use JNI behind the scenes to FFmpeg, but when using it that's totally invisible to you. Hop that helps.

Art

Xuggle