gpt4 book ai didi

java - 从视频中仅捕获一张缩略图

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:55:44 24 4
gpt4 key购买 nike

我正在努力从视频中生成缩略图。我能够做到,但我只需要视频中的一张缩略图,但我得到的是视频不同时间的不止一张图像。我使用以下代码生成缩略图。请建议我应该在以下代码中修改什么以从视频的中间部分仅获取一个缩略图。我使用的代码如下(我用过Xuggler):

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
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 Main {

public static final double SECONDS_BETWEEN_FRAMES = 10;
private static final String inputFilename = "D:\\k\\Knock On Wood Lesson.flv";
private static final String outputFilePrefix = "D:\\pix\\";
// The video stream index, used to ensure we display frames from one and
// only one video stream from the media container.
private static int mVideoStreamIndex = -1;
// Time of last frame write
private static long mLastPtsWrite = Global.NO_PTS;
public static final long MICRO_SECONDS_BETWEEN_FRAMES =
(long) (Global.DEFAULT_PTS_PER_SECOND * SECONDS_BETWEEN_FRAMES);

public static void main(String[] args) {
IMediaReader mediaReader = ToolFactory.makeReader(inputFilename);
// stipulate that we want BufferedImages created in BGR 24bit color space
mediaReader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
mediaReader.addListener(new ImageSnapListener());
// read out the contents of the media file and
// dispatch events to the attached listener
while (mediaReader.readPacket() == null);
}

private static class ImageSnapListener extends MediaListenerAdapter {

public void onVideoPicture(IVideoPictureEvent event) {
if (event.getStreamIndex() != mVideoStreamIndex) {
// if the selected video stream id is not yet set, go ahead an
// select this lucky video stream
if (mVideoStreamIndex == -1) {
mVideoStreamIndex = event.getStreamIndex();
} // no need to show frames from this video stream
else {
return;
}
}
// if uninitialized, back date mLastPtsWrite to get the very first frame
if (mLastPtsWrite == Global.NO_PTS) {
mLastPtsWrite = event.getTimeStamp() - MICRO_SECONDS_BETWEEN_FRAMES;
}
// if it's time to write the next frame
if (event.getTimeStamp() - mLastPtsWrite
>= MICRO_SECONDS_BETWEEN_FRAMES) {
String outputFilename = dumpImageToFile(event.getImage());
// indicate file written
double seconds = ((double) event.getTimeStamp())
/ Global.DEFAULT_PTS_PER_SECOND;
System.out.printf("at elapsed time of %6.3f seconds wrote: %s\n",
seconds, outputFilename);
// update last write time
mLastPtsWrite += MICRO_SECONDS_BETWEEN_FRAMES;
}
}

private String dumpImageToFile(BufferedImage image) {
try {
String outputFilename = outputFilePrefix
+ System.currentTimeMillis() + ".png";
ImageIO.write(image, "png", new File(outputFilename));
return outputFilename;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
}

最佳答案

您可以这样做。

     public class ThumbsGenerator { 

private static void processFrame(IVideoPicture picture, BufferedImage image) {
try {

File file=new File("C:\\snapshot\thimbnailpic.png");//name of pic
ImageIO.write(image, "png", file);


} catch (Exception e) {
e.printStackTrace();
}
}


@SuppressWarnings("deprecation")
public static void main(String[] args) throws NumberFormatException,IOException {

String filename = "your_video.mp4";

if (!IVideoResampler.isSupported(IVideoResampler.Feature.FEATURE_COLORSPACECONVERSION))
throw new RuntimeException("you must install the GPL version of Xuggler (with IVideoResampler support) for this demo to work");


IContainer container = IContainer.make();


if (container.open(filename, IContainer.Type.READ, null) < 0)
throw new IllegalArgumentException("could not open file: "
+ filename);


String seconds=container.getDuration()/(1000000*2)+""; // time of thumbnail

int numStreams = container.getNumStreams();

// and iterate through the streams to find the first video stream
int videoStreamId = -1;
IStreamCoder videoCoder = null;
for (int i = 0; i < numStreams; i++) {
// find the stream object
IStream stream = container.getStream(i);
// get the pre-configured decoder that can decode this stream;
IStreamCoder coder = stream.getStreamCoder();

if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
videoStreamId = i;
videoCoder = coder;
break;
}
}

if (videoStreamId == -1)
throw new RuntimeException(
"could not find video stream in container: " + filename);



if (videoCoder.open() < 0)
throw new RuntimeException(
"could not open video decoder for container: " + filename);

IVideoResampler resampler = null;
if (videoCoder.getPixelType() != IPixelFormat.Type.BGR24) {


resampler = IVideoResampler.make(videoCoder.getWidth(), videoCoder
.getHeight(), IPixelFormat.Type.BGR24, videoCoder
.getWidth(), videoCoder.getHeight(), videoCoder
.getPixelType());
if (resampler == null)
throw new RuntimeException(
"could not create color space resampler for: "
+ filename);
}


IPacket packet = IPacket.make();


IRational timeBase = container.getStream(videoStreamId).getTimeBase();


System.out.println("Timebase " + timeBase.toString());


long timeStampOffset = (timeBase.getDenominator() / timeBase.getNumerator())
* Integer.parseInt(seconds);
System.out.println("TimeStampOffset " + timeStampOffset);


long target = container.getStartTime() + timeStampOffset;


container.seekKeyFrame(videoStreamId, target, 0);

boolean isFinished = false;

while(container.readNextPacket(packet) >= 0 && !isFinished ) {




if (packet.getStreamIndex() == videoStreamId) {


IVideoPicture picture = IVideoPicture.make(videoCoder
.getPixelType(), videoCoder.getWidth(), videoCoder
.getHeight());

int offset = 0;
while (offset < packet.getSize()) {


int bytesDecoded = videoCoder.decodeVideo(picture, packet,
offset);
if (bytesDecoded < 0) {
System.err.println("WARNING!!! got no data decoding " +
"video in one packet");
}
offset += bytesDecoded;



picture from


if (picture.isComplete()) {

IVideoPicture newPic = picture;



if (resampler != null) {

newPic = IVideoPicture.make(resampler
.getOutputPixelFormat(), picture.getWidth(),
picture.getHeight());
if (resampler.resample(newPic, picture) < 0)
throw new RuntimeException(
"could not resample video from: "
+ filename);
}

if (newPic.getPixelType() != IPixelFormat.Type.BGR24)
throw new RuntimeException(
"could not decode video as BGR 24 bit data in: "
+ filename);


BufferedImage javaImage = Utils.videoPictureToImage(newPic);


processFrame(newPic, javaImage);
isFinished = true;
}
}
}
}


if (videoCoder != null) {
videoCoder.close();
videoCoder = null;
}
if (container != null) {
container.close();
container = null;
}
} }

关于java - 从视频中仅捕获一张缩略图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12643170/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com