Java - Xuggle - 获取框架的最佳方法

标签 java xuggle

我从一个星期开始就在使用 xuggle,我写了一个方法来获得一个 视频帧,但如果视频很长,这种方法会花费太多时间:

public static void getFrameBySec(IContainer container, int videoStreamId, IStreamCoder videoCoder, IVideoResampler resampler, double sec) 
{ 
    BufferedImage javaImage = new BufferedImage(videoCoder.getWidth(), videoCoder.getHeight(), BufferedImage.TYPE_3BYTE_BGR); 
    IConverter converter = ConverterFactory.createConverter(javaImage, IPixelFormat.Type.BGR24); 
    IPacket packet = IPacket.make(); 
    while(container.readNextPacket(packet) >= 0) 
    { 
        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) 
                    throw new RuntimeException("got error decoding video"); 
                offset += bytesDecoded; 
                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"); 
                    } 
                    if (newPic.getPixelType() != IPixelFormat.Type.BGR24) 
                            throw new RuntimeException("could not decode video as RGB 32 bit data in"); 

                    javaImage = converter.toImage(newPic); 
                    try 
                    { 
                        double seconds = ((double)picture.getPts()) / Global.DEFAULT_PTS_PER_SECOND; 
                        if (seconds >= sec && seconds <= (sec +(Global.DEFAULT_PTS_PER_SECOND ))) 
                        { 

                            File file = new File(Config.MULTIMEDIA_PATH, "frame_" + sec + ".png"); 
                            ImageIO.write(javaImage, "png", file); 
                            System.out.printf("at elapsed time of %6.3f seconds wrote: %s \n", seconds, file); 
                            return; 
                        } 
                    } 
                    catch (Exception e) 
                    { 
                        e.printStackTrace(); 
                    } 
                } 
            } 
        } 
        else 
        { 
            // This packet isn't part of our video stream, so we just 
            // silently drop it. 
        } 
    } 
    converter.delete(); 
} 

你知道更好的方法吗?

最佳答案

通过阅读您的代码,我发现可以进行一些优化。

您首先阅读整个文件一次,创建字节偏移量和秒数的索引。然后该函数可以从给定的秒数中查找字节偏移量,您可以在该偏移量处解码视频并执行其余代码。

另一种选择是使用您的方法,每次读取整个文件,但不是调用所有重新采样器、newPic 和 java 图像转换器代码,而是首先检查秒数是否匹配。如果他们这样做,则将图像转换为要显示的新图片。

所以

if(picture.isComplete()){

try { 

  double seconds = ((double)picture.getPts()) / Global.DEFAULT_PTS_PER_SECOND; 
  if (seconds >= sec && seconds <= (sec +(Global.DEFAULT_PTS_PER_SECOND ))) 
  {
    Resample image
    Convert Image
    Do File stuff
  }

关于Java - Xuggle - 获取框架的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6184934/

相关文章:

java - 音频播放速度太快

android - IMediaReader 和 IMediaWriter 是否在 android 中工作?

java - Xuggle 将音频与生成的音频结合起来

java - 深入了解队列

java - 获取 `ResultSet` 大小的最佳方法

java - webservice @POST 返回 415 不支持的媒体类型

java - 我如何在 Java 中去隔行扫描图像?

java - java native 编程中未满足的链接错误

java - Do While 循环跳过语句

java - Java 视频处理库