0
4

1 回答 1

2

我终于得到了一个可行的解决方案,可以使用 Xuggler 库将 JPEG 图像转换为 MPEG 扩展“.mp4”视频:

这是我修改后的“XugglerJpegImagesToMpegVideo.java”:

package com.conuretech.video_assembler;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.IContainer;
import java.util.ArrayList;
import java.util.List;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IRational;
/**
 *
 * @author Aryan Naim 
 * This class converts JPEG images to MPEG (.mp4) extension video using Xuggler library
 */
public class XugglerJpegImagesToMpegVideo {

    //fps = how many frames will be displayed per sec, default 24
    private int frameRate = 24;
    //number of millisecs each frame will be displayed for the viewer , default 1000 millisecs
    private long durationPerFrame = 1000; 
    //path to output mpeg video 
    private String outputFilenamePath = "";
    //list of JPEG pictures to be converted 
    private List<String> jpegFilePathList = new ArrayList<String>();
    //list of actual images in memory to be iterated through & encoded by Xuggler 
    private List<BufferedImage> jpegFileList = new ArrayList<BufferedImage>();

    /* VERY IMPORTANT regarding setDurationPerFrame(), I noticed that fpr 24 fps , 
    the expected duration fell short 15% or 150 millisec per 1 second, 
    therefore I adjusted this by adding 15% to the user specified duration, 
    For example 3000 millisec duration will be adjusted to 3450 millisecs. 
    This adjustment was even more severe for lower fps*/

      public void setDurationPerFrame(long  durationPerFrame) {
        this.durationPerFrame = new Double(Math.ceil(durationPerFrame * 1.15)).longValue();
    }

     public long getDurationPerFrame() {
        return durationPerFrame;
    }
    /* 
     Actual method that converts JPEG images to MPEG (.mp4) extension video using Xuggler library
     */
    public void convertJpegFramesToMpegVideo() {
        System.out.println("convertJpegFramesToMpegVideo, start...");
        // BufferedImage to store JPEG data from file
        BufferedImage img = null;
        IContainer container = IContainer.make();
        IMediaWriter writer = null;
        long nextEncodeTime = getDurationPerFrame();
        writer = ToolFactory.makeWriter(getOutputFilenamePath(), container);
        //the framerate is set at 24 fps , could be adjusted
        writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_MPEG4,IRational.make(frameRate),1024,768);

        File imgFile = null;
        //loop to load data from paths to BufferedImage objects
        for (int i = 0; i < jpegFilePathList.size(); i++) {
            imgFile = new File(getJpegFilePathList().get(i));
            if (imgFile.exists()) {

                try {

                    img = ImageIO.read(imgFile);

                    jpegFileList.add(img);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                System.out.println("convertJpegFramesToMpegVideo, file path: " + imgFile.getPath() + " does not exist!");
            }
        }//end for to load path to images 


        //for loop to encode each BufferedImage 
        for (int i = 0; i <jpegFileList.size(); i++) {
            System.out.println("convertJpegFramesToMpegVideo encoded frame counter: " + i);
            img = jpegFileList.get(i);
            writer.encodeVideo(0, img, nextEncodeTime, TimeUnit.MILLISECONDS);
            nextEncodeTime = nextEncodeTime + getDurationPerFrame();
        }//end loop 
        // after encoding all BufferedImages close 
        writer.close();
   System.out.println("convertJpegFramesToMpegVideo, end!");
    }//end

    public int getFrameRate() {
        return frameRate;
    }

    public void setFrameRate(int frameRate) {
        this.frameRate = frameRate;
    }
    public String getOutputFilenamePath() {
        return outputFilenamePath;
    }

    public void setOutputFilenamePath(String outputFilenamePath) {
        this.outputFilenamePath = outputFilenamePath;
    }

    public List<String> getJpegFilePathList() {
        return jpegFilePathList;
    }

    public void setJpegFilePathList(List<String> jpegFilePathList) {
        this.jpegFilePathList = jpegFilePathList;
    }

    public List<BufferedImage> getJpegFileList() {
        return jpegFileList;
    }

    public void setJpegFileList(List<BufferedImage> jpegFileList) {
        this.jpegFileList = jpegFileList;
    }

}//end class 

下面是实例化 XugglerJpegImagesToMpegVideo.java 并设置 JPEG 文件路径、fps 和帧持续时间等参数的主类:

package com.conuretech.video_assembler;
import com.xuggle.xuggler.IContainerFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author ANaim
 */
public class TestVideo {

    public static void main (String [] args)
    {
        if (args[0].equalsIgnoreCase("1"))
        {


          System.out.println("Testing xuggler...");
          XugglerJpegImagesToMpegVideo newjpegImagesToMpegVideo = new XugglerJpegImagesToMpegVideo(); 
    newjpegImagesToMpegVideo.setFrameRate(24);
    //duration in millisecs, for example 2 secs will be 2000 
    newjpegImagesToMpegVideo.setDurationPerFrame(2000);
    newjpegImagesToMpegVideo.setOutputFilenamePath("C:/Users/Public/Pictures/Sample_Pictures_2/video.mp4");
    List<String> jpegImages = new ArrayList<String>();
    jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/1.jpg");
    jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/2.jpg");
    jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/3.jpg");
    jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/4.jpg");
    jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/5.jpg");
    jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/6.jpg");
    jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/7.jpg");
    jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/8.jpg");
    newjpegImagesToMpegVideo.setJpegFilePathList(jpegImages);
    newjpegImagesToMpegVideo.convertJpegFramesToMpegVideo();

    }     

        else
        {

        }

         System.exit(0);
}

}//end main 

这创建了一个 16 秒的 MPEG 视频,每帧有 2 秒的持续时间。

这就是所有人!

于 2015-01-19T22:27:47.210 回答