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

标签 java image video xuggler

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

相关文章:

java - Intellij 需要很长时间才能执行 JUnit 测试的 Maven 目标

html - Img 源是一个变量,URL 被编码

javascript - 正则表达式从YouTube获取get_video_info响应的一部分

java - Android - 视频文件的缩略图

java - 棋盘游戏的 GUI 操作

java - 为什么这个 while 循环在满足条件后才运行?

java - JSP Servlet 检索(显示)网页

python - 图像合成

java - 按钮上嵌入的图像不会显示

c++ - cvCaptureFromCAM 中存在内存泄漏吗?