I want to create an image from a video using xuggler. The sample code provided generates images from video in an interval, I modified it so that it only generates one image from video. BUT, it looks like it is actually looping through the whole video rather than just taking a snapshot of a specific time then end.
How can I properly generate ONE image from a video without looping through the whole video? On shorter videos this is fine but on hr+ videos, this would become a huge problem.
Below is my code:
import javax.imageio.ImageIO;
import java.io.File;
import java.awt.image.BufferedImage;
import java.util.Random;
import com.xuggle.mediatool.IMediaReader;
import com.xuggle.mediatool.MediaListenerAdapter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.mediatool.event.IVideoPictureEvent;
import com.xuggle.xuggler.Global;
public class Test extends MediaListenerAdapter {
public static final double SECONDS_BETWEEN_FRAMES = 1;
public static final long MICRO_SECONDS_BETWEEN_FRAMES = (long)(Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);
private int mVideoStreamIndex = -1;
boolean takeImage = true;
public static void main(String[] args) {
new Test("src/main/Wildlife_ 512kb, hkf.mp4");
}
public Test(String filename) {
System.out.println("starting the xuggler");
IMediaReader reader = ToolFactory.makeReader(filename);
reader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
reader.addListener(this);
while (reader.readPacket() == null) { do { } while(false); }
}
public void onVideoPicture(IVideoPictureEvent event) {
try {
if (event.getStreamIndex() != mVideoStreamIndex) {
if (-1 == mVideoStreamIndex) {
mVideoStreamIndex = event.getStreamIndex();
} else {
return;
}
}
if (event.getTimeStamp() > MICRO_SECONDS_BETWEEN_FRAMES && takeImage) {
Random random = new Random();
File file = new File("/Users/yao/__TEMP__/media_upload_temp/" + random.nextInt(Integer.MAX_VALUE) + ".png");
ImageIO.write(event.getImage(), "png", file);
double seconds = ((double)event.getTimeStamp()) / Global.DEFAULT_PTS_PER_SECOND;
System.out.printf("at elapsed time of %6.3f seconds wrote: %s\n", seconds, file);
takeImage = false;
}
} catch (Exception e) { e.printStackTrace(); }
}
}
Basically, I just aded a boolean field and use that to manage when to break out of loop/video after one image was capture.
while (reader.readPacket() == null) {
if (!takeImage) {
reader.removeListener(this);
break;
}
}