视频缩略图xuggle

时间:2012-04-26 18:26:20

标签: java xuggle

我希望从一半左右的视频中获取缩略图,并通过使用以下内容完成此操作:

http://build.xuggle.com/view/Stable/job/xuggler_jdk5_stable/ws/workingcopy/src/com/xuggle/mediatool/demos/DecodeAndCaptureFrames.java

但我的解决方案非常慢,实际上它在视频中循环。它不是大文件的智能解决方案。

IContainer.seekKeyFrame对我的问题看起来很有用。有人可以解释我如何为此目的使用seekKeyFrame。

2 个答案:

答案 0 :(得分:1)

我修改了代码并在从第五秒开始取帧后退出循环。不是最好的,而是一个有效的解决方案。

答案 1 :(得分:0)

从任意时间段创建视频的缩略图。

     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="20" //20 seconds 

            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; 
            } 
    }